@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.
- package/README.md +14 -0
- package/dist/bodymap.js +129 -76
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +129 -76
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +117 -26
- package/dist/index.d.ts +117 -26
- package/dist/index.js +677 -450
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +673 -451
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-_3Ajpiqu.d.ts → pages-CsjsUn0G.d.ts} +30 -13
- package/dist/{pages-CpW3OB3g.d.mts → pages-ZbT_pD_U.d.mts} +30 -13
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +676 -701
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +676 -701
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +31 -7
- package/dist/theme/index.d.ts +31 -7
- package/dist/theme/index.js +84 -20
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +83 -21
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +84 -20
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +84 -20
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/dist/theme/tokens.d.mts +56 -7
- package/dist/theme/tokens.d.ts +56 -7
- package/dist/theme/tokens.js +72 -20
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme/tokens.mjs +71 -21
- package/dist/theme/tokens.mjs.map +1 -1
- package/docs/render-testing-pattern.md +130 -0
- package/package.json +1 -1
- package/src/arch/Architecture.stories.tsx +3 -1
- package/src/arch/arch-graph.json +74 -72
- package/src/components/custom/ActiveWork/InitiativeBrief.tsx +2 -1
- package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +8 -3
- package/src/components/custom/EmptyState/EmptyState.stories.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.stories.tsx +4 -1
- package/src/components/custom/Gauge/Gauge.tsx +3 -1
- package/src/components/custom/Scatter/Scatter.stories.tsx +10 -7
- package/src/components/custom/Scatter/Scatter.tsx +6 -4
- package/src/components/custom/Sidebar/Sidebar.stories.tsx +1 -1
- package/src/components/custom/Table/Table.stories.tsx +1 -1
- package/src/components/custom/Table/Table.tsx +2 -2
- package/src/components/custom/Treemap/Treemap.stories.tsx +13 -10
- package/src/components/custom/Treemap/Treemap.tsx +4 -1
- package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +2 -1
- package/src/components/custom/Workout/BaseBadge.stories.tsx +11 -7
- package/src/components/custom/Workout/BaseBadge.tsx +3 -2
- package/src/components/custom/Workout/BodyMap.tsx +5 -3
- package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +13 -3
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +5 -3
- package/src/components/custom/Workout/CapacityBandChart.stories.tsx +2 -1
- package/src/components/custom/Workout/CapacityBandChart.tsx +5 -3
- package/src/components/custom/Workout/DeviationBar.test.tsx +5 -2
- package/src/components/custom/Workout/DeviationBar.tsx +5 -2
- package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +7 -6
- package/src/components/custom/Workout/DualVelocityStrip.test.tsx +29 -16
- package/src/components/custom/Workout/ExerciseCard.stories.tsx +8 -8
- package/src/components/custom/Workout/ExerciseCard.test.tsx +39 -19
- package/src/components/custom/Workout/ExerciseCard.tsx +92 -167
- package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +89 -6
- package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +189 -1
- package/src/components/custom/Workout/ExerciseCardHeading.tsx +167 -18
- package/src/components/custom/Workout/ExerciseDetailPage.tsx +3 -2
- package/src/components/custom/Workout/ExerciseHeading.tsx +192 -47
- package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +6 -5
- package/src/components/custom/Workout/InputBar.tsx +4 -2
- package/src/components/custom/Workout/IntensityBar.tsx +4 -1
- package/src/components/custom/Workout/MesoCard.tsx +2 -1
- package/src/components/custom/Workout/MesoStatusCard.tsx +11 -10
- package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +8 -3
- package/src/components/custom/Workout/PrHistoryModal.stories.tsx +12 -2
- package/src/components/custom/Workout/README.md +58 -12
- package/src/components/custom/Workout/ReadinessCheck.tsx +4 -2
- package/src/components/custom/Workout/RestTimer.stories.tsx +13 -2
- package/src/components/custom/Workout/RestTimer.tsx +4 -2
- package/src/components/custom/Workout/SegmentedBar.stories.tsx +16 -12
- package/src/components/custom/Workout/SegmentedBar.tsx +4 -3
- package/src/components/custom/Workout/SetStrip.stories.tsx +3 -2
- package/src/components/custom/Workout/SetsRepsLoad.tsx +23 -9
- package/src/components/custom/Workout/Sparkline.stories.tsx +13 -10
- package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +2 -1
- package/src/components/custom/Workout/StrengthTrendChart.tsx +8 -6
- package/src/components/custom/Workout/TempoDisplay.stories.tsx +4 -3
- package/src/components/custom/Workout/TempoDisplay.tsx +2 -0
- package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +3 -2
- package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +1 -1
- package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +40 -0
- package/src/components/custom/Workout/VelocityStrip.test.tsx +48 -6
- package/src/components/custom/Workout/VelocityStrip.tsx +23 -14
- package/src/components/custom/Workout/ZoneTrack.stories.tsx +3 -1
- package/src/components/custom/Workout/exerciseRowState.ts +29 -0
- package/src/components/custom/Workout/index.ts +12 -2
- package/src/components/custom/Workout/metricText.stories.tsx +9 -8
- package/src/components/custom/Workout/metricText.tsx +4 -2
- package/src/components/custom/Workout/setHeadingKit.tsx +12 -10
- package/src/components/custom/Workout/velocity-story-kit.tsx +2 -2
- package/src/components/custom/charts/README.md +5 -0
- package/src/components/custom/charts/SetBarChart.test.tsx +16 -0
- package/src/components/custom/charts/SetBarChart.tsx +14 -5
- package/src/components/custom/charts/flatBarGeometry.test.ts +41 -0
- package/src/components/custom/charts/flatBarGeometry.ts +32 -0
- package/src/components/custom/stepper/Stepper.tsx +8 -6
- package/src/components/ui/alert/Alert.stories.tsx +14 -4
- package/src/components/ui/alert/Alert.tsx +24 -3
- package/src/components/ui/button/Button.tsx +12 -12
- package/src/components/ui/checkbox/Checkbox.tsx +2 -2
- package/src/components/ui/data-row/DataRow.stories.tsx +6 -2
- package/src/components/ui/drawer/Drawer.tsx +4 -1
- package/src/components/ui/icon-box/IconBox.tsx +8 -6
- package/src/components/ui/indicator/Indicator.stories.tsx +4 -3
- package/src/components/ui/list-item/ListItem.stories.tsx +7 -4
- package/src/components/ui/modal/Modal.tsx +2 -0
- package/src/components/ui/pill/Pill.stories.tsx +53 -0
- package/src/components/ui/pill/Pill.tsx +10 -6
- package/src/components/ui/popover/Popover.stories.tsx +1 -1
- package/src/components/ui/progress/Progress.tsx +9 -6
- package/src/components/ui/radio/Radio.tsx +1 -1
- package/src/components/ui/section/Section.stories.tsx +10 -10
- package/src/components/ui/select/Select.tsx +2 -1
- package/src/components/ui/spinner/Spinner.tsx +3 -1
- package/src/components/ui/stack/Stack.stories.tsx +7 -7
- package/src/components/ui/surface/Surface.stories.tsx +75 -28
- package/src/components/ui/switch/Switch.tsx +1 -1
- package/src/components/ui/tabs/Tabs.tsx +4 -2
- package/src/components/ui/toast/Toast.tsx +6 -4
- package/src/components/ui/toolbar-button/ToolbarButton.tsx +13 -6
- package/src/stories/PresetShowcase.stories.tsx +1 -1
- package/src/test/no-raw-color.test.ts +39 -0
- package/src/theme/Alpha.stories.tsx +103 -0
- package/src/theme/ProposedTokensVW82.stories.tsx +414 -0
- package/src/theme/config.ts +12 -0
- package/src/theme/global.css +15 -3
- package/src/theme/subtle-tone-weight.test.ts +163 -0
- package/src/theme/tailwind-var-opacity.test.ts +163 -0
- package/src/theme/tokens/primitives.ts +33 -0
- package/src/theme/tokens/semantic-hex-guard.test.ts +322 -0
- package/src/theme/tokens/semantic.ts +56 -20
- package/src/utils/colors.alpha-adoption.test.ts +408 -0
- package/tailwind.config.js +50 -9
package/dist/index.js
CHANGED
|
@@ -186,33 +186,41 @@ var statusColors = {
|
|
|
186
186
|
subtle: "bg-status-success-subtle",
|
|
187
187
|
outline: "border-2 border-status-success bg-transparent",
|
|
188
188
|
solid: "bg-status-success",
|
|
189
|
+
onSolid: "text-on-status-success",
|
|
189
190
|
border: "border-status-success",
|
|
190
191
|
icon: "text-status-success",
|
|
191
|
-
text: "text-status-success"
|
|
192
|
+
text: "text-status-success",
|
|
193
|
+
subtleText: "text-on-status-success-subtle"
|
|
192
194
|
},
|
|
193
195
|
info: {
|
|
194
196
|
subtle: "bg-status-info-subtle",
|
|
195
197
|
outline: "border-2 border-status-info bg-transparent",
|
|
196
198
|
solid: "bg-status-info",
|
|
199
|
+
onSolid: "text-on-status-info",
|
|
197
200
|
border: "border-status-info",
|
|
198
201
|
icon: "text-status-info",
|
|
199
|
-
text: "text-status-info"
|
|
202
|
+
text: "text-status-info",
|
|
203
|
+
subtleText: "text-on-status-info-subtle"
|
|
200
204
|
},
|
|
201
205
|
warning: {
|
|
202
206
|
subtle: "bg-status-warning-subtle",
|
|
203
207
|
outline: "border-2 border-status-warning bg-transparent",
|
|
204
208
|
solid: "bg-status-warning",
|
|
209
|
+
onSolid: "text-on-status-warning",
|
|
205
210
|
border: "border-status-warning",
|
|
206
211
|
icon: "text-status-warning",
|
|
207
|
-
text: "text-status-warning"
|
|
212
|
+
text: "text-status-warning",
|
|
213
|
+
subtleText: "text-on-status-warning-subtle"
|
|
208
214
|
},
|
|
209
215
|
error: {
|
|
210
216
|
subtle: "bg-status-error-subtle",
|
|
211
217
|
outline: "border-2 border-status-error bg-transparent",
|
|
212
218
|
solid: "bg-status-error",
|
|
219
|
+
onSolid: "text-on-status-error",
|
|
213
220
|
border: "border-status-error",
|
|
214
221
|
icon: "text-status-error",
|
|
215
|
-
text: "text-status-error"
|
|
222
|
+
text: "text-status-error",
|
|
223
|
+
subtleText: "text-on-status-error-subtle"
|
|
216
224
|
}
|
|
217
225
|
};
|
|
218
226
|
var defaultIcons = {
|
|
@@ -256,7 +264,7 @@ function Alert({
|
|
|
256
264
|
className: cn(
|
|
257
265
|
"font-bold",
|
|
258
266
|
isCompact ? "text-base" : "text-lg",
|
|
259
|
-
isSolid ? "
|
|
267
|
+
isSolid ? colors.onSolid : variant === "subtle" ? colors.subtleText : colors.icon
|
|
260
268
|
),
|
|
261
269
|
children: defaultIcons[status]
|
|
262
270
|
}
|
|
@@ -265,7 +273,10 @@ function Alert({
|
|
|
265
273
|
message != null && /* @__PURE__ */ jsx(
|
|
266
274
|
reactNative.Text,
|
|
267
275
|
{
|
|
268
|
-
className: cn(
|
|
276
|
+
className: cn(
|
|
277
|
+
"text-sm font-semibold",
|
|
278
|
+
isSolid ? colors.onSolid : variant === "subtle" ? colors.subtleText : colors.text
|
|
279
|
+
),
|
|
269
280
|
testID: "alert-message",
|
|
270
281
|
children: message
|
|
271
282
|
}
|
|
@@ -279,7 +290,16 @@ function Alert({
|
|
|
279
290
|
accessibilityRole: "button",
|
|
280
291
|
accessibilityLabel: "Close alert",
|
|
281
292
|
className: "ml-2 p-1 rounded web:hover:bg-black/10 active:bg-black/20",
|
|
282
|
-
children: /* @__PURE__ */ jsx(
|
|
293
|
+
children: /* @__PURE__ */ jsx(
|
|
294
|
+
reactNative.Text,
|
|
295
|
+
{
|
|
296
|
+
className: cn(
|
|
297
|
+
"text-lg",
|
|
298
|
+
isSolid ? cn(colors.onSolid, "opacity-70") : "text-text-secondary"
|
|
299
|
+
),
|
|
300
|
+
children: "\xD7"
|
|
301
|
+
}
|
|
302
|
+
)
|
|
283
303
|
}
|
|
284
304
|
)
|
|
285
305
|
]
|
|
@@ -300,6 +320,26 @@ var primitiveColors = {
|
|
|
300
320
|
transparent: "transparent"
|
|
301
321
|
};
|
|
302
322
|
var alertRedVivid = "#FF4757";
|
|
323
|
+
var resultPaletteColors = {
|
|
324
|
+
improve: "#4caf50",
|
|
325
|
+
improveDark: "#248a24",
|
|
326
|
+
degrade: "#ef5350",
|
|
327
|
+
degradeDark: "#b30000",
|
|
328
|
+
inconclusive: "#9E9A97"
|
|
329
|
+
};
|
|
330
|
+
var semanticPins = {
|
|
331
|
+
// Cool navy-black; darker and more blue-shifted than any warm greyRamp step.
|
|
332
|
+
textPrimaryLight: "#121828",
|
|
333
|
+
// Cool blue-grey; outside greyRamp's warm (R>=G>=B) scale.
|
|
334
|
+
textSecondaryLight: "#65748B",
|
|
335
|
+
// Pure neutral grey (R=G=B); no warm greyRamp step lands on it exactly.
|
|
336
|
+
backgroundBaseLight: "#EBEBEB",
|
|
337
|
+
// Near-neutral grey, kept one step off backgroundBaseLight by design.
|
|
338
|
+
dividerLight: "#E8E9EB",
|
|
339
|
+
// Periwinkle/indigo; more purple than any primitiveRamps.blue step. Shared by
|
|
340
|
+
// dark-mode text-link, border-focus and border-input-focus.
|
|
341
|
+
focusIndigoDark: "#828DF8"
|
|
342
|
+
};
|
|
303
343
|
var greyRamp = {
|
|
304
344
|
50: "#F9F6F3",
|
|
305
345
|
// L*97.0 W6
|
|
@@ -732,6 +772,12 @@ var semanticColorsLight = {
|
|
|
732
772
|
// Text on brand backgrounds (on-*)
|
|
733
773
|
"on-brand-primary": primitiveColors.white,
|
|
734
774
|
"on-brand-secondary": primitiveColors.white,
|
|
775
|
+
// Text ON a `-subtle` fill. Light mode keeps today's pairing (the base token) so
|
|
776
|
+
// nothing moves here: light has the same disease mirrored — a light rung on a
|
|
777
|
+
// near-white ramp[50] fill — but correcting it belongs with the light-mode pass
|
|
778
|
+
// in AW-121, not this one.
|
|
779
|
+
"on-brand-primary-subtle": primitiveRamps.orange[400],
|
|
780
|
+
"on-brand-secondary-subtle": primitiveRamps.cyan[600],
|
|
735
781
|
// Status colors (status-*)
|
|
736
782
|
"status-success": primitiveRamps.green[300],
|
|
737
783
|
"status-success-light": primitiveRamps.green[200],
|
|
@@ -767,21 +813,26 @@ var semanticColorsLight = {
|
|
|
767
813
|
"status-info-subtle": primitiveRamps.blue[50],
|
|
768
814
|
"status-info-muted": "rgba(33, 150, 243, 0.30)",
|
|
769
815
|
"status-info-strong": "rgba(33, 150, 243, 0.50)",
|
|
816
|
+
// Text ON a `-subtle` fill — see the on-brand-*-subtle note above.
|
|
817
|
+
"on-status-success-subtle": primitiveRamps.green[300],
|
|
818
|
+
"on-status-error-subtle": primitiveRamps.red[600],
|
|
819
|
+
"on-status-warning-subtle": primitiveRamps.amber[300],
|
|
820
|
+
"on-status-info-subtle": primitiveRamps.blue[500],
|
|
770
821
|
// Text on status backgrounds (on-status-*)
|
|
771
822
|
"on-status-success": primitiveColors.white,
|
|
772
823
|
"on-status-error": primitiveColors.white,
|
|
773
824
|
"on-status-warning": primitiveColors.white,
|
|
774
825
|
"on-status-info": primitiveColors.white,
|
|
775
826
|
// Result/outcome indicators (result-*)
|
|
776
|
-
"result-improve":
|
|
827
|
+
"result-improve": resultPaletteColors.improve,
|
|
777
828
|
// Green - positive outcome
|
|
778
829
|
"result-improve-light": "rgba(76, 175, 80, 0.12)",
|
|
779
|
-
"result-improve-dark":
|
|
780
|
-
"result-degrade":
|
|
830
|
+
"result-improve-dark": resultPaletteColors.improveDark,
|
|
831
|
+
"result-degrade": resultPaletteColors.degrade,
|
|
781
832
|
// Red - negative outcome
|
|
782
833
|
"result-degrade-light": "rgba(239, 83, 80, 0.12)",
|
|
783
|
-
"result-degrade-dark":
|
|
784
|
-
"result-inconclusive":
|
|
834
|
+
"result-degrade-dark": resultPaletteColors.degradeDark,
|
|
835
|
+
"result-inconclusive": resultPaletteColors.inconclusive,
|
|
785
836
|
// Gray - no clear result
|
|
786
837
|
"result-inconclusive-light": "rgba(158, 154, 151, 0.12)",
|
|
787
838
|
"result-neutral": greyRamp[600],
|
|
@@ -813,8 +864,8 @@ var semanticColorsLight = {
|
|
|
813
864
|
"data-10": discreteRainbow[22],
|
|
814
865
|
// Dark Orange
|
|
815
866
|
// Text colors (text-*)
|
|
816
|
-
"text-primary":
|
|
817
|
-
"text-secondary":
|
|
867
|
+
"text-primary": semanticPins.textPrimaryLight,
|
|
868
|
+
"text-secondary": semanticPins.textSecondaryLight,
|
|
818
869
|
"text-tertiary": greyRamp[400],
|
|
819
870
|
"text-disabled": "rgba(55, 65, 81, 0.48)",
|
|
820
871
|
"text-inverse": primitiveColors.white,
|
|
@@ -830,7 +881,7 @@ var semanticColorsLight = {
|
|
|
830
881
|
"surface-input": greyRamp[50],
|
|
831
882
|
// Input field background (filled variant)
|
|
832
883
|
// Background colors (background-*)
|
|
833
|
-
"background-base":
|
|
884
|
+
"background-base": semanticPins.backgroundBaseLight,
|
|
834
885
|
"background-default": primitiveColors.white,
|
|
835
886
|
"background-subtle": greyRamp[50],
|
|
836
887
|
// Frame/bezel chrome — top bar + side nav shell, one step below
|
|
@@ -861,7 +912,7 @@ var semanticColorsLight = {
|
|
|
861
912
|
"interactive-disabled": "rgba(55, 65, 81, 0.12)",
|
|
862
913
|
"interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
|
|
863
914
|
// Divider
|
|
864
|
-
divider:
|
|
915
|
+
divider: semanticPins.dividerLight,
|
|
865
916
|
// Avatar default
|
|
866
917
|
"avatar-background": greyRamp[600],
|
|
867
918
|
"avatar-text": primitiveColors.white
|
|
@@ -879,7 +930,7 @@ var semanticColorsDark = {
|
|
|
879
930
|
"brand-secondary": primitiveRamps.cyan[600],
|
|
880
931
|
"brand-secondary-light": primitiveRamps.cyan[500],
|
|
881
932
|
"brand-secondary-dark": primitiveRamps.cyan[700],
|
|
882
|
-
"brand-secondary-subtle": "rgba(
|
|
933
|
+
"brand-secondary-subtle": "rgba(34, 211, 238, 0.12)",
|
|
883
934
|
"brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
|
|
884
935
|
"brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
|
|
885
936
|
"brand-secondary-hover": primitiveRamps.cyan[500],
|
|
@@ -887,6 +938,14 @@ var semanticColorsDark = {
|
|
|
887
938
|
// Text on brand backgrounds
|
|
888
939
|
"on-brand-primary": primitiveColors.white,
|
|
889
940
|
"on-brand-secondary": primitiveColors.white,
|
|
941
|
+
// Text ON a `-subtle` fill. Its own role: `brand-primary` and friends are tuned to
|
|
942
|
+
// carry a white label as a solid fill, which makes the two deepest of them
|
|
943
|
+
// (cyan[600], red[600]) too dark to read as text on a dark plane. Levelling the
|
|
944
|
+
// family at rung 300 puts every tone within OKLCH L 0.769-0.813 instead of
|
|
945
|
+
// 0.550-0.813. Brand is deliberately left at its own orange[400] (operator, AW-133)
|
|
946
|
+
// so the Voltras tone never drifts; it is the one tone under AA on a raised card.
|
|
947
|
+
"on-brand-primary-subtle": primitiveRamps.orange[400],
|
|
948
|
+
"on-brand-secondary-subtle": primitiveRamps.cyan[300],
|
|
890
949
|
// Status colors
|
|
891
950
|
"status-success": primitiveRamps.green[300],
|
|
892
951
|
"status-success-light": primitiveRamps.green[200],
|
|
@@ -900,7 +959,10 @@ var semanticColorsDark = {
|
|
|
900
959
|
"status-error": primitiveRamps.red[600],
|
|
901
960
|
"status-error-light": primitiveRamps.red[500],
|
|
902
961
|
"status-error-dark": primitiveRamps.red[700],
|
|
903
|
-
|
|
962
|
+
// Alpha 0.08, not the family's 0.12: error's label is red[400], a rung darker than
|
|
963
|
+
// its siblings so it reads RED rather than pink (rung 300 has only 0.121 chroma).
|
|
964
|
+
// Thinning the fill buys back the contrast that extra darkness costs. See AW-133.
|
|
965
|
+
"status-error-subtle": "rgba(247, 113, 117, 0.08)",
|
|
904
966
|
"status-error-muted": "rgba(209, 67, 67, 0.30)",
|
|
905
967
|
"status-error-strong": "rgba(209, 67, 67, 0.50)",
|
|
906
968
|
"status-error-vivid": alertRedVivid,
|
|
@@ -918,7 +980,7 @@ var semanticColorsDark = {
|
|
|
918
980
|
"status-info": primitiveRamps.blue[500],
|
|
919
981
|
"status-info-light": primitiveRamps.blue[300],
|
|
920
982
|
"status-info-dark": primitiveRamps.blue[600],
|
|
921
|
-
"status-info-subtle": "rgba(
|
|
983
|
+
"status-info-subtle": "rgba(120, 194, 255, 0.12)",
|
|
922
984
|
"status-info-muted": "rgba(33, 150, 243, 0.30)",
|
|
923
985
|
"status-info-strong": "rgba(33, 150, 243, 0.50)",
|
|
924
986
|
// Text on status backgrounds
|
|
@@ -926,14 +988,22 @@ var semanticColorsDark = {
|
|
|
926
988
|
"on-status-error": primitiveColors.white,
|
|
927
989
|
"on-status-warning": primitiveColors.white,
|
|
928
990
|
"on-status-info": primitiveColors.white,
|
|
991
|
+
// Text ON a `-subtle` fill — see the on-brand-*-subtle note above. Error is the
|
|
992
|
+
// second deliberate exception to the rung-300 rule (operator, AW-133): red[300]
|
|
993
|
+
// levelled perfectly but read PINK, because a red that light can only hold 0.121
|
|
994
|
+
// chroma. red[400] carries 0.165 and reads red; its fill is thinned to compensate.
|
|
995
|
+
"on-status-success-subtle": primitiveRamps.green[300],
|
|
996
|
+
"on-status-error-subtle": primitiveRamps.red[400],
|
|
997
|
+
"on-status-warning-subtle": primitiveRamps.amber[300],
|
|
998
|
+
"on-status-info-subtle": primitiveRamps.blue[300],
|
|
929
999
|
// Result/outcome indicators (result-*)
|
|
930
|
-
"result-improve":
|
|
1000
|
+
"result-improve": resultPaletteColors.improve,
|
|
931
1001
|
"result-improve-light": "rgba(76, 175, 80, 0.16)",
|
|
932
|
-
"result-improve-dark":
|
|
933
|
-
"result-degrade":
|
|
1002
|
+
"result-improve-dark": resultPaletteColors.improveDark,
|
|
1003
|
+
"result-degrade": resultPaletteColors.degrade,
|
|
934
1004
|
"result-degrade-light": "rgba(239, 83, 80, 0.16)",
|
|
935
|
-
"result-degrade-dark":
|
|
936
|
-
"result-inconclusive":
|
|
1005
|
+
"result-degrade-dark": resultPaletteColors.degradeDark,
|
|
1006
|
+
"result-inconclusive": resultPaletteColors.inconclusive,
|
|
937
1007
|
"result-inconclusive-light": "rgba(158, 154, 151, 0.16)",
|
|
938
1008
|
"result-neutral": greyRamp[400],
|
|
939
1009
|
// Text on result backgrounds
|
|
@@ -964,7 +1034,7 @@ var semanticColorsDark = {
|
|
|
964
1034
|
"text-tertiary": greyRamp[500],
|
|
965
1035
|
"text-disabled": "rgba(255, 255, 255, 0.38)",
|
|
966
1036
|
"text-inverse": greyRamp[950],
|
|
967
|
-
"text-link":
|
|
1037
|
+
"text-link": semanticPins.focusIndigoDark,
|
|
968
1038
|
"text-link-hover": primitiveRamps.blue[400],
|
|
969
1039
|
// Surface colors - dark backgrounds — warm-tapered DERIVED ramp (TD-surface-tokens,
|
|
970
1040
|
// S-1, re-spaced S-3). Shipped verbatim from `deriveSurfaceRamp()` — see
|
|
@@ -1014,10 +1084,10 @@ var semanticColorsDark = {
|
|
|
1014
1084
|
// plane, so it keeps its job without collision.
|
|
1015
1085
|
"border-prominent": greyRamp[800],
|
|
1016
1086
|
// high-visibility divider
|
|
1017
|
-
"border-focus":
|
|
1087
|
+
"border-focus": semanticPins.focusIndigoDark,
|
|
1018
1088
|
"border-input": greyRamp[700],
|
|
1019
1089
|
"border-input-hover": greyRamp[600],
|
|
1020
|
-
"border-input-focus":
|
|
1090
|
+
"border-input-focus": semanticPins.focusIndigoDark,
|
|
1021
1091
|
"border-input-error": primitiveRamps.red[500],
|
|
1022
1092
|
// Alpha hairline separators — the primary separation cue (§4/S-2). Self-
|
|
1023
1093
|
// normalizing: composites toward white by ~the same amount on ANY plane, so
|
|
@@ -1173,12 +1243,12 @@ function getSemanticColors(mode) {
|
|
|
1173
1243
|
// src/components/ui/button/Button.tsx
|
|
1174
1244
|
var textColorMap = {
|
|
1175
1245
|
solid: {
|
|
1176
|
-
primary: "
|
|
1177
|
-
secondary: "
|
|
1178
|
-
success: "
|
|
1179
|
-
error: "
|
|
1180
|
-
warning: "
|
|
1181
|
-
info: "
|
|
1246
|
+
primary: semanticColorsDark["on-brand-primary"],
|
|
1247
|
+
secondary: semanticColorsDark["on-brand-secondary"],
|
|
1248
|
+
success: semanticColorsDark["on-status-success"],
|
|
1249
|
+
error: semanticColorsDark["on-status-error"],
|
|
1250
|
+
warning: semanticColorsDark["on-status-warning"],
|
|
1251
|
+
info: semanticColorsDark["on-status-info"]
|
|
1182
1252
|
},
|
|
1183
1253
|
outline: {
|
|
1184
1254
|
primary: semanticColorsDark["brand-primary"],
|
|
@@ -1249,12 +1319,12 @@ var variantStyles = {
|
|
|
1249
1319
|
};
|
|
1250
1320
|
var textStyles = {
|
|
1251
1321
|
solid: {
|
|
1252
|
-
primary: "text-
|
|
1253
|
-
secondary: "text-
|
|
1254
|
-
success: "text-
|
|
1255
|
-
error: "text-
|
|
1256
|
-
warning: "text-
|
|
1257
|
-
info: "text-
|
|
1322
|
+
primary: "text-on-brand-primary",
|
|
1323
|
+
secondary: "text-on-brand-secondary",
|
|
1324
|
+
success: "text-on-status-success",
|
|
1325
|
+
error: "text-on-status-error",
|
|
1326
|
+
warning: "text-on-status-warning",
|
|
1327
|
+
info: "text-on-status-info"
|
|
1258
1328
|
},
|
|
1259
1329
|
outline: {
|
|
1260
1330
|
primary: "text-brand-primary",
|
|
@@ -2202,13 +2272,16 @@ var toneStyles = {
|
|
|
2202
2272
|
// host is, and an alpha fill composites by the same amount on all of them.
|
|
2203
2273
|
// A `surface-*` fill would vanish on the plane it names. Borderless like the
|
|
2204
2274
|
// six coloured tones — the fill carries the capsule, not a ring.
|
|
2275
|
+
// Label comes from `on-*-subtle`, not the base tone token: the base is tuned to
|
|
2276
|
+
// carry a white label as a solid fill, which left error and accent unreadable
|
|
2277
|
+
// here (AW-133). The on-subtle tokens level the family at one weight.
|
|
2205
2278
|
neutral: "bg-hairline-subtle border-transparent text-text-secondary",
|
|
2206
|
-
brand: "bg-brand-primary-subtle border-transparent text-brand-primary",
|
|
2207
|
-
"brand-secondary": "bg-brand-secondary-subtle border-transparent text-brand-secondary",
|
|
2208
|
-
success: "bg-status-success-subtle border-transparent text-status-success",
|
|
2209
|
-
warning: "bg-status-warning-subtle border-transparent text-status-warning",
|
|
2210
|
-
error: "bg-status-error-subtle border-transparent text-status-error",
|
|
2211
|
-
info: "bg-status-info-subtle border-transparent text-status-info"
|
|
2279
|
+
brand: "bg-brand-primary-subtle border-transparent text-on-brand-primary-subtle",
|
|
2280
|
+
"brand-secondary": "bg-brand-secondary-subtle border-transparent text-on-brand-secondary-subtle",
|
|
2281
|
+
success: "bg-status-success-subtle border-transparent text-on-status-success-subtle",
|
|
2282
|
+
warning: "bg-status-warning-subtle border-transparent text-on-status-warning-subtle",
|
|
2283
|
+
error: "bg-status-error-subtle border-transparent text-on-status-error-subtle",
|
|
2284
|
+
info: "bg-status-info-subtle border-transparent text-on-status-info-subtle"
|
|
2212
2285
|
},
|
|
2213
2286
|
outline: {
|
|
2214
2287
|
neutral: "border-hairline text-text-secondary",
|
|
@@ -2377,7 +2450,8 @@ var sizeMap = {
|
|
|
2377
2450
|
var colorMap = {
|
|
2378
2451
|
primary: SPINNER_PRIMARY,
|
|
2379
2452
|
secondary: SPINNER_SECONDARY,
|
|
2380
|
-
white:
|
|
2453
|
+
white: primitiveColors.white,
|
|
2454
|
+
// VW-82: Tailwind gray-500; no titan grey matches. Left raw, proposed in the PR.
|
|
2381
2455
|
default: "#6B7280"
|
|
2382
2456
|
};
|
|
2383
2457
|
var containerSizes = {
|
|
@@ -2578,8 +2652,8 @@ var Checkbox = React26.forwardRef(function Checkbox2({
|
|
|
2578
2652
|
!isDisabled && "web:hover:border-brand-primary"
|
|
2579
2653
|
),
|
|
2580
2654
|
children: [
|
|
2581
|
-
isChecked && !isIndeterminate && /* @__PURE__ */ jsx(reactNative.View, { className: cn("bg-
|
|
2582
|
-
isIndeterminate && /* @__PURE__ */ jsx(reactNative.View, { className: cn("bg-
|
|
2655
|
+
isChecked && !isIndeterminate && /* @__PURE__ */ jsx(reactNative.View, { className: cn("bg-on-brand-primary rounded-sm", styles2.icon), children: /* @__PURE__ */ jsx(reactNative.Text, { className: "text-brand-primary font-bold text-center leading-none", children: "\u2713" }) }),
|
|
2656
|
+
isIndeterminate && /* @__PURE__ */ jsx(reactNative.View, { className: cn("bg-on-brand-primary h-0.5 w-2/3 rounded") })
|
|
2583
2657
|
]
|
|
2584
2658
|
}
|
|
2585
2659
|
),
|
|
@@ -2636,7 +2710,7 @@ var Switch = React26.forwardRef(function Switch2({
|
|
|
2636
2710
|
reactNative.View,
|
|
2637
2711
|
{
|
|
2638
2712
|
className: cn(
|
|
2639
|
-
"rounded-full bg-
|
|
2713
|
+
"rounded-full bg-on-brand-primary transition-transform",
|
|
2640
2714
|
styles2.thumb,
|
|
2641
2715
|
isChecked && styles2.translate
|
|
2642
2716
|
),
|
|
@@ -2696,6 +2770,8 @@ function Modal({
|
|
|
2696
2770
|
onPress: handleBackdropPress,
|
|
2697
2771
|
className: cn(
|
|
2698
2772
|
"flex-1 items-center justify-center",
|
|
2773
|
+
// VW-82: scrims stay raw — Tailwind v3 drops the `/n` modifier on a
|
|
2774
|
+
// `var()` colour, so a translucent role has to be its own token (proposed).
|
|
2699
2775
|
backdropBlur ? "bg-black/30 web:backdrop-blur-sm" : "bg-black/50",
|
|
2700
2776
|
backdropClassName
|
|
2701
2777
|
),
|
|
@@ -2991,7 +3067,7 @@ function Tab({ index = 0, isDisabled = false, className, children }) {
|
|
|
2991
3067
|
),
|
|
2992
3068
|
"soft-rounded": cn(
|
|
2993
3069
|
"px-4 py-2 rounded-full",
|
|
2994
|
-
isActive ? "bg-brand-primary text-
|
|
3070
|
+
isActive ? "bg-brand-primary text-on-brand-primary" : "text-text-secondary web:hover:text-text-primary"
|
|
2995
3071
|
)
|
|
2996
3072
|
};
|
|
2997
3073
|
return /* @__PURE__ */ jsx(
|
|
@@ -3012,7 +3088,7 @@ function Tab({ index = 0, isDisabled = false, className, children }) {
|
|
|
3012
3088
|
{
|
|
3013
3089
|
className: cn(
|
|
3014
3090
|
"font-medium",
|
|
3015
|
-
isActive ? variant === "soft-rounded" ? "text-
|
|
3091
|
+
isActive ? variant === "soft-rounded" ? "text-on-brand-primary" : "text-text-primary" : "text-text-secondary"
|
|
3016
3092
|
),
|
|
3017
3093
|
children
|
|
3018
3094
|
}
|
|
@@ -3879,6 +3955,7 @@ function Select({
|
|
|
3879
3955
|
accessibilityState: { expanded: isOpen, disabled: isDisabled },
|
|
3880
3956
|
className: cn(
|
|
3881
3957
|
"flex-row items-center justify-between px-4 py-2.5 rounded-md border",
|
|
3958
|
+
// VW-82: scrim-style fill, left raw (see Modal.tsx).
|
|
3882
3959
|
variant === "filled" ? "bg-black/30" : "bg-surface-base",
|
|
3883
3960
|
isInvalid ? "border-border-input-error" : variant === "filled" ? "border-hairline-subtle" : "border-border-input",
|
|
3884
3961
|
!isDisabled && !isInvalid && "web:hover:border-border-input-hover",
|
|
@@ -3952,7 +4029,7 @@ function SelectOption({ option }) {
|
|
|
3952
4029
|
"w-4 h-4 mr-3 rounded border",
|
|
3953
4030
|
selected ? "bg-brand-primary border-brand-primary" : "border-hairline-strong"
|
|
3954
4031
|
),
|
|
3955
|
-
children: selected && /* @__PURE__ */ jsx(reactNative.Text, { className: "text-
|
|
4032
|
+
children: selected && /* @__PURE__ */ jsx(reactNative.Text, { className: "text-on-brand-primary text-xs text-center", children: "\u2713" })
|
|
3956
4033
|
}
|
|
3957
4034
|
),
|
|
3958
4035
|
/* @__PURE__ */ jsx(
|
|
@@ -4009,6 +4086,8 @@ var lightThemeCSSVars = {
|
|
|
4009
4086
|
"--color-brand-secondary-strong": semanticColorsLight["brand-secondary-strong"],
|
|
4010
4087
|
"--color-on-brand-primary": semanticColorsLight["on-brand-primary"],
|
|
4011
4088
|
"--color-on-brand-secondary": semanticColorsLight["on-brand-secondary"],
|
|
4089
|
+
"--color-on-brand-primary-subtle": semanticColorsLight["on-brand-primary-subtle"],
|
|
4090
|
+
"--color-on-brand-secondary-subtle": semanticColorsLight["on-brand-secondary-subtle"],
|
|
4012
4091
|
"--color-status-success": semanticColorsLight["status-success"],
|
|
4013
4092
|
"--color-status-success-subtle": semanticColorsLight["status-success-subtle"],
|
|
4014
4093
|
"--color-status-success-muted": semanticColorsLight["status-success-muted"],
|
|
@@ -4070,6 +4149,10 @@ var lightThemeCSSVars = {
|
|
|
4070
4149
|
"--color-on-status-error": semanticColorsLight["on-status-error"],
|
|
4071
4150
|
"--color-on-status-warning": semanticColorsLight["on-status-warning"],
|
|
4072
4151
|
"--color-on-status-info": semanticColorsLight["on-status-info"],
|
|
4152
|
+
"--color-on-status-success-subtle": semanticColorsLight["on-status-success-subtle"],
|
|
4153
|
+
"--color-on-status-error-subtle": semanticColorsLight["on-status-error-subtle"],
|
|
4154
|
+
"--color-on-status-warning-subtle": semanticColorsLight["on-status-warning-subtle"],
|
|
4155
|
+
"--color-on-status-info-subtle": semanticColorsLight["on-status-info-subtle"],
|
|
4073
4156
|
"--color-result-improve": semanticColorsLight["result-improve"],
|
|
4074
4157
|
"--color-result-improve-light": semanticColorsLight["result-improve-light"],
|
|
4075
4158
|
"--color-result-improve-dark": semanticColorsLight["result-improve-dark"],
|
|
@@ -4122,6 +4205,8 @@ var darkThemeCSSVars = {
|
|
|
4122
4205
|
"--color-brand-secondary-strong": semanticColorsDark["brand-secondary-strong"],
|
|
4123
4206
|
"--color-on-brand-primary": semanticColorsDark["on-brand-primary"],
|
|
4124
4207
|
"--color-on-brand-secondary": semanticColorsDark["on-brand-secondary"],
|
|
4208
|
+
"--color-on-brand-primary-subtle": semanticColorsDark["on-brand-primary-subtle"],
|
|
4209
|
+
"--color-on-brand-secondary-subtle": semanticColorsDark["on-brand-secondary-subtle"],
|
|
4125
4210
|
"--color-status-success": semanticColorsDark["status-success"],
|
|
4126
4211
|
"--color-status-success-subtle": semanticColorsDark["status-success-subtle"],
|
|
4127
4212
|
"--color-status-success-muted": semanticColorsDark["status-success-muted"],
|
|
@@ -4183,6 +4268,10 @@ var darkThemeCSSVars = {
|
|
|
4183
4268
|
"--color-on-status-error": semanticColorsDark["on-status-error"],
|
|
4184
4269
|
"--color-on-status-warning": semanticColorsDark["on-status-warning"],
|
|
4185
4270
|
"--color-on-status-info": semanticColorsDark["on-status-info"],
|
|
4271
|
+
"--color-on-status-success-subtle": semanticColorsDark["on-status-success-subtle"],
|
|
4272
|
+
"--color-on-status-error-subtle": semanticColorsDark["on-status-error-subtle"],
|
|
4273
|
+
"--color-on-status-warning-subtle": semanticColorsDark["on-status-warning-subtle"],
|
|
4274
|
+
"--color-on-status-info-subtle": semanticColorsDark["on-status-info-subtle"],
|
|
4186
4275
|
"--color-result-improve": semanticColorsDark["result-improve"],
|
|
4187
4276
|
"--color-result-improve-light": semanticColorsDark["result-improve-light"],
|
|
4188
4277
|
"--color-result-improve-dark": semanticColorsDark["result-improve-dark"],
|
|
@@ -4530,7 +4619,67 @@ var audiobookPreset = {
|
|
|
4530
4619
|
rootClasses: ["atmosphere-warm", "grain"]
|
|
4531
4620
|
};
|
|
4532
4621
|
|
|
4622
|
+
// src/utils/colors.ts
|
|
4623
|
+
function getStatusColor(status) {
|
|
4624
|
+
return `var(--color-status-${status})`;
|
|
4625
|
+
}
|
|
4626
|
+
function getResultColor(result) {
|
|
4627
|
+
return `var(--color-result-${result})`;
|
|
4628
|
+
}
|
|
4629
|
+
function alpha(color, opacity) {
|
|
4630
|
+
const clampedOpacity = Math.max(0, Math.min(1, opacity));
|
|
4631
|
+
if (color.startsWith("#")) {
|
|
4632
|
+
const hex = color.slice(1);
|
|
4633
|
+
let r, g, b;
|
|
4634
|
+
if (hex.length === 3) {
|
|
4635
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
4636
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
4637
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
4638
|
+
} else if (hex.length === 6) {
|
|
4639
|
+
r = parseInt(hex.slice(0, 2), 16);
|
|
4640
|
+
g = parseInt(hex.slice(2, 4), 16);
|
|
4641
|
+
b = parseInt(hex.slice(4, 6), 16);
|
|
4642
|
+
} else {
|
|
4643
|
+
return color;
|
|
4644
|
+
}
|
|
4645
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
4646
|
+
}
|
|
4647
|
+
const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
4648
|
+
if (rgbMatch) {
|
|
4649
|
+
const [, r, g, b] = rgbMatch;
|
|
4650
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
4651
|
+
}
|
|
4652
|
+
const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
|
|
4653
|
+
if (rgbaMatch) {
|
|
4654
|
+
const [, r, g, b] = rgbaMatch;
|
|
4655
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
4656
|
+
}
|
|
4657
|
+
return color;
|
|
4658
|
+
}
|
|
4659
|
+
function getLuminance(color) {
|
|
4660
|
+
if (!color.startsWith("#")) return "dark";
|
|
4661
|
+
const hex = color.slice(1);
|
|
4662
|
+
let r, g, b;
|
|
4663
|
+
if (hex.length === 3) {
|
|
4664
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
4665
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
4666
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
4667
|
+
} else if (hex.length === 6) {
|
|
4668
|
+
r = parseInt(hex.slice(0, 2), 16);
|
|
4669
|
+
g = parseInt(hex.slice(2, 4), 16);
|
|
4670
|
+
b = parseInt(hex.slice(4, 6), 16);
|
|
4671
|
+
} else {
|
|
4672
|
+
return "dark";
|
|
4673
|
+
}
|
|
4674
|
+
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
4675
|
+
return luminance > 0.5 ? "light" : "dark";
|
|
4676
|
+
}
|
|
4677
|
+
function getContrastText(backgroundColor) {
|
|
4678
|
+
return getLuminance(backgroundColor) === "light" ? "#000000" : "#FFFFFF";
|
|
4679
|
+
}
|
|
4680
|
+
|
|
4533
4681
|
// src/components/ui/toolbar-button/ToolbarButton.tsx
|
|
4682
|
+
var ICON_IDLE = "#D1D1D1";
|
|
4534
4683
|
var ToolbarButtonContext = React26.createContext({
|
|
4535
4684
|
isOpen: false,
|
|
4536
4685
|
setIsOpen: () => {
|
|
@@ -4580,7 +4729,7 @@ function ToolbarButton({
|
|
|
4580
4729
|
const showActive = isActive !== false;
|
|
4581
4730
|
const getIconColor = () => {
|
|
4582
4731
|
if (isActive === true) return resolveColor("brand-primary");
|
|
4583
|
-
return showActive ?
|
|
4732
|
+
return showActive ? primitiveColors.white : ICON_IDLE;
|
|
4584
4733
|
};
|
|
4585
4734
|
const getRaisedStyle = () => {
|
|
4586
4735
|
if (isDisabled) return styles.disabledBg;
|
|
@@ -4669,7 +4818,7 @@ function ToolbarButton({
|
|
|
4669
4818
|
var styles = reactNative.StyleSheet.create({
|
|
4670
4819
|
// Disabled - flat gray background, no shadows
|
|
4671
4820
|
disabledBg: {
|
|
4672
|
-
backgroundColor:
|
|
4821
|
+
backgroundColor: alpha(primitiveColors.white, 0.12),
|
|
4673
4822
|
...reactNative.Platform.select({
|
|
4674
4823
|
web: { boxShadow: "none" },
|
|
4675
4824
|
default: { shadowOpacity: 0, elevation: 0 }
|
|
@@ -4820,7 +4969,7 @@ function Radio({
|
|
|
4820
4969
|
isChecked ? checked : unchecked,
|
|
4821
4970
|
!isDisabled && !isChecked && "web:hover:border-brand-primary"
|
|
4822
4971
|
),
|
|
4823
|
-
children: isChecked && /* @__PURE__ */ jsx(reactNative.View, { className: cn("rounded-full bg-
|
|
4972
|
+
children: isChecked && /* @__PURE__ */ jsx(reactNative.View, { className: cn("rounded-full bg-on-brand-primary", inner) })
|
|
4824
4973
|
}
|
|
4825
4974
|
),
|
|
4826
4975
|
children && /* @__PURE__ */ jsx(reactNative.Text, { className: cn("ml-2 text-text-primary", text), children })
|
|
@@ -4883,7 +5032,13 @@ function Drawer({
|
|
|
4883
5032
|
}
|
|
4884
5033
|
};
|
|
4885
5034
|
return /* @__PURE__ */ jsx(reactNative.Modal, { visible: isOpen, transparent: true, animationType: "fade", onRequestClose: onClose, children: /* @__PURE__ */ jsxs(reactNative.View, { className: "flex-1", children: [
|
|
4886
|
-
/* @__PURE__ */ jsx(
|
|
5035
|
+
/* @__PURE__ */ jsx(
|
|
5036
|
+
reactNative.Pressable,
|
|
5037
|
+
{
|
|
5038
|
+
onPress: handleOverlayPress,
|
|
5039
|
+
className: "absolute inset-0 bg-black/50"
|
|
5040
|
+
}
|
|
5041
|
+
),
|
|
4887
5042
|
/* @__PURE__ */ jsxs(
|
|
4888
5043
|
Surface,
|
|
4889
5044
|
{
|
|
@@ -4961,12 +5116,12 @@ var colorStyles4 = {
|
|
|
4961
5116
|
info: "bg-status-info"
|
|
4962
5117
|
};
|
|
4963
5118
|
var trackColorStyles = {
|
|
4964
|
-
primary: "bg-brand-primary
|
|
4965
|
-
secondary: "bg-brand-secondary
|
|
4966
|
-
success: "bg-status-success
|
|
4967
|
-
error: "bg-status-error
|
|
4968
|
-
warning: "bg-status-warning
|
|
4969
|
-
info: "bg-status-info
|
|
5119
|
+
primary: "bg-brand-primary-muted",
|
|
5120
|
+
secondary: "bg-brand-secondary-muted",
|
|
5121
|
+
success: "bg-status-success-muted",
|
|
5122
|
+
error: "bg-status-error-muted",
|
|
5123
|
+
warning: "bg-status-warning-muted",
|
|
5124
|
+
info: "bg-status-info-muted"
|
|
4970
5125
|
};
|
|
4971
5126
|
function Progress({
|
|
4972
5127
|
value = 0,
|
|
@@ -5203,7 +5358,7 @@ function ToastProvider({
|
|
|
5203
5358
|
[defaultDuration, maxToasts]
|
|
5204
5359
|
);
|
|
5205
5360
|
const removeToast = React26.useCallback((id) => {
|
|
5206
|
-
setToasts((prev) => prev.filter((
|
|
5361
|
+
setToasts((prev) => prev.filter((t19) => t19.id !== id));
|
|
5207
5362
|
}, []);
|
|
5208
5363
|
const removeAllToasts = React26.useCallback(() => {
|
|
5209
5364
|
setToasts([]);
|
|
@@ -5239,22 +5394,22 @@ function useToast() {
|
|
|
5239
5394
|
}
|
|
5240
5395
|
var statusStyles = {
|
|
5241
5396
|
success: {
|
|
5242
|
-
bg: "bg-status-success
|
|
5397
|
+
bg: "bg-status-success-subtle",
|
|
5243
5398
|
border: "border-status-success",
|
|
5244
5399
|
icon: "\u2713"
|
|
5245
5400
|
},
|
|
5246
5401
|
error: {
|
|
5247
|
-
bg: "bg-status-error
|
|
5402
|
+
bg: "bg-status-error-subtle",
|
|
5248
5403
|
border: "border-status-error",
|
|
5249
5404
|
icon: "\u2715"
|
|
5250
5405
|
},
|
|
5251
5406
|
warning: {
|
|
5252
|
-
bg: "bg-status-warning
|
|
5407
|
+
bg: "bg-status-warning-subtle",
|
|
5253
5408
|
border: "border-status-warning",
|
|
5254
5409
|
icon: "\u26A0"
|
|
5255
5410
|
},
|
|
5256
5411
|
info: {
|
|
5257
|
-
bg: "bg-status-info
|
|
5412
|
+
bg: "bg-status-info-subtle",
|
|
5258
5413
|
border: "border-status-info",
|
|
5259
5414
|
icon: "\u2139"
|
|
5260
5415
|
}
|
|
@@ -5864,12 +6019,12 @@ function DataRow({
|
|
|
5864
6019
|
] });
|
|
5865
6020
|
}
|
|
5866
6021
|
var colorClasses = {
|
|
5867
|
-
primary: { bg: "bg-brand-primary
|
|
5868
|
-
secondary: { bg: "bg-brand-secondary
|
|
5869
|
-
success: { bg: "bg-status-success
|
|
5870
|
-
error: { bg: "bg-status-error
|
|
5871
|
-
warning: { bg: "bg-status-warning
|
|
5872
|
-
info: { bg: "bg-status-info
|
|
6022
|
+
primary: { bg: "bg-brand-primary-subtle", icon: "text-brand-primary" },
|
|
6023
|
+
secondary: { bg: "bg-brand-secondary-subtle", icon: "text-brand-secondary" },
|
|
6024
|
+
success: { bg: "bg-status-success-subtle", icon: "text-status-success" },
|
|
6025
|
+
error: { bg: "bg-status-error-subtle", icon: "text-status-error" },
|
|
6026
|
+
warning: { bg: "bg-status-warning-subtle", icon: "text-status-warning" },
|
|
6027
|
+
info: { bg: "bg-status-info-subtle", icon: "text-status-info" },
|
|
5873
6028
|
neutral: { bg: "bg-surface-elevated", icon: "text-text-secondary" }
|
|
5874
6029
|
};
|
|
5875
6030
|
var sizeClasses = {
|
|
@@ -6643,6 +6798,12 @@ function StepIndicator({
|
|
|
6643
6798
|
upcoming: "bg-surface-base border-hairline-strong",
|
|
6644
6799
|
error: "bg-status-error border-status-error"
|
|
6645
6800
|
};
|
|
6801
|
+
const glyphStyles = {
|
|
6802
|
+
completed: "text-on-brand-primary",
|
|
6803
|
+
active: "text-on-brand-primary",
|
|
6804
|
+
upcoming: "text-text-secondary",
|
|
6805
|
+
error: "text-on-status-error"
|
|
6806
|
+
};
|
|
6646
6807
|
return /* @__PURE__ */ jsx(
|
|
6647
6808
|
reactNative.View,
|
|
6648
6809
|
{
|
|
@@ -6651,16 +6812,7 @@ function StepIndicator({
|
|
|
6651
6812
|
statusStyles2[status],
|
|
6652
6813
|
className
|
|
6653
6814
|
),
|
|
6654
|
-
children: icon || /* @__PURE__ */ jsx(
|
|
6655
|
-
reactNative.Text,
|
|
6656
|
-
{
|
|
6657
|
-
className: cn(
|
|
6658
|
-
"text-sm font-semibold",
|
|
6659
|
-
status === "upcoming" ? "text-text-secondary" : "text-white"
|
|
6660
|
-
),
|
|
6661
|
-
children: status === "completed" ? "\u2713" : index + 1
|
|
6662
|
-
}
|
|
6663
|
-
)
|
|
6815
|
+
children: icon || /* @__PURE__ */ jsx(reactNative.Text, { className: cn("text-sm font-semibold", glyphStyles[status]), children: status === "completed" ? "\u2713" : index + 1 })
|
|
6664
6816
|
}
|
|
6665
6817
|
);
|
|
6666
6818
|
}
|
|
@@ -7030,8 +7182,8 @@ var baseBadgeSizeConfig = {
|
|
|
7030
7182
|
var variantColors = {
|
|
7031
7183
|
plain: { backgroundColor: t2["surface-raised"], borderColor: t2["hairline-default"] },
|
|
7032
7184
|
pr: {
|
|
7033
|
-
backgroundColor: "
|
|
7034
|
-
borderColor: "
|
|
7185
|
+
backgroundColor: alpha(t2["brand-primary"], 0.12),
|
|
7186
|
+
borderColor: alpha(t2["brand-primary"], 0.3)
|
|
7035
7187
|
}
|
|
7036
7188
|
};
|
|
7037
7189
|
function BaseBadge({
|
|
@@ -7261,67 +7413,6 @@ function PrBadge({
|
|
|
7261
7413
|
}
|
|
7262
7414
|
return badge;
|
|
7263
7415
|
}
|
|
7264
|
-
|
|
7265
|
-
// src/utils/colors.ts
|
|
7266
|
-
function getStatusColor(status) {
|
|
7267
|
-
return `var(--color-status-${status})`;
|
|
7268
|
-
}
|
|
7269
|
-
function getResultColor(result) {
|
|
7270
|
-
return `var(--color-result-${result})`;
|
|
7271
|
-
}
|
|
7272
|
-
function alpha(color, opacity) {
|
|
7273
|
-
const clampedOpacity = Math.max(0, Math.min(1, opacity));
|
|
7274
|
-
if (color.startsWith("#")) {
|
|
7275
|
-
const hex = color.slice(1);
|
|
7276
|
-
let r, g, b;
|
|
7277
|
-
if (hex.length === 3) {
|
|
7278
|
-
r = parseInt(hex[0] + hex[0], 16);
|
|
7279
|
-
g = parseInt(hex[1] + hex[1], 16);
|
|
7280
|
-
b = parseInt(hex[2] + hex[2], 16);
|
|
7281
|
-
} else if (hex.length === 6) {
|
|
7282
|
-
r = parseInt(hex.slice(0, 2), 16);
|
|
7283
|
-
g = parseInt(hex.slice(2, 4), 16);
|
|
7284
|
-
b = parseInt(hex.slice(4, 6), 16);
|
|
7285
|
-
} else {
|
|
7286
|
-
return color;
|
|
7287
|
-
}
|
|
7288
|
-
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
7289
|
-
}
|
|
7290
|
-
const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
7291
|
-
if (rgbMatch) {
|
|
7292
|
-
const [, r, g, b] = rgbMatch;
|
|
7293
|
-
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
7294
|
-
}
|
|
7295
|
-
const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
|
|
7296
|
-
if (rgbaMatch) {
|
|
7297
|
-
const [, r, g, b] = rgbaMatch;
|
|
7298
|
-
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
7299
|
-
}
|
|
7300
|
-
return color;
|
|
7301
|
-
}
|
|
7302
|
-
function getLuminance(color) {
|
|
7303
|
-
if (!color.startsWith("#")) return "dark";
|
|
7304
|
-
const hex = color.slice(1);
|
|
7305
|
-
let r, g, b;
|
|
7306
|
-
if (hex.length === 3) {
|
|
7307
|
-
r = parseInt(hex[0] + hex[0], 16);
|
|
7308
|
-
g = parseInt(hex[1] + hex[1], 16);
|
|
7309
|
-
b = parseInt(hex[2] + hex[2], 16);
|
|
7310
|
-
} else if (hex.length === 6) {
|
|
7311
|
-
r = parseInt(hex.slice(0, 2), 16);
|
|
7312
|
-
g = parseInt(hex.slice(2, 4), 16);
|
|
7313
|
-
b = parseInt(hex.slice(4, 6), 16);
|
|
7314
|
-
} else {
|
|
7315
|
-
return "dark";
|
|
7316
|
-
}
|
|
7317
|
-
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
7318
|
-
return luminance > 0.5 ? "light" : "dark";
|
|
7319
|
-
}
|
|
7320
|
-
function getContrastText(backgroundColor) {
|
|
7321
|
-
return getLuminance(backgroundColor) === "light" ? "#000000" : "#FFFFFF";
|
|
7322
|
-
}
|
|
7323
|
-
|
|
7324
|
-
// src/components/custom/Workout/StatusDot.tsx
|
|
7325
7416
|
var solidFillToken = {
|
|
7326
7417
|
success: "status-success",
|
|
7327
7418
|
warning: "status-warning",
|
|
@@ -7617,7 +7708,7 @@ function formatPrescription(p) {
|
|
|
7617
7708
|
return full.length > 0 ? full : null;
|
|
7618
7709
|
}
|
|
7619
7710
|
var METRIC_FONT = "Inter, sans-serif";
|
|
7620
|
-
function MetricCell({ children, color, fontSize = 11 }) {
|
|
7711
|
+
function MetricCell({ children, color, fontSize = 11, weight = 600 }) {
|
|
7621
7712
|
return /* @__PURE__ */ jsx(
|
|
7622
7713
|
reactNative.Text,
|
|
7623
7714
|
{
|
|
@@ -7625,7 +7716,7 @@ function MetricCell({ children, color, fontSize = 11 }) {
|
|
|
7625
7716
|
fontFamily: METRIC_FONT,
|
|
7626
7717
|
fontSize,
|
|
7627
7718
|
color,
|
|
7628
|
-
fontWeight:
|
|
7719
|
+
fontWeight: String(weight),
|
|
7629
7720
|
letterSpacing: 1
|
|
7630
7721
|
},
|
|
7631
7722
|
children
|
|
@@ -7972,7 +8063,10 @@ function DeviationBar({ deviation, width, className, ...props }) {
|
|
|
7972
8063
|
width: resolvedWidth,
|
|
7973
8064
|
borderRadius: 3,
|
|
7974
8065
|
// react-native-web renders backgroundImage at runtime; not in RN ViewStyle types
|
|
7975
|
-
|
|
8066
|
+
// rgba(107,114,128,0.15) at 50% has no exact token match (nearest:
|
|
8067
|
+
// semanticPins.textSecondaryLight #65748B, ΔRGB ~12.7) — left as a
|
|
8068
|
+
// raw literal (VW-78).
|
|
8069
|
+
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%)`
|
|
7976
8070
|
}
|
|
7977
8071
|
}
|
|
7978
8072
|
),
|
|
@@ -8003,7 +8097,7 @@ function DeviationBar({ deviation, width, className, ...props }) {
|
|
|
8003
8097
|
var t5 = getSemanticColors("dark");
|
|
8004
8098
|
var TRACK_BG = "#333333";
|
|
8005
8099
|
var LABEL_COLOR = "#6B7280";
|
|
8006
|
-
var TARGET_LINE_COLOR = "
|
|
8100
|
+
var TARGET_LINE_COLOR = alpha(t5["status-info"], 0.5);
|
|
8007
8101
|
var AT_TARGET_GLOW = getGlowShadow(t5["status-info"], "subtle");
|
|
8008
8102
|
var ZONE = {
|
|
8009
8103
|
building: t5["status-success"],
|
|
@@ -8397,15 +8491,31 @@ function useLiveRepGrowth(active, liveRepIndex, liveVelocity, isNewPeak) {
|
|
|
8397
8491
|
return liveGrowth;
|
|
8398
8492
|
}
|
|
8399
8493
|
|
|
8494
|
+
// src/components/custom/charts/flatBarGeometry.ts
|
|
8495
|
+
var SET_LEVEL_FLAT_BAR = {
|
|
8496
|
+
/** Track height (px). */
|
|
8497
|
+
height: 8,
|
|
8498
|
+
/** Gap between segment slots (px) — also SetStrip's between-set gap, see `SEGMENTED_BAR_GAP`. */
|
|
8499
|
+
gap: 5,
|
|
8500
|
+
/** Corner radius (px). */
|
|
8501
|
+
radius: 2
|
|
8502
|
+
};
|
|
8503
|
+
var REP_LEVEL_FLAT_BAR = {
|
|
8504
|
+
/** Inter-bar gap is proportional (`gapRatio · barWidth`), floored at this many px. */
|
|
8505
|
+
gapFloor: 2,
|
|
8506
|
+
/** Corner radius (px) default. */
|
|
8507
|
+
radius: 5
|
|
8508
|
+
};
|
|
8509
|
+
|
|
8400
8510
|
// src/components/custom/charts/SetBarChart.tsx
|
|
8401
|
-
function mixHex(a, b,
|
|
8511
|
+
function mixHex(a, b, t19) {
|
|
8402
8512
|
const parse = (h) => {
|
|
8403
8513
|
const s = h.replace("#", "");
|
|
8404
8514
|
return [parseInt(s.slice(0, 2), 16), parseInt(s.slice(2, 4), 16), parseInt(s.slice(4, 6), 16)];
|
|
8405
8515
|
};
|
|
8406
8516
|
const [ar, ag, ab] = parse(a);
|
|
8407
8517
|
const [br, bg, bb] = parse(b);
|
|
8408
|
-
const ch = (x, y) => Math.round(x + (y - x) *
|
|
8518
|
+
const ch = (x, y) => Math.round(x + (y - x) * t19).toString(16).padStart(2, "0");
|
|
8409
8519
|
return `#${ch(ar, br)}${ch(ag, bg)}${ch(ab, bb)}`;
|
|
8410
8520
|
}
|
|
8411
8521
|
var VARIABLE_FILL = primitiveRamps.cyan[900];
|
|
@@ -8413,7 +8523,7 @@ var CONTINUE_OUTLINE = primitiveRamps.cyan[800];
|
|
|
8413
8523
|
var FIXED_MAX_VALUE = 1.15;
|
|
8414
8524
|
var PEAK_HEADROOM = 1.03;
|
|
8415
8525
|
function scaleDenominator(scale, maxValue) {
|
|
8416
|
-
return scale === "fixed" ? FIXED_MAX_VALUE : maxValue * PEAK_HEADROOM;
|
|
8526
|
+
return (scale === "fixed" ? FIXED_MAX_VALUE : maxValue) * PEAK_HEADROOM;
|
|
8417
8527
|
}
|
|
8418
8528
|
function valueLabelFontSize(height) {
|
|
8419
8529
|
return Math.round(Math.max(8, Math.min(12, height * 0.11)));
|
|
@@ -8429,12 +8539,12 @@ var SET_BAR_DEFAULT_HEIGHT = 220;
|
|
|
8429
8539
|
var LABEL_ROW_HEIGHT = 16;
|
|
8430
8540
|
var LABEL_GAP = 3;
|
|
8431
8541
|
var GAP_RATIO = 0.08;
|
|
8432
|
-
var MIN_BAR_GAP =
|
|
8542
|
+
var MIN_BAR_GAP = REP_LEVEL_FLAT_BAR.gapFloor;
|
|
8433
8543
|
var CHUNK_NOTCH_RATIO = 0.25;
|
|
8434
8544
|
var CHUNK_NOTCH_MIN_PX = 10;
|
|
8435
8545
|
var BAR_MAX_WIDTH = 120;
|
|
8436
8546
|
var LABEL_MIN_BAR_WIDTH = 30;
|
|
8437
|
-
var DEFAULT_BAR_RADIUS =
|
|
8547
|
+
var DEFAULT_BAR_RADIUS = REP_LEVEL_FLAT_BAR.radius;
|
|
8438
8548
|
var MIN_BAR_HEIGHT = 4;
|
|
8439
8549
|
var FLAT_BAR_FRACTION = 0.5;
|
|
8440
8550
|
var STUB_HEIGHT = 9;
|
|
@@ -9257,7 +9367,8 @@ function DualVelocityStrip({
|
|
|
9257
9367
|
className,
|
|
9258
9368
|
...props
|
|
9259
9369
|
}) {
|
|
9260
|
-
const
|
|
9370
|
+
const resolvedVariant = variant === "rail" ? "dual-expanded" : variant;
|
|
9371
|
+
const resolvedHeight = height ?? (resolvedVariant === "hero" ? DUAL_HERO_HEIGHT : resolvedVariant === "compact" ? DUAL_COMPACT_HEIGHT : DUAL_RAIL_HEIGHT);
|
|
9261
9372
|
const leftDone = streamDone(left);
|
|
9262
9373
|
const rightDone = streamDone(right);
|
|
9263
9374
|
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`;
|
|
@@ -9277,8 +9388,9 @@ function DualVelocityStrip({
|
|
|
9277
9388
|
label,
|
|
9278
9389
|
viewProps: props
|
|
9279
9390
|
};
|
|
9280
|
-
if (
|
|
9281
|
-
|
|
9391
|
+
if (resolvedVariant === "dual-expanded")
|
|
9392
|
+
return /* @__PURE__ */ jsx(DualVelocityRail, { ...shared, liveRepIndex });
|
|
9393
|
+
if (resolvedVariant === "compact") return /* @__PURE__ */ jsx(DualVelocityCompactStrip, { ...shared });
|
|
9282
9394
|
return /* @__PURE__ */ jsx(DualVelocityHero, { ...shared, liveRepIndex });
|
|
9283
9395
|
}
|
|
9284
9396
|
function VelocityStrip({
|
|
@@ -9891,7 +10003,9 @@ function SetRow(set) {
|
|
|
9891
10003
|
}
|
|
9892
10004
|
);
|
|
9893
10005
|
}
|
|
9894
|
-
var
|
|
10006
|
+
var t6 = getSemanticColors("dark");
|
|
10007
|
+
var BRAND_PRIMARY = t6["brand-primary"];
|
|
10008
|
+
var ON_BRAND_PRIMARY = t6["on-brand-primary"];
|
|
9895
10009
|
var INPUT_CLASSNAME = "bg-surface-raised border-hairline-strong text-text-primary";
|
|
9896
10010
|
var inputStyle = {
|
|
9897
10011
|
fontSize: 14,
|
|
@@ -10036,7 +10150,7 @@ function InputBar({
|
|
|
10036
10150
|
fontSize: 13,
|
|
10037
10151
|
fontWeight: "700",
|
|
10038
10152
|
fontFamily: "Inter, sans-serif",
|
|
10039
|
-
color:
|
|
10153
|
+
color: ON_BRAND_PRIMARY
|
|
10040
10154
|
},
|
|
10041
10155
|
children: "Record"
|
|
10042
10156
|
}
|
|
@@ -10056,7 +10170,7 @@ function RestActions({ onAddTime, onSkip }) {
|
|
|
10056
10170
|
{
|
|
10057
10171
|
onPress: onAddTime,
|
|
10058
10172
|
style: {
|
|
10059
|
-
backgroundColor:
|
|
10173
|
+
backgroundColor: alpha(primitiveColors.white, 0.06),
|
|
10060
10174
|
paddingVertical: 8,
|
|
10061
10175
|
paddingHorizontal: 20,
|
|
10062
10176
|
borderRadius: 8
|
|
@@ -10079,7 +10193,7 @@ function RestActions({ onAddTime, onSkip }) {
|
|
|
10079
10193
|
{
|
|
10080
10194
|
onPress: onSkip,
|
|
10081
10195
|
style: {
|
|
10082
|
-
backgroundColor:
|
|
10196
|
+
backgroundColor: alpha(BRAND_PRIMARY2, 0.12),
|
|
10083
10197
|
paddingVertical: 8,
|
|
10084
10198
|
paddingHorizontal: 20,
|
|
10085
10199
|
borderRadius: 8
|
|
@@ -10291,11 +10405,17 @@ function SetsRepsLoad({
|
|
|
10291
10405
|
load,
|
|
10292
10406
|
unit = "lb",
|
|
10293
10407
|
fontSize,
|
|
10408
|
+
muted = false,
|
|
10294
10409
|
className,
|
|
10295
10410
|
...props
|
|
10296
10411
|
}) {
|
|
10297
|
-
const
|
|
10298
|
-
const
|
|
10412
|
+
const primary = useOnSurfaceColor("primary");
|
|
10413
|
+
const tertiary = useOnSurfaceColor("tertiary");
|
|
10414
|
+
const secondary = useOnSurfaceColor("secondary");
|
|
10415
|
+
const value = muted ? secondary : primary;
|
|
10416
|
+
const sep = muted ? secondary : tertiary;
|
|
10417
|
+
const weight = muted ? 400 : 600;
|
|
10418
|
+
const times = muted ? TIMES : ` ${TIMES} `;
|
|
10299
10419
|
return /* @__PURE__ */ jsxs(
|
|
10300
10420
|
reactNative.View,
|
|
10301
10421
|
{
|
|
@@ -10305,19 +10425,19 @@ function SetsRepsLoad({
|
|
|
10305
10425
|
testID: "sets-reps-load",
|
|
10306
10426
|
...props,
|
|
10307
10427
|
children: [
|
|
10308
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: sets }),
|
|
10309
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children:
|
|
10310
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: reps }),
|
|
10311
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${AT} ` }),
|
|
10312
|
-
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, children: load }),
|
|
10313
|
-
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, children: ` ${unit}` })
|
|
10428
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, weight, children: sets }),
|
|
10429
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, weight, children: times }),
|
|
10430
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, weight, children: reps }),
|
|
10431
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, weight, children: ` ${AT} ` }),
|
|
10432
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, fontSize, weight, children: load }),
|
|
10433
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, fontSize, weight, children: ` ${unit}` })
|
|
10314
10434
|
]
|
|
10315
10435
|
}
|
|
10316
10436
|
);
|
|
10317
10437
|
}
|
|
10318
10438
|
var PULSE_HALF_MS = 950;
|
|
10319
10439
|
var PULSE_MIN_OPACITY = 0.45;
|
|
10320
|
-
var SEGMENTED_BAR_GAP =
|
|
10440
|
+
var SEGMENTED_BAR_GAP = SET_LEVEL_FLAT_BAR.gap;
|
|
10321
10441
|
function usePulse2(active) {
|
|
10322
10442
|
const [value] = React26.useState(() => new reactNative.Animated.Value(0));
|
|
10323
10443
|
React26.useEffect(() => {
|
|
@@ -10345,9 +10465,9 @@ function usePulse2(active) {
|
|
|
10345
10465
|
}
|
|
10346
10466
|
function SegmentedBar({
|
|
10347
10467
|
segments,
|
|
10348
|
-
height =
|
|
10468
|
+
height = SET_LEVEL_FLAT_BAR.height,
|
|
10349
10469
|
gap = SEGMENTED_BAR_GAP,
|
|
10350
|
-
radius =
|
|
10470
|
+
radius = SET_LEVEL_FLAT_BAR.radius,
|
|
10351
10471
|
marker = null,
|
|
10352
10472
|
segmentTestID,
|
|
10353
10473
|
style,
|
|
@@ -10708,41 +10828,102 @@ function ExerciseIndicator({ kind, onPress, className, ...props }) {
|
|
|
10708
10828
|
}
|
|
10709
10829
|
return chip;
|
|
10710
10830
|
}
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10831
|
+
|
|
10832
|
+
// src/components/custom/Workout/exerciseRowState.ts
|
|
10833
|
+
var ROW_STATE_TOKEN = {
|
|
10834
|
+
hovered: "interactive-hover",
|
|
10835
|
+
selected: "interactive-selected",
|
|
10836
|
+
pressed: "interactive-active"
|
|
10837
|
+
};
|
|
10838
|
+
function exerciseRowStateColor(state, mode = "dark") {
|
|
10839
|
+
return getSemanticColors(mode)[ROW_STATE_TOKEN[state]];
|
|
10840
|
+
}
|
|
10841
|
+
function exerciseLiveColor(mode = "dark") {
|
|
10842
|
+
return getSemanticColors(mode)["status-live"];
|
|
10843
|
+
}
|
|
10844
|
+
|
|
10845
|
+
// src/components/custom/Workout/ExerciseHeading.tsx
|
|
10846
|
+
var DIMMED_OPACITY = 0.55;
|
|
10847
|
+
function prescriptionText(p, unit) {
|
|
10848
|
+
if (p.prescription !== void 0) return p.prescription;
|
|
10849
|
+
if (p.sets === void 0) return void 0;
|
|
10850
|
+
const loadLabel = typeof p.load === "number" ? roundWeight(p.load) : p.load;
|
|
10851
|
+
return `${p.sets}\xD7${p.reps} @ ${loadLabel} ${unit}`;
|
|
10852
|
+
}
|
|
10853
|
+
function exerciseHeadingLabel(p, unit = p.unit ?? "lbs") {
|
|
10854
|
+
const prescription = prescriptionText(p, unit);
|
|
10855
|
+
return prescription ? `${p.name}, ${prescription}` : p.name;
|
|
10856
|
+
}
|
|
10857
|
+
function pressProps(p, unit) {
|
|
10858
|
+
return {
|
|
10859
|
+
onPress: p.onPress,
|
|
10860
|
+
onPressIn: p.onPressIn,
|
|
10861
|
+
onPressOut: p.onPressOut,
|
|
10862
|
+
onHoverIn: p.onHoverIn,
|
|
10863
|
+
onHoverOut: p.onHoverOut,
|
|
10864
|
+
accessibilityRole: "button",
|
|
10865
|
+
accessibilityLabel: exerciseHeadingLabel(p, unit)
|
|
10866
|
+
};
|
|
10714
10867
|
}
|
|
10715
|
-
function
|
|
10868
|
+
function HeadingName({
|
|
10716
10869
|
name,
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
load,
|
|
10720
|
-
unit = "lbs",
|
|
10721
|
-
tempo,
|
|
10722
|
-
indicator,
|
|
10723
|
-
dimmed,
|
|
10724
|
-
onPress
|
|
10870
|
+
nameStyle,
|
|
10871
|
+
className
|
|
10725
10872
|
}) {
|
|
10726
|
-
return
|
|
10873
|
+
return (
|
|
10874
|
+
// The row is a button label, not a heading, so `boldLabel` carries the weight and
|
|
10875
|
+
// no header role has to be undone. Size and the Space Grotesk face are pinned.
|
|
10876
|
+
/* @__PURE__ */ jsx(
|
|
10877
|
+
Typography,
|
|
10878
|
+
{
|
|
10879
|
+
variant: "boldLabel",
|
|
10880
|
+
color: nameStyle ? "inherit" : "primary",
|
|
10881
|
+
style: nameStyle,
|
|
10882
|
+
className: cn("font-heading text-sm leading-[normal]", className),
|
|
10883
|
+
testID: "exercise-card-name",
|
|
10884
|
+
children: name
|
|
10885
|
+
}
|
|
10886
|
+
)
|
|
10887
|
+
);
|
|
10888
|
+
}
|
|
10889
|
+
function prescriptionNode(p, unit) {
|
|
10890
|
+
if (p.prescription !== void 0) {
|
|
10891
|
+
return /* @__PURE__ */ jsx(
|
|
10892
|
+
Typography,
|
|
10893
|
+
{
|
|
10894
|
+
variant: "caption",
|
|
10895
|
+
color: "secondary",
|
|
10896
|
+
maxLines: 1,
|
|
10897
|
+
className: "font-sans shrink leading-[normal]",
|
|
10898
|
+
testID: "exercise-card-prescription",
|
|
10899
|
+
children: p.prescription
|
|
10900
|
+
}
|
|
10901
|
+
);
|
|
10902
|
+
}
|
|
10903
|
+
if (p.sets === void 0) return null;
|
|
10904
|
+
return /* @__PURE__ */ jsx(
|
|
10905
|
+
SetsRepsLoad,
|
|
10906
|
+
{
|
|
10907
|
+
sets: p.sets,
|
|
10908
|
+
reps: p.reps,
|
|
10909
|
+
load: p.load,
|
|
10910
|
+
unit,
|
|
10911
|
+
muted: p.mutedPrescription
|
|
10912
|
+
}
|
|
10913
|
+
);
|
|
10914
|
+
}
|
|
10915
|
+
function StackedHeading({ heading, nameStyle }) {
|
|
10916
|
+
const { unit = "lbs", tempo, indicator } = heading;
|
|
10917
|
+
return /* @__PURE__ */ jsxs(jsxRuntime.Fragment, { children: [
|
|
10727
10918
|
/* @__PURE__ */ jsxs(
|
|
10728
10919
|
reactNative.Pressable,
|
|
10729
10920
|
{
|
|
10730
|
-
|
|
10731
|
-
accessibilityRole: "button",
|
|
10732
|
-
accessibilityLabel: headingLabel(name, sets, reps, load, unit),
|
|
10921
|
+
...pressProps(heading, unit),
|
|
10733
10922
|
className: "flex-row items-center",
|
|
10734
10923
|
style: { gap: 8 },
|
|
10735
10924
|
testID: "exercise-card-header",
|
|
10736
10925
|
children: [
|
|
10737
|
-
/* @__PURE__ */ jsx(
|
|
10738
|
-
Typography,
|
|
10739
|
-
{
|
|
10740
|
-
variant: "boldLabel",
|
|
10741
|
-
className: "font-heading text-sm leading-[normal]",
|
|
10742
|
-
testID: "exercise-card-name",
|
|
10743
|
-
children: name
|
|
10744
|
-
}
|
|
10745
|
-
),
|
|
10926
|
+
/* @__PURE__ */ jsx(HeadingName, { name: heading.name, nameStyle }),
|
|
10746
10927
|
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1" }),
|
|
10747
10928
|
indicator && /* @__PURE__ */ jsx(ExerciseIndicator, { kind: indicator })
|
|
10748
10929
|
]
|
|
@@ -10755,7 +10936,7 @@ function ExerciseHeading({
|
|
|
10755
10936
|
style: { gap: 8, marginTop: 1 },
|
|
10756
10937
|
testID: "exercise-card-summary",
|
|
10757
10938
|
children: [
|
|
10758
|
-
|
|
10939
|
+
prescriptionNode(heading, unit),
|
|
10759
10940
|
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1" }),
|
|
10760
10941
|
tempo && /* @__PURE__ */ jsx(TempoDisplay, { tempo, size: "sm", showLabel: false, showInfo: false })
|
|
10761
10942
|
]
|
|
@@ -10763,20 +10944,148 @@ function ExerciseHeading({
|
|
|
10763
10944
|
)
|
|
10764
10945
|
] });
|
|
10765
10946
|
}
|
|
10766
|
-
function
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
dimmed,
|
|
10770
|
-
testID = "exercise-card",
|
|
10771
|
-
...heading
|
|
10772
|
-
}) {
|
|
10947
|
+
function InlineHeading({ heading, nameStyle }) {
|
|
10948
|
+
const { unit = "lbs", indicator, previousBest } = heading;
|
|
10949
|
+
const Row = heading.pressTarget === "ancestor" ? reactNative.View : reactNative.Pressable;
|
|
10773
10950
|
return /* @__PURE__ */ jsxs(
|
|
10774
|
-
|
|
10951
|
+
Row,
|
|
10952
|
+
{
|
|
10953
|
+
...heading.pressTarget === "ancestor" ? {} : pressProps(heading, unit),
|
|
10954
|
+
className: "flex-row items-center",
|
|
10955
|
+
style: { gap: 8 },
|
|
10956
|
+
testID: "exercise-card-header",
|
|
10957
|
+
children: [
|
|
10958
|
+
/* @__PURE__ */ jsx(HeadingName, { name: heading.name, nameStyle, className: "shrink-0" }),
|
|
10959
|
+
/* @__PURE__ */ jsx(reactNative.View, { className: "shrink flex-row items-center", testID: "exercise-card-summary", children: prescriptionNode(heading, unit) }),
|
|
10960
|
+
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1", style: { minWidth: 8 } }),
|
|
10961
|
+
indicator && /* @__PURE__ */ jsx(ExerciseIndicator, { kind: indicator }),
|
|
10962
|
+
previousBest && /* @__PURE__ */ jsx(
|
|
10963
|
+
Typography,
|
|
10964
|
+
{
|
|
10965
|
+
variant: "caption",
|
|
10966
|
+
color: "tertiary",
|
|
10967
|
+
maxLines: 1,
|
|
10968
|
+
className: "font-sans shrink text-2xs leading-[normal]",
|
|
10969
|
+
testID: "exercise-card-previous-best",
|
|
10970
|
+
children: previousBest
|
|
10971
|
+
}
|
|
10972
|
+
)
|
|
10973
|
+
]
|
|
10974
|
+
}
|
|
10975
|
+
);
|
|
10976
|
+
}
|
|
10977
|
+
function ExerciseHeading(props) {
|
|
10978
|
+
const mode = useSurfaceMode();
|
|
10979
|
+
const nameStyle = props.isLive ? { color: exerciseLiveColor(mode) } : void 0;
|
|
10980
|
+
return /* @__PURE__ */ jsx(reactNative.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 }) });
|
|
10981
|
+
}
|
|
10982
|
+
var DENSITY = {
|
|
10983
|
+
rail: {
|
|
10984
|
+
paddingVertical: 9,
|
|
10985
|
+
paddingHorizontal: 12,
|
|
10986
|
+
layout: "stacked",
|
|
10987
|
+
dimOpacity: 0.55,
|
|
10988
|
+
dimByDefault: false,
|
|
10989
|
+
mutedPrescription: false
|
|
10990
|
+
},
|
|
10991
|
+
compact: {
|
|
10992
|
+
paddingVertical: 12,
|
|
10993
|
+
paddingHorizontal: 14,
|
|
10994
|
+
layout: "inline",
|
|
10995
|
+
dimOpacity: 0.55,
|
|
10996
|
+
dimByDefault: false,
|
|
10997
|
+
mutedPrescription: true
|
|
10998
|
+
},
|
|
10999
|
+
upcoming: {
|
|
11000
|
+
paddingVertical: 12,
|
|
11001
|
+
paddingHorizontal: 14,
|
|
11002
|
+
layout: "inline",
|
|
11003
|
+
dimOpacity: 0.6,
|
|
11004
|
+
dimByDefault: true,
|
|
11005
|
+
mutedPrescription: true
|
|
11006
|
+
}
|
|
11007
|
+
};
|
|
11008
|
+
function useRowInteraction() {
|
|
11009
|
+
const { hovered: rowHovered, hoverProps } = useHoverState();
|
|
11010
|
+
const [headingHovered, setHeadingHovered] = React26.useState(false);
|
|
11011
|
+
const [pressed, setPressed] = React26.useState(false);
|
|
11012
|
+
return {
|
|
11013
|
+
hoverProps,
|
|
11014
|
+
pressed,
|
|
11015
|
+
hovered: rowHovered || headingHovered,
|
|
11016
|
+
headingHandlers: {
|
|
11017
|
+
onHoverIn: () => setHeadingHovered(true),
|
|
11018
|
+
onHoverOut: () => setHeadingHovered(false),
|
|
11019
|
+
onPressIn: () => setPressed(true),
|
|
11020
|
+
onPressOut: () => setPressed(false)
|
|
11021
|
+
}
|
|
11022
|
+
};
|
|
11023
|
+
}
|
|
11024
|
+
function rowWash(mode, state) {
|
|
11025
|
+
if (state.pressed) return exerciseRowStateColor("pressed", mode);
|
|
11026
|
+
if (state.isSelected) return exerciseRowStateColor("selected", mode);
|
|
11027
|
+
if (state.hovered) return exerciseRowStateColor("hovered", mode);
|
|
11028
|
+
return void 0;
|
|
11029
|
+
}
|
|
11030
|
+
function prescriptionProps(p) {
|
|
11031
|
+
const base = { name: p.name };
|
|
11032
|
+
if (p.prescription !== void 0) return { ...base, prescription: p.prescription };
|
|
11033
|
+
if (p.sets === void 0) return base;
|
|
11034
|
+
return { ...base, sets: p.sets, reps: p.reps, load: p.load };
|
|
11035
|
+
}
|
|
11036
|
+
function ExerciseCardHeading(props) {
|
|
11037
|
+
const {
|
|
11038
|
+
density = "rail",
|
|
11039
|
+
setStates = [],
|
|
11040
|
+
stripHeight = 8,
|
|
11041
|
+
dimmed,
|
|
11042
|
+
isSelected = false,
|
|
11043
|
+
isLive = false,
|
|
11044
|
+
testID = "exercise-card",
|
|
11045
|
+
style
|
|
11046
|
+
} = props;
|
|
11047
|
+
const spec = DENSITY[density];
|
|
11048
|
+
const { hoverProps, pressed, hovered, headingHandlers } = useRowInteraction();
|
|
11049
|
+
const wash = rowWash(useSurfaceMode(), { pressed, isSelected, hovered });
|
|
11050
|
+
const rowIsButton = spec.layout === "inline";
|
|
11051
|
+
const Root = rowIsButton ? reactNative.Pressable : reactNative.View;
|
|
11052
|
+
const rootPress = rowIsButton ? {
|
|
11053
|
+
...headingHandlers,
|
|
11054
|
+
onPress: props.onPress,
|
|
11055
|
+
accessibilityRole: "button",
|
|
11056
|
+
accessibilityLabel: exerciseHeadingLabel(props)
|
|
11057
|
+
} : {};
|
|
11058
|
+
return /* @__PURE__ */ jsxs(
|
|
11059
|
+
Root,
|
|
10775
11060
|
{
|
|
10776
|
-
|
|
11061
|
+
...hoverProps,
|
|
11062
|
+
...rootPress,
|
|
11063
|
+
style: [
|
|
11064
|
+
{
|
|
11065
|
+
paddingVertical: spec.paddingVertical,
|
|
11066
|
+
paddingHorizontal: spec.paddingHorizontal,
|
|
11067
|
+
opacity: dimmed ?? spec.dimByDefault ? spec.dimOpacity : 1
|
|
11068
|
+
},
|
|
11069
|
+
wash ? { backgroundColor: wash } : null,
|
|
11070
|
+
style
|
|
11071
|
+
],
|
|
10777
11072
|
testID,
|
|
10778
11073
|
children: [
|
|
10779
|
-
/* @__PURE__ */ jsx(
|
|
11074
|
+
/* @__PURE__ */ jsx(
|
|
11075
|
+
ExerciseHeading,
|
|
11076
|
+
{
|
|
11077
|
+
...prescriptionProps(props),
|
|
11078
|
+
...rowIsButton ? { pressTarget: "ancestor" } : headingHandlers,
|
|
11079
|
+
unit: props.unit,
|
|
11080
|
+
tempo: props.tempo,
|
|
11081
|
+
indicator: props.indicator,
|
|
11082
|
+
previousBest: props.previousBest,
|
|
11083
|
+
onPress: rowIsButton ? void 0 : props.onPress,
|
|
11084
|
+
layout: spec.layout,
|
|
11085
|
+
mutedPrescription: spec.mutedPrescription,
|
|
11086
|
+
isLive
|
|
11087
|
+
}
|
|
11088
|
+
),
|
|
10780
11089
|
setStates.length > 0 && /* @__PURE__ */ jsx(reactNative.View, { style: { marginTop: 7 }, testID: "exercise-card-strip", children: /* @__PURE__ */ jsx(SetStrip, { sets: setStates, height: stripHeight }) })
|
|
10781
11090
|
]
|
|
10782
11091
|
}
|
|
@@ -10870,103 +11179,58 @@ function getSupersetMargin(position) {
|
|
|
10870
11179
|
}
|
|
10871
11180
|
return {};
|
|
10872
11181
|
}
|
|
10873
|
-
function
|
|
10874
|
-
|
|
10875
|
-
return `${summary.sets}\xD7${summary.reps} @ ${roundWeight(summary.weight)} ${summary.unit}`;
|
|
11182
|
+
function supersetChrome(position) {
|
|
11183
|
+
return { ...getSupersetBorderRadius(position), ...getSupersetMargin(position) };
|
|
10876
11184
|
}
|
|
10877
|
-
function
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
11185
|
+
function deriveCollapsedSetStates(setVelocities, totalPlannedSets, plannedReps2) {
|
|
11186
|
+
const done = (setVelocities ?? []).map(
|
|
11187
|
+
(velocities) => ({ status: "done", velocities })
|
|
11188
|
+
);
|
|
11189
|
+
const remaining = Math.max(0, (totalPlannedSets ?? 0) - done.length);
|
|
11190
|
+
return [
|
|
11191
|
+
...done,
|
|
11192
|
+
...Array.from(
|
|
11193
|
+
{ length: remaining },
|
|
11194
|
+
() => ({ status: "todo", planned: plannedReps2 })
|
|
11195
|
+
)
|
|
11196
|
+
];
|
|
10881
11197
|
}
|
|
10882
11198
|
function CollapsedCard({
|
|
10883
11199
|
name,
|
|
10884
11200
|
onToggle,
|
|
10885
11201
|
summary,
|
|
10886
11202
|
isPR,
|
|
11203
|
+
indicator,
|
|
10887
11204
|
setVelocities,
|
|
10888
|
-
|
|
11205
|
+
setStates,
|
|
10889
11206
|
totalPlannedSets,
|
|
10890
|
-
|
|
11207
|
+
stripHeight,
|
|
11208
|
+
supersetPosition,
|
|
11209
|
+
isSelected,
|
|
11210
|
+
isLive
|
|
10891
11211
|
}) {
|
|
10892
|
-
const
|
|
10893
|
-
const
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
11212
|
+
const plannedReps2 = typeof summary?.reps === "number" ? summary.reps : 0;
|
|
11213
|
+
const row = {
|
|
11214
|
+
density: "compact",
|
|
11215
|
+
name,
|
|
11216
|
+
indicator: indicator ?? (isPR ? "pr" : void 0),
|
|
11217
|
+
setStates: setStates ?? deriveCollapsedSetStates(setVelocities, totalPlannedSets, plannedReps2),
|
|
11218
|
+
stripHeight,
|
|
11219
|
+
isSelected,
|
|
11220
|
+
isLive,
|
|
11221
|
+
onPress: onToggle,
|
|
11222
|
+
style: supersetChrome(supersetPosition)
|
|
11223
|
+
};
|
|
11224
|
+
return summary ? /* @__PURE__ */ jsx(
|
|
11225
|
+
ExerciseCardHeading,
|
|
10899
11226
|
{
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
testID: "exercise-card",
|
|
10906
|
-
children: /* @__PURE__ */ jsxs(
|
|
10907
|
-
reactNative.View,
|
|
10908
|
-
{
|
|
10909
|
-
className: pressed ? "bg-surface-raised" : void 0,
|
|
10910
|
-
style: {
|
|
10911
|
-
padding: 12,
|
|
10912
|
-
paddingHorizontal: 14,
|
|
10913
|
-
cursor: "pointer",
|
|
10914
|
-
...borderRadius,
|
|
10915
|
-
...supersetMargin
|
|
10916
|
-
},
|
|
10917
|
-
children: [
|
|
10918
|
-
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", testID: "exercise-card-header", children: [
|
|
10919
|
-
/* @__PURE__ */ jsx(
|
|
10920
|
-
Typography,
|
|
10921
|
-
{
|
|
10922
|
-
variant: "h6",
|
|
10923
|
-
color: "primary",
|
|
10924
|
-
className: "text-sm font-bold leading-[normal]",
|
|
10925
|
-
testID: "exercise-card-name",
|
|
10926
|
-
children: name
|
|
10927
|
-
}
|
|
10928
|
-
),
|
|
10929
|
-
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1" }),
|
|
10930
|
-
summary && /* The demo's "body" face is Inter, which is the library's `font-sans`
|
|
10931
|
-
(the mapping B1 established for PrBadge), not Typography's `font-body`. */
|
|
10932
|
-
/* @__PURE__ */ jsx(
|
|
10933
|
-
Typography,
|
|
10934
|
-
{
|
|
10935
|
-
variant: "caption",
|
|
10936
|
-
color: "secondary",
|
|
10937
|
-
className: "font-sans mr-2 leading-[normal]",
|
|
10938
|
-
testID: "exercise-card-summary",
|
|
10939
|
-
children: formatSummary(summary)
|
|
10940
|
-
}
|
|
10941
|
-
),
|
|
10942
|
-
isPR && /* @__PURE__ */ jsx(reactNative.View, { style: { marginLeft: 4 }, children: /* @__PURE__ */ jsx(PrBadge, { type: "e1rm", compact: true, animate: false }) })
|
|
10943
|
-
] }),
|
|
10944
|
-
(completedSets > 0 || remaining > 0) && /* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row", style: { marginTop: 6, gap: 4 }, testID: "exercise-card-strips", children: [
|
|
10945
|
-
setVelocities?.map((velocities, i) => /* @__PURE__ */ jsx(
|
|
10946
|
-
VelocityStrip,
|
|
10947
|
-
{
|
|
10948
|
-
velocities,
|
|
10949
|
-
zones: velocityZones,
|
|
10950
|
-
variant: "compact",
|
|
10951
|
-
height: 8,
|
|
10952
|
-
hideBaseline: true,
|
|
10953
|
-
testID: `exercise-card-velocity-strip-${i}`
|
|
10954
|
-
},
|
|
10955
|
-
i
|
|
10956
|
-
)),
|
|
10957
|
-
Array.from({ length: remaining }, (_, i) => /* @__PURE__ */ jsx(
|
|
10958
|
-
PlaceholderStrip,
|
|
10959
|
-
{
|
|
10960
|
-
testID: `exercise-card-placeholder-${i}`
|
|
10961
|
-
},
|
|
10962
|
-
`placeholder-${i}`
|
|
10963
|
-
))
|
|
10964
|
-
] })
|
|
10965
|
-
]
|
|
10966
|
-
}
|
|
10967
|
-
)
|
|
11227
|
+
...row,
|
|
11228
|
+
sets: summary.sets,
|
|
11229
|
+
reps: summary.reps,
|
|
11230
|
+
load: summary.weight,
|
|
11231
|
+
unit: summary.unit
|
|
10968
11232
|
}
|
|
10969
|
-
);
|
|
11233
|
+
) : /* @__PURE__ */ jsx(ExerciseCardHeading, { ...row });
|
|
10970
11234
|
}
|
|
10971
11235
|
function deriveHeaderSetStates(sets) {
|
|
10972
11236
|
return sets.map((set) => {
|
|
@@ -10991,10 +11255,9 @@ function ExpandedCard({
|
|
|
10991
11255
|
setStates,
|
|
10992
11256
|
stripHeight = 8,
|
|
10993
11257
|
velocityZones,
|
|
10994
|
-
supersetPosition
|
|
11258
|
+
supersetPosition,
|
|
11259
|
+
isLive
|
|
10995
11260
|
}) {
|
|
10996
|
-
const borderRadius = getSupersetBorderRadius(supersetPosition);
|
|
10997
|
-
const supersetMargin = getSupersetMargin(supersetPosition);
|
|
10998
11261
|
const unit = summary?.unit ?? sets?.[0]?.unit ?? "lbs";
|
|
10999
11262
|
const headerStates = setStates ?? (sets ? deriveHeaderSetStates(sets) : []);
|
|
11000
11263
|
const headerIndicator = indicator ?? (isPR ? "pr" : void 0);
|
|
@@ -11002,11 +11265,7 @@ function ExpandedCard({
|
|
|
11002
11265
|
reactNative.View,
|
|
11003
11266
|
{
|
|
11004
11267
|
className: "bg-surface-elevated border-hairline",
|
|
11005
|
-
style: {
|
|
11006
|
-
borderWidth: 1,
|
|
11007
|
-
...borderRadius,
|
|
11008
|
-
...supersetMargin
|
|
11009
|
-
},
|
|
11268
|
+
style: { borderWidth: 1, ...supersetChrome(supersetPosition) },
|
|
11010
11269
|
testID: "exercise-card",
|
|
11011
11270
|
children: [
|
|
11012
11271
|
/* @__PURE__ */ jsx(
|
|
@@ -11021,6 +11280,7 @@ function ExpandedCard({
|
|
|
11021
11280
|
indicator: headerIndicator,
|
|
11022
11281
|
setStates: headerStates,
|
|
11023
11282
|
stripHeight,
|
|
11283
|
+
isLive,
|
|
11024
11284
|
onPress: onToggle,
|
|
11025
11285
|
testID: "exercise-card-heading"
|
|
11026
11286
|
}
|
|
@@ -11048,62 +11308,21 @@ function UpcomingCard({
|
|
|
11048
11308
|
name,
|
|
11049
11309
|
prescription,
|
|
11050
11310
|
previousBest,
|
|
11311
|
+
indicator,
|
|
11051
11312
|
supersetPosition,
|
|
11313
|
+
isSelected,
|
|
11052
11314
|
onToggle
|
|
11053
11315
|
}) {
|
|
11054
|
-
const
|
|
11055
|
-
|
|
11056
|
-
|
|
11057
|
-
|
|
11058
|
-
|
|
11059
|
-
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
|
|
11064
|
-
...supersetMargin
|
|
11065
|
-
},
|
|
11066
|
-
accessibilityLabel: formatAccessibilityLabel(name, void 0, prescription),
|
|
11067
|
-
testID: "exercise-card",
|
|
11068
|
-
children: /* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", children: [
|
|
11069
|
-
/* @__PURE__ */ jsx(
|
|
11070
|
-
Typography,
|
|
11071
|
-
{
|
|
11072
|
-
variant: "h6",
|
|
11073
|
-
color: "primary",
|
|
11074
|
-
className: "shrink-0 text-sm font-bold leading-[normal]",
|
|
11075
|
-
testID: "exercise-card-name",
|
|
11076
|
-
children: name
|
|
11077
|
-
}
|
|
11078
|
-
),
|
|
11079
|
-
prescription && /* @__PURE__ */ jsx(
|
|
11080
|
-
Typography,
|
|
11081
|
-
{
|
|
11082
|
-
variant: "caption",
|
|
11083
|
-
color: "secondary",
|
|
11084
|
-
maxLines: 1,
|
|
11085
|
-
className: "font-sans shrink ml-2 leading-[normal]",
|
|
11086
|
-
testID: "exercise-card-prescription",
|
|
11087
|
-
children: prescription
|
|
11088
|
-
}
|
|
11089
|
-
),
|
|
11090
|
-
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1", style: { minWidth: 8 } }),
|
|
11091
|
-
previousBest && /* 11px is off the type scale; `2xs` (10px) is the step below, as B2's
|
|
11092
|
-
WorkoutCard date took for the same size. */
|
|
11093
|
-
/* @__PURE__ */ jsx(
|
|
11094
|
-
Typography,
|
|
11095
|
-
{
|
|
11096
|
-
variant: "caption",
|
|
11097
|
-
color: "tertiary",
|
|
11098
|
-
maxLines: 1,
|
|
11099
|
-
className: "font-sans shrink text-2xs leading-[normal]",
|
|
11100
|
-
testID: "exercise-card-previous-best",
|
|
11101
|
-
children: previousBest
|
|
11102
|
-
}
|
|
11103
|
-
)
|
|
11104
|
-
] })
|
|
11105
|
-
}
|
|
11106
|
-
) });
|
|
11316
|
+
const row = {
|
|
11317
|
+
density: "upcoming",
|
|
11318
|
+
name,
|
|
11319
|
+
previousBest,
|
|
11320
|
+
indicator,
|
|
11321
|
+
isSelected,
|
|
11322
|
+
onPress: onToggle,
|
|
11323
|
+
style: supersetChrome(supersetPosition)
|
|
11324
|
+
};
|
|
11325
|
+
return prescription !== void 0 ? /* @__PURE__ */ jsx(ExerciseCardHeading, { ...row, prescription }) : /* @__PURE__ */ jsx(ExerciseCardHeading, { ...row });
|
|
11107
11326
|
}
|
|
11108
11327
|
function ExerciseCard({
|
|
11109
11328
|
upcoming,
|
|
@@ -11711,7 +11930,7 @@ var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY3, BRAND_PRIMARY_LIGHT];
|
|
|
11711
11930
|
function heatmapColor(percentage) {
|
|
11712
11931
|
const clamped = Math.max(0, Math.min(100, percentage));
|
|
11713
11932
|
const opacity = 0.12 + clamped / 100 * 0.78;
|
|
11714
|
-
return
|
|
11933
|
+
return alpha(BRAND_PRIMARY3, opacity);
|
|
11715
11934
|
}
|
|
11716
11935
|
function MesoCard({
|
|
11717
11936
|
name,
|
|
@@ -12054,12 +12273,13 @@ function PrHistoryModal({
|
|
|
12054
12273
|
}
|
|
12055
12274
|
);
|
|
12056
12275
|
}
|
|
12057
|
-
var
|
|
12058
|
-
var BRAND_PRIMARY5 =
|
|
12059
|
-
var
|
|
12060
|
-
var
|
|
12061
|
-
var
|
|
12062
|
-
var
|
|
12276
|
+
var t7 = getSemanticColors("dark");
|
|
12277
|
+
var BRAND_PRIMARY5 = t7["brand-primary"];
|
|
12278
|
+
var ON_BRAND_PRIMARY2 = t7["on-brand-primary"];
|
|
12279
|
+
var BRAND_PRIMARY_SUBTLE = alpha(BRAND_PRIMARY5, 0.12);
|
|
12280
|
+
var STATUS_SUCCESS2 = t7["status-success"];
|
|
12281
|
+
var STATUS_WARNING2 = t7["status-warning"];
|
|
12282
|
+
var STATUS_ERROR2 = t7["status-error"];
|
|
12063
12283
|
var EMOJI_SETS = {
|
|
12064
12284
|
sleep: ["\u{1F634}", "\u{1F610}", "\u{1F642}", "\u{1F60A}", "\u{1F929}"],
|
|
12065
12285
|
soreness: ["\u{1F635}", "\u{1F623}", "\u{1F610}", "\u{1F642}", "\u{1F4AA}"],
|
|
@@ -12256,7 +12476,7 @@ function ReadinessCheck({
|
|
|
12256
12476
|
fontSize: 13,
|
|
12257
12477
|
fontWeight: "700",
|
|
12258
12478
|
fontFamily: "Inter, sans-serif",
|
|
12259
|
-
color:
|
|
12479
|
+
color: ON_BRAND_PRIMARY2
|
|
12260
12480
|
},
|
|
12261
12481
|
children: "Start Workout"
|
|
12262
12482
|
}
|
|
@@ -12265,20 +12485,20 @@ function ReadinessCheck({
|
|
|
12265
12485
|
)
|
|
12266
12486
|
] }) });
|
|
12267
12487
|
}
|
|
12268
|
-
var
|
|
12269
|
-
var BRAND_PRIMARY6 =
|
|
12488
|
+
var t8 = getSemanticColors("dark");
|
|
12489
|
+
var BRAND_PRIMARY6 = t8["brand-primary"];
|
|
12270
12490
|
var BRAND_PRIMARY_DARK2 = MESO_ACCENT_GRADIENT_DARK;
|
|
12271
12491
|
var BRAND_PRIMARY_LIGHT2 = MESO_ACCENT_GRADIENT_LIGHT;
|
|
12272
|
-
var SUCCESS =
|
|
12273
|
-
var WARNING =
|
|
12274
|
-
var ERROR =
|
|
12492
|
+
var SUCCESS = t8["status-success"];
|
|
12493
|
+
var WARNING = t8["status-warning"];
|
|
12494
|
+
var ERROR = t8["status-error"];
|
|
12275
12495
|
var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2, BRAND_PRIMARY6, BRAND_PRIMARY_LIGHT2];
|
|
12276
12496
|
var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
|
|
12277
|
-
var GAUGE_GRADIENT =
|
|
12497
|
+
var GAUGE_GRADIENT = `linear-gradient(90deg, ${alpha(SUCCESS, 0.25)} 0%, ${alpha(WARNING, 0.25)} 50%, ${alpha(ERROR, 0.25)} 100%)`;
|
|
12278
12498
|
var STATUS_VARIANTS = {
|
|
12279
|
-
success: { bg:
|
|
12280
|
-
warning: { bg:
|
|
12281
|
-
error: { bg:
|
|
12499
|
+
success: { bg: alpha(SUCCESS, 0.15), border: alpha(SUCCESS, 0.3), text: SUCCESS },
|
|
12500
|
+
warning: { bg: alpha(WARNING, 0.15), border: alpha(WARNING, 0.3), text: WARNING },
|
|
12501
|
+
error: { bg: alpha(ERROR, 0.15), border: alpha(ERROR, 0.25), text: ERROR }
|
|
12282
12502
|
};
|
|
12283
12503
|
function clamp01(value) {
|
|
12284
12504
|
if (!Number.isFinite(value)) return 0;
|
|
@@ -12431,7 +12651,7 @@ function Gauge({ gauge }) {
|
|
|
12431
12651
|
bottom: 0,
|
|
12432
12652
|
width: 1,
|
|
12433
12653
|
marginLeft: -0.5,
|
|
12434
|
-
backgroundColor:
|
|
12654
|
+
backgroundColor: alpha(primitiveColors.white, 0.3)
|
|
12435
12655
|
},
|
|
12436
12656
|
testID: "meso-status-card-gauge-center"
|
|
12437
12657
|
}
|
|
@@ -12540,9 +12760,9 @@ function MesoStatusCard({
|
|
|
12540
12760
|
reactNative.View,
|
|
12541
12761
|
{
|
|
12542
12762
|
style: {
|
|
12543
|
-
backgroundColor:
|
|
12763
|
+
backgroundColor: alpha(WARNING, 0.06),
|
|
12544
12764
|
borderWidth: 1,
|
|
12545
|
-
borderColor:
|
|
12765
|
+
borderColor: alpha(WARNING, 0.15),
|
|
12546
12766
|
borderRadius: 8,
|
|
12547
12767
|
paddingVertical: 10,
|
|
12548
12768
|
paddingHorizontal: 12
|
|
@@ -12568,9 +12788,9 @@ function MesoStatusCard({
|
|
|
12568
12788
|
className: "flex-row items-center",
|
|
12569
12789
|
style: {
|
|
12570
12790
|
gap: 8,
|
|
12571
|
-
backgroundColor:
|
|
12791
|
+
backgroundColor: alpha(SUCCESS, 0.06),
|
|
12572
12792
|
borderWidth: 1,
|
|
12573
|
-
borderColor:
|
|
12793
|
+
borderColor: alpha(SUCCESS, 0.2),
|
|
12574
12794
|
borderRadius: 8,
|
|
12575
12795
|
paddingVertical: 10,
|
|
12576
12796
|
paddingHorizontal: 12
|
|
@@ -12605,16 +12825,16 @@ var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
|
|
|
12605
12825
|
var STATUS_SUCCESS3 = sem["status-success"];
|
|
12606
12826
|
var STATUS_ERROR3 = sem["status-error"];
|
|
12607
12827
|
var STATUS_WARNING3 = sem["status-warning"];
|
|
12608
|
-
var GRID_LINE =
|
|
12609
|
-
var SUCCESS_PILL_BG =
|
|
12610
|
-
var SUCCESS_PILL_BORDER =
|
|
12611
|
-
var ERROR_PILL_BG =
|
|
12612
|
-
var ERROR_PILL_BORDER =
|
|
12828
|
+
var GRID_LINE = alpha(primitiveColors.white, 0.06);
|
|
12829
|
+
var SUCCESS_PILL_BG = alpha(STATUS_SUCCESS3, 0.1);
|
|
12830
|
+
var SUCCESS_PILL_BORDER = alpha(STATUS_SUCCESS3, 0.2);
|
|
12831
|
+
var ERROR_PILL_BG = alpha(STATUS_ERROR3, 0.1);
|
|
12832
|
+
var ERROR_PILL_BORDER = alpha(STATUS_ERROR3, 0.2);
|
|
12613
12833
|
var PLOT_LEFT = 26;
|
|
12614
12834
|
var TOOLTIP_WIDTH = 124;
|
|
12615
12835
|
function timeOf(dateStr) {
|
|
12616
|
-
const
|
|
12617
|
-
return Number.isNaN(
|
|
12836
|
+
const t19 = Date.parse(dateStr);
|
|
12837
|
+
return Number.isNaN(t19) ? 0 : t19;
|
|
12618
12838
|
}
|
|
12619
12839
|
function formatValue(value) {
|
|
12620
12840
|
return `${Math.round(value)}`;
|
|
@@ -12854,7 +13074,7 @@ function StrengthTrendChart({
|
|
|
12854
13074
|
height,
|
|
12855
13075
|
borderLeftWidth: 1,
|
|
12856
13076
|
borderStyle: "dashed",
|
|
12857
|
-
borderLeftColor:
|
|
13077
|
+
borderLeftColor: alpha(primitiveColors.white, 0.1)
|
|
12858
13078
|
}
|
|
12859
13079
|
},
|
|
12860
13080
|
`boundary-${i}`
|
|
@@ -13122,14 +13342,14 @@ function StrengthTrendChart({
|
|
|
13122
13342
|
)
|
|
13123
13343
|
] });
|
|
13124
13344
|
}
|
|
13125
|
-
var
|
|
13126
|
-
var STATUS_SUCCESS4 =
|
|
13127
|
-
var STATUS_WARNING4 =
|
|
13128
|
-
var STATUS_INFO =
|
|
13345
|
+
var t9 = getSemanticColors("dark");
|
|
13346
|
+
var STATUS_SUCCESS4 = t9["status-success"];
|
|
13347
|
+
var STATUS_WARNING4 = t9["status-warning"];
|
|
13348
|
+
var STATUS_INFO = t9["status-info"];
|
|
13129
13349
|
var DOT_BORDER = "#F3F4F6";
|
|
13130
|
-
var BAND_FILL =
|
|
13131
|
-
var BAND_EDGE =
|
|
13132
|
-
var PROJECTION_FILL =
|
|
13350
|
+
var BAND_FILL = alpha(STATUS_SUCCESS4, 0.1);
|
|
13351
|
+
var BAND_EDGE = alpha(STATUS_SUCCESS4, 0.45);
|
|
13352
|
+
var PROJECTION_FILL = alpha(STATUS_SUCCESS4, 0.05);
|
|
13133
13353
|
var PADDING_LEFT = 28;
|
|
13134
13354
|
var PADDING_RIGHT = 10;
|
|
13135
13355
|
var PADDING_TOP = 8;
|
|
@@ -13168,8 +13388,8 @@ function interpEdge(pixels, x, key) {
|
|
|
13168
13388
|
const a = pixels[i];
|
|
13169
13389
|
const b = pixels[i + 1];
|
|
13170
13390
|
if (x >= a.x && x <= b.x) {
|
|
13171
|
-
const
|
|
13172
|
-
return a[key] +
|
|
13391
|
+
const t19 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
|
|
13392
|
+
return a[key] + t19 * (b[key] - a[key]);
|
|
13173
13393
|
}
|
|
13174
13394
|
}
|
|
13175
13395
|
return pixels[pixels.length - 1][key];
|
|
@@ -13534,10 +13754,10 @@ function CapacityBandChart({
|
|
|
13534
13754
|
}
|
|
13535
13755
|
);
|
|
13536
13756
|
}
|
|
13537
|
-
var
|
|
13757
|
+
var t10 = getSemanticColors("dark");
|
|
13538
13758
|
var DEFAULT_TRACK_COLOR = greyRamp[800];
|
|
13539
13759
|
var DEFAULT_MARKER_COLOR2 = primitiveColors.white;
|
|
13540
|
-
var TICK_COLOR =
|
|
13760
|
+
var TICK_COLOR = t10["text-tertiary"];
|
|
13541
13761
|
var ZONE_SIZES = {
|
|
13542
13762
|
default: {
|
|
13543
13763
|
trackHeight: 14,
|
|
@@ -13720,7 +13940,7 @@ function ZoneTrack({
|
|
|
13720
13940
|
),
|
|
13721
13941
|
ticks?.map((tick, i) => {
|
|
13722
13942
|
const emphasized = tick.emphasized === true;
|
|
13723
|
-
const lineColor = tick.color ?? (emphasized ?
|
|
13943
|
+
const lineColor = tick.color ?? (emphasized ? t10["brand-primary"] : TICK_COLOR);
|
|
13724
13944
|
const lineWidth = emphasized ? s.tickLineEmphasized : s.tickLineNormal;
|
|
13725
13945
|
return /* @__PURE__ */ jsx(
|
|
13726
13946
|
reactNative.View,
|
|
@@ -13751,7 +13971,7 @@ function ZoneTrack({
|
|
|
13751
13971
|
if (tick.label == null) return null;
|
|
13752
13972
|
const emphasized = tick.emphasized === true;
|
|
13753
13973
|
if (!showTickLabel(i, emphasized)) return null;
|
|
13754
|
-
const labelColor = tick.color ?? (emphasized ?
|
|
13974
|
+
const labelColor = tick.color ?? (emphasized ? t10["brand-primary"] : TICK_COLOR);
|
|
13755
13975
|
const labelNode = /* @__PURE__ */ jsx(
|
|
13756
13976
|
reactNative.Text,
|
|
13757
13977
|
{
|
|
@@ -13983,7 +14203,7 @@ function StatusPill2({ status, label, className, ...props }) {
|
|
|
13983
14203
|
}
|
|
13984
14204
|
);
|
|
13985
14205
|
}
|
|
13986
|
-
var
|
|
14206
|
+
var t11 = getSemanticColors("dark");
|
|
13987
14207
|
var categoryToken = {
|
|
13988
14208
|
productive: null,
|
|
13989
14209
|
threshold: "status-warning",
|
|
@@ -13996,7 +14216,7 @@ var floodOpacity = {
|
|
|
13996
14216
|
};
|
|
13997
14217
|
function liveAuraColor(category) {
|
|
13998
14218
|
const token = categoryToken[category];
|
|
13999
|
-
return token ?
|
|
14219
|
+
return token ? t11[token] : null;
|
|
14000
14220
|
}
|
|
14001
14221
|
function LiveAuraFrame({
|
|
14002
14222
|
category,
|
|
@@ -14025,9 +14245,9 @@ function LiveAuraFrame({
|
|
|
14025
14245
|
position: "relative",
|
|
14026
14246
|
overflow: "hidden",
|
|
14027
14247
|
borderRadius: 10,
|
|
14028
|
-
backgroundColor:
|
|
14248
|
+
backgroundColor: t11["background-base"],
|
|
14029
14249
|
borderWidth: 1,
|
|
14030
|
-
borderColor:
|
|
14250
|
+
borderColor: t11["hairline-default"]
|
|
14031
14251
|
},
|
|
14032
14252
|
style
|
|
14033
14253
|
],
|
|
@@ -14134,14 +14354,14 @@ function panelBodySplit(bodyHeight, layout) {
|
|
|
14134
14354
|
}
|
|
14135
14355
|
|
|
14136
14356
|
// src/components/custom/Fatigue/fatigue-tokens.ts
|
|
14137
|
-
var
|
|
14357
|
+
var t12 = getSemanticColors("dark");
|
|
14138
14358
|
var FONT_HEAD = '"Space Grotesk", sans-serif';
|
|
14139
14359
|
var FONT_UI = '"Nunito Sans", sans-serif';
|
|
14140
14360
|
var FONT_MONO = "monospace";
|
|
14141
14361
|
var TONE_COLOR = {
|
|
14142
|
-
ok:
|
|
14143
|
-
warn:
|
|
14144
|
-
alarm:
|
|
14362
|
+
ok: t12["status-success"],
|
|
14363
|
+
warn: t12["status-warning"],
|
|
14364
|
+
alarm: t12["status-error"]
|
|
14145
14365
|
};
|
|
14146
14366
|
var STATE_LABEL = {
|
|
14147
14367
|
good: "Good",
|
|
@@ -14200,13 +14420,13 @@ function auraForVerdict(state) {
|
|
|
14200
14420
|
}
|
|
14201
14421
|
|
|
14202
14422
|
// src/components/custom/Fatigue/VerdictHero.tsx
|
|
14203
|
-
var
|
|
14423
|
+
var t13 = getSemanticColors("dark");
|
|
14204
14424
|
function formatRpe(rpe) {
|
|
14205
14425
|
if (rpe == null) return "\u2014";
|
|
14206
14426
|
return (Math.round(rpe * 2) / 2).toFixed(1);
|
|
14207
14427
|
}
|
|
14208
14428
|
function VerdictHero({ rpe, verdict }) {
|
|
14209
|
-
const tone = verdict ? TONE_COLOR[verdict.tone] :
|
|
14429
|
+
const tone = verdict ? TONE_COLOR[verdict.tone] : t13["text-tertiary"];
|
|
14210
14430
|
const word = verdict ? STATE_LABEL[verdict.state] : "Warming up";
|
|
14211
14431
|
return /* @__PURE__ */ jsxs(reactNative.View, { style: { gap: 6 }, testID: "verdict-hero", children: [
|
|
14212
14432
|
/* @__PURE__ */ jsx(
|
|
@@ -14216,7 +14436,7 @@ function VerdictHero({ rpe, verdict }) {
|
|
|
14216
14436
|
fontSize: 9,
|
|
14217
14437
|
letterSpacing: 1.5,
|
|
14218
14438
|
fontFamily: FONT_MONO,
|
|
14219
|
-
color:
|
|
14439
|
+
color: t13["text-tertiary"]
|
|
14220
14440
|
},
|
|
14221
14441
|
children: "FATIGUE"
|
|
14222
14442
|
}
|
|
@@ -14255,7 +14475,7 @@ function VerdictHero({ rpe, verdict }) {
|
|
|
14255
14475
|
] })
|
|
14256
14476
|
] });
|
|
14257
14477
|
}
|
|
14258
|
-
var
|
|
14478
|
+
var t14 = getSemanticColors("dark");
|
|
14259
14479
|
var TONE_VARIANT = {
|
|
14260
14480
|
ok: "success",
|
|
14261
14481
|
warn: "warning",
|
|
@@ -14283,7 +14503,7 @@ function Light({
|
|
|
14283
14503
|
fontSize: 9,
|
|
14284
14504
|
letterSpacing: 0.6,
|
|
14285
14505
|
fontFamily: FONT_MONO,
|
|
14286
|
-
color:
|
|
14506
|
+
color: t14["text-secondary"]
|
|
14287
14507
|
},
|
|
14288
14508
|
children: label
|
|
14289
14509
|
}
|
|
@@ -14392,14 +14612,14 @@ function RomProgressionChart({
|
|
|
14392
14612
|
}
|
|
14393
14613
|
|
|
14394
14614
|
// src/components/custom/Fatigue/tempo-pacing.ts
|
|
14395
|
-
var
|
|
14615
|
+
var t15 = getSemanticColors("dark");
|
|
14396
14616
|
var ON_TARGET_MS2 = 100;
|
|
14397
14617
|
function phaseFillFraction(elapsedMs, targetMs) {
|
|
14398
14618
|
if (targetMs == null || targetMs <= 0) return 1;
|
|
14399
14619
|
return Math.min(1, Math.max(0, elapsedMs / targetMs));
|
|
14400
14620
|
}
|
|
14401
14621
|
function pacingTone(elapsedMs, targetMs) {
|
|
14402
|
-
if (targetMs == null || targetMs <= 0) return
|
|
14622
|
+
if (targetMs == null || targetMs <= 0) return t15["text-primary"];
|
|
14403
14623
|
const remainingMs = targetMs - elapsedMs;
|
|
14404
14624
|
if (remainingMs > ON_TARGET_MS2) return PACING_TONE.ahead;
|
|
14405
14625
|
if (remainingMs >= -ON_TARGET_MS2) return PACING_TONE.onPace;
|
|
@@ -14415,11 +14635,11 @@ function prescribedSegments(tempo) {
|
|
|
14415
14635
|
["hold", pauseTop]
|
|
14416
14636
|
];
|
|
14417
14637
|
const out = [];
|
|
14418
|
-
let
|
|
14638
|
+
let t19 = 0;
|
|
14419
14639
|
for (const [phase, seconds] of order) {
|
|
14420
14640
|
const ms = seconds * 1e3;
|
|
14421
|
-
if (ms > 0) out.push({ phase, startMs:
|
|
14422
|
-
|
|
14641
|
+
if (ms > 0) out.push({ phase, startMs: t19, endMs: t19 + ms });
|
|
14642
|
+
t19 += ms;
|
|
14423
14643
|
}
|
|
14424
14644
|
return out;
|
|
14425
14645
|
}
|
|
@@ -14443,7 +14663,7 @@ function phaseTargetsMs(phases, tempo) {
|
|
|
14443
14663
|
}
|
|
14444
14664
|
|
|
14445
14665
|
// src/components/custom/Fatigue/GhostBand.tsx
|
|
14446
|
-
var
|
|
14666
|
+
var t16 = getSemanticColors("dark");
|
|
14447
14667
|
var BAND_H = 16;
|
|
14448
14668
|
var BAND_GAP = 4;
|
|
14449
14669
|
var PHASE_LABEL = {
|
|
@@ -14463,7 +14683,7 @@ function GhostBand({
|
|
|
14463
14683
|
top,
|
|
14464
14684
|
height = BAND_H,
|
|
14465
14685
|
showLabels = false,
|
|
14466
|
-
labelColor =
|
|
14686
|
+
labelColor = t16["text-primary"],
|
|
14467
14687
|
targetTempoSeconds = null,
|
|
14468
14688
|
prescribed = false
|
|
14469
14689
|
}) {
|
|
@@ -14578,8 +14798,8 @@ function GhostBand({
|
|
|
14578
14798
|
] })
|
|
14579
14799
|
] });
|
|
14580
14800
|
}
|
|
14581
|
-
var
|
|
14582
|
-
var PARCH =
|
|
14801
|
+
var t17 = getSemanticColors("dark");
|
|
14802
|
+
var PARCH = t17["text-primary"];
|
|
14583
14803
|
function smoothPath(pts) {
|
|
14584
14804
|
if (pts.length < 2) return pts.length ? `M ${pts[0][0]} ${pts[0][1]}` : "";
|
|
14585
14805
|
let d = `M ${pts[0][0].toFixed(1)} ${pts[0][1].toFixed(1)}`;
|
|
@@ -14725,7 +14945,7 @@ function GhostSpark({
|
|
|
14725
14945
|
var PAD = 18;
|
|
14726
14946
|
var GHOST_GUTTER = 4;
|
|
14727
14947
|
function LiveFatigueCard({ model, width = 318, height }) {
|
|
14728
|
-
const
|
|
14948
|
+
const t19 = getSemanticColors(useSurfaceMode());
|
|
14729
14949
|
const chartW = width - PAD * 2 - GHOST_GUTTER * 2;
|
|
14730
14950
|
const chartH = cardChartHeight(height);
|
|
14731
14951
|
return /* @__PURE__ */ jsxs(
|
|
@@ -14739,8 +14959,8 @@ function LiveFatigueCard({ model, width = 318, height }) {
|
|
|
14739
14959
|
borderRadius: 14,
|
|
14740
14960
|
padding: PAD,
|
|
14741
14961
|
borderWidth: 1,
|
|
14742
|
-
borderColor:
|
|
14743
|
-
...barPaper(
|
|
14962
|
+
borderColor: t19["hairline-default"],
|
|
14963
|
+
...barPaper(t19["surface-base"])
|
|
14744
14964
|
},
|
|
14745
14965
|
children: [
|
|
14746
14966
|
/* @__PURE__ */ jsxs(reactNative.View, { style: { gap: 12 }, children: [
|
|
@@ -14843,7 +15063,7 @@ function LiveFatiguePanel({
|
|
|
14843
15063
|
}
|
|
14844
15064
|
);
|
|
14845
15065
|
}
|
|
14846
|
-
var
|
|
15066
|
+
var t18 = getSemanticColors("dark");
|
|
14847
15067
|
function phaseAt(segments, ms) {
|
|
14848
15068
|
const hit = segments.find((s) => ms >= s.startMs && ms < s.endMs);
|
|
14849
15069
|
return hit ? hit.phase : null;
|
|
@@ -14908,7 +15128,7 @@ function DualGhostSpark({
|
|
|
14908
15128
|
cur,
|
|
14909
15129
|
current: cur ? toPts(cur) : [],
|
|
14910
15130
|
ghosts: curves.slice(0, -1).map(toPts),
|
|
14911
|
-
tint: cur ? ghostLineColor(cur.tempoDeviation, cur.grindSignature) :
|
|
15131
|
+
tint: cur ? ghostLineColor(cur.tempoDeviation, cur.grindSignature) : t18["text-tertiary"]
|
|
14912
15132
|
};
|
|
14913
15133
|
};
|
|
14914
15134
|
const up = wing(left);
|
|
@@ -14942,7 +15162,7 @@ function DualGhostSpark({
|
|
|
14942
15162
|
x,
|
|
14943
15163
|
top: bandTop,
|
|
14944
15164
|
showLabels: true,
|
|
14945
|
-
labelColor: alpha(
|
|
15165
|
+
labelColor: alpha(t18["text-primary"], 0.92),
|
|
14946
15166
|
targetTempoSeconds
|
|
14947
15167
|
}
|
|
14948
15168
|
),
|
|
@@ -14956,7 +15176,7 @@ function DualGhostSpark({
|
|
|
14956
15176
|
fontWeight: 800,
|
|
14957
15177
|
letterSpacing: 1,
|
|
14958
15178
|
fontFamily: FONT_UI,
|
|
14959
|
-
fill:
|
|
15179
|
+
fill: t18["text-tertiary"],
|
|
14960
15180
|
children: leftLabel
|
|
14961
15181
|
}
|
|
14962
15182
|
),
|
|
@@ -14969,7 +15189,7 @@ function DualGhostSpark({
|
|
|
14969
15189
|
fontWeight: 800,
|
|
14970
15190
|
letterSpacing: 1,
|
|
14971
15191
|
fontFamily: FONT_UI,
|
|
14972
|
-
fill:
|
|
15192
|
+
fill: t18["text-tertiary"],
|
|
14973
15193
|
children: rightLabel
|
|
14974
15194
|
}
|
|
14975
15195
|
)
|
|
@@ -15060,6 +15280,7 @@ function Treemap({
|
|
|
15060
15280
|
{
|
|
15061
15281
|
id: "__more__",
|
|
15062
15282
|
value: restValue,
|
|
15283
|
+
// VW-82: no token at this value (nearest surface-overlay #373635); proposed, not swapped.
|
|
15063
15284
|
color: "#3a3a3a",
|
|
15064
15285
|
label: `+${clean.length - (maxTiles - 1)} more`
|
|
15065
15286
|
}
|
|
@@ -15087,20 +15308,21 @@ function Treemap({
|
|
|
15087
15308
|
borderRadius: 3,
|
|
15088
15309
|
opacity: selected ? 1 : 0.9,
|
|
15089
15310
|
borderWidth: selected ? 2 : 0,
|
|
15090
|
-
borderColor:
|
|
15311
|
+
borderColor: primitiveColors.white,
|
|
15091
15312
|
padding: 4,
|
|
15092
15313
|
overflow: "hidden"
|
|
15093
15314
|
},
|
|
15094
|
-
children: labelFits2 &&
|
|
15315
|
+
children: labelFits2 && // VW-82: label on a data-coloured tile; no on-data token exists yet.
|
|
15316
|
+
/* @__PURE__ */ jsx(reactNative.Text, { numberOfLines: 2, className: "text-[10px] font-semibold text-[#0b0b0b]", children: r.datum.label ?? r.datum.id })
|
|
15095
15317
|
},
|
|
15096
15318
|
r.datum.id
|
|
15097
15319
|
);
|
|
15098
15320
|
}) });
|
|
15099
15321
|
}
|
|
15100
15322
|
var PALETTE2 = DATAVIZ_CATEGORICAL_PALETTE;
|
|
15101
|
-
var GRID_LINE2 =
|
|
15102
|
-
var AXIS_LINE =
|
|
15103
|
-
var DIAGONAL_LINE =
|
|
15323
|
+
var GRID_LINE2 = alpha(primitiveColors.white, 0.07);
|
|
15324
|
+
var AXIS_LINE = alpha(primitiveColors.white, 0.18);
|
|
15325
|
+
var DIAGONAL_LINE = alpha(primitiveColors.white, 0.28);
|
|
15104
15326
|
var DEFAULT_R = 6;
|
|
15105
15327
|
var PLOT_LEFT2 = 40;
|
|
15106
15328
|
var PLOT_RIGHT = 12;
|
|
@@ -15195,8 +15417,8 @@ function Scatter({
|
|
|
15195
15417
|
testID: "scatter-canvas",
|
|
15196
15418
|
style: { position: "absolute", top: 0, left: 0, width, height, overflow: "hidden" },
|
|
15197
15419
|
children: [
|
|
15198
|
-
ticksOf(yd, TICK_COUNT).map((
|
|
15199
|
-
const y = toY(
|
|
15420
|
+
ticksOf(yd, TICK_COUNT).map((t19, i) => {
|
|
15421
|
+
const y = toY(t19);
|
|
15200
15422
|
return /* @__PURE__ */ jsx(
|
|
15201
15423
|
reactNative.View,
|
|
15202
15424
|
{
|
|
@@ -15221,15 +15443,15 @@ function Scatter({
|
|
|
15221
15443
|
width: PLOT_LEFT2 - 6,
|
|
15222
15444
|
textAlign: "right"
|
|
15223
15445
|
},
|
|
15224
|
-
children: formatTick(
|
|
15446
|
+
children: formatTick(t19)
|
|
15225
15447
|
}
|
|
15226
15448
|
)
|
|
15227
15449
|
},
|
|
15228
15450
|
`y-${i}`
|
|
15229
15451
|
);
|
|
15230
15452
|
}),
|
|
15231
|
-
ticksOf(xd, TICK_COUNT).map((
|
|
15232
|
-
const x = toX(
|
|
15453
|
+
ticksOf(xd, TICK_COUNT).map((t19, i) => {
|
|
15454
|
+
const x = toX(t19);
|
|
15233
15455
|
return /* @__PURE__ */ jsx(
|
|
15234
15456
|
reactNative.View,
|
|
15235
15457
|
{
|
|
@@ -15254,7 +15476,7 @@ function Scatter({
|
|
|
15254
15476
|
width: 32,
|
|
15255
15477
|
textAlign: "center"
|
|
15256
15478
|
},
|
|
15257
|
-
children: formatTick(
|
|
15479
|
+
children: formatTick(t19)
|
|
15258
15480
|
}
|
|
15259
15481
|
)
|
|
15260
15482
|
},
|
|
@@ -15360,7 +15582,7 @@ function Scatter({
|
|
|
15360
15582
|
backgroundColor: p.color,
|
|
15361
15583
|
opacity: selected ? 1 : 0.82,
|
|
15362
15584
|
borderWidth: selected ? 2 : 0,
|
|
15363
|
-
borderColor:
|
|
15585
|
+
borderColor: primitiveColors.white
|
|
15364
15586
|
},
|
|
15365
15587
|
children: showLabel && /* @__PURE__ */ jsx(
|
|
15366
15588
|
reactNative.Text,
|
|
@@ -15388,7 +15610,7 @@ var sem2 = getSemanticColors("dark");
|
|
|
15388
15610
|
var STATUS_SUCCESS5 = sem2["status-success"];
|
|
15389
15611
|
var STATUS_WARNING5 = sem2["status-warning"];
|
|
15390
15612
|
var STATUS_ERROR4 = sem2["status-error"];
|
|
15391
|
-
var TRACK =
|
|
15613
|
+
var TRACK = alpha(primitiveColors.white, 0.08);
|
|
15392
15614
|
var DEFAULT_THRESHOLDS2 = [
|
|
15393
15615
|
{ value: 0, color: STATUS_ERROR4 },
|
|
15394
15616
|
{ value: 60, color: STATUS_WARNING5 },
|
|
@@ -15459,23 +15681,23 @@ function Gauge2({
|
|
|
15459
15681
|
testID: "gauge",
|
|
15460
15682
|
...props,
|
|
15461
15683
|
children: [
|
|
15462
|
-
ticks.map((
|
|
15684
|
+
ticks.map((t19) => /* @__PURE__ */ jsx(
|
|
15463
15685
|
reactNative.View,
|
|
15464
15686
|
{
|
|
15465
15687
|
accessibilityElementsHidden: true,
|
|
15466
15688
|
testID: "gauge-segment",
|
|
15467
15689
|
style: {
|
|
15468
15690
|
position: "absolute",
|
|
15469
|
-
left:
|
|
15470
|
-
top:
|
|
15691
|
+
left: t19.left - tickThickness / 2,
|
|
15692
|
+
top: t19.top - tickLength / 2,
|
|
15471
15693
|
width: tickThickness,
|
|
15472
15694
|
height: tickLength,
|
|
15473
15695
|
borderRadius: tickThickness / 2,
|
|
15474
|
-
backgroundColor:
|
|
15475
|
-
transform: [{ rotate:
|
|
15696
|
+
backgroundColor: t19.color,
|
|
15697
|
+
transform: [{ rotate: t19.rotate }]
|
|
15476
15698
|
}
|
|
15477
15699
|
},
|
|
15478
|
-
|
|
15700
|
+
t19.key
|
|
15479
15701
|
)),
|
|
15480
15702
|
/* @__PURE__ */ jsxs(
|
|
15481
15703
|
reactNative.View,
|
|
@@ -16124,7 +16346,7 @@ var TASK_COMPARATORS = {
|
|
|
16124
16346
|
function SeverityLegend({ tasks }) {
|
|
16125
16347
|
const counts = React26.useMemo(() => {
|
|
16126
16348
|
const c2 = { critical: 0, high: 0, medium: 0, low: 0 };
|
|
16127
|
-
for (const
|
|
16349
|
+
for (const t19 of tasks) if (t19.severity) c2[t19.severity]++;
|
|
16128
16350
|
return c2;
|
|
16129
16351
|
}, [tasks]);
|
|
16130
16352
|
return /* @__PURE__ */ jsx(reactNative.View, { className: "flex-row items-center gap-3", children: SEVERITY_ORDER.map((severity) => /* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center gap-1.5", children: [
|
|
@@ -16546,7 +16768,7 @@ function SessionDetail({
|
|
|
16546
16768
|
}) {
|
|
16547
16769
|
const refs = React26.useMemo(() => extractTaskRefs(session.body), [session.body]);
|
|
16548
16770
|
const touched = React26.useMemo(
|
|
16549
|
-
() => refs.map((id) => tasks.find((
|
|
16771
|
+
() => refs.map((id) => tasks.find((t19) => t19.id === id)).filter((t19) => !!t19),
|
|
16550
16772
|
[refs, tasks]
|
|
16551
16773
|
);
|
|
16552
16774
|
const body = React26.useMemo(() => stripLeadingHeading(session.body), [session.body]);
|
|
@@ -16630,7 +16852,7 @@ function StepButton({
|
|
|
16630
16852
|
Typography,
|
|
16631
16853
|
{
|
|
16632
16854
|
variant: "body2",
|
|
16633
|
-
className: cn("leading-none", disabled ? "text-text-
|
|
16855
|
+
className: cn("leading-none", disabled ? "text-text-disabled" : "text-text-secondary"),
|
|
16634
16856
|
children: glyph
|
|
16635
16857
|
}
|
|
16636
16858
|
)
|
|
@@ -17600,6 +17822,9 @@ exports.defaultPreset = defaultPreset;
|
|
|
17600
17822
|
exports.discreteRainbow = discreteRainbow;
|
|
17601
17823
|
exports.divergingScale = divergingScale;
|
|
17602
17824
|
exports.elevationPlane = elevationPlane;
|
|
17825
|
+
exports.exerciseHeadingLabel = exerciseHeadingLabel;
|
|
17826
|
+
exports.exerciseLiveColor = exerciseLiveColor;
|
|
17827
|
+
exports.exerciseRowStateColor = exerciseRowStateColor;
|
|
17603
17828
|
exports.extractTaskRefs = extractTaskRefs;
|
|
17604
17829
|
exports.fitColumns = fitColumns;
|
|
17605
17830
|
exports.formatCompact = formatCompact;
|
|
@@ -17672,6 +17897,7 @@ exports.raisedLevel = raisedLevel;
|
|
|
17672
17897
|
exports.resolveColor = resolveColor;
|
|
17673
17898
|
exports.resolveIndicator = resolveIndicator;
|
|
17674
17899
|
exports.resolveSurfaceDepth = resolveSurfaceDepth;
|
|
17900
|
+
exports.resultPaletteColors = resultPaletteColors;
|
|
17675
17901
|
exports.rgbToHex = rgbToHex;
|
|
17676
17902
|
exports.rgbToHsv = rgbToHsv;
|
|
17677
17903
|
exports.roundRpe = roundRpe;
|
|
@@ -17680,6 +17906,7 @@ exports.roundWeight = roundWeight;
|
|
|
17680
17906
|
exports.rpeColor = rpeColor;
|
|
17681
17907
|
exports.semanticColorsDark = semanticColorsDark;
|
|
17682
17908
|
exports.semanticColorsLight = semanticColorsLight;
|
|
17909
|
+
exports.semanticPins = semanticPins;
|
|
17683
17910
|
exports.semanticTypography = semanticTypography;
|
|
17684
17911
|
exports.sequentialEffort = sequentialEffort;
|
|
17685
17912
|
exports.sessionLinkers = sessionLinkers;
|