@titan-design/react-ui 0.5.0 → 0.7.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/dist/bodymap.js +241 -189
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +241 -189
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +1017 -130
- package/dist/index.d.ts +1017 -130
- package/dist/index.js +3058 -1090
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2992 -1091
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-MO0JCySL.d.mts → pages-8u_4WbL-.d.mts} +280 -57
- package/dist/{pages-D7Jlssvp.d.ts → pages-DaWiBOGa.d.ts} +280 -57
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +1797 -1292
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +1797 -1292
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +464 -268
- package/dist/theme/index.d.ts +464 -268
- package/dist/theme/index.js +303 -191
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +295 -192
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +160 -143
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +160 -143
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/package.json +3 -1
- package/src/arch/Architecture.stories.tsx +870 -0
- package/src/arch/annotations.json +48 -0
- package/src/arch/arch-graph.json +4301 -0
- package/src/components/custom/DateTime/DateTime.stories.tsx +83 -7
- package/src/components/custom/DateTime/DateTime.test.tsx +29 -3
- package/src/components/custom/DateTime/DateTime.tsx +55 -15
- package/src/components/custom/EmptyState/EmptyState.stories.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.stories.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.test.tsx +2 -2
- package/src/components/custom/Gauge/Gauge.tsx +6 -3
- package/src/components/custom/Metric/Metric.stories.tsx +1 -1
- package/src/components/custom/Scatter/Scatter.stories.tsx +1 -1
- package/src/components/custom/Scatter/Scatter.tsx +3 -5
- package/src/components/custom/Sidebar/Sidebar.stories.tsx +1 -1
- package/src/components/custom/Table/Table.stories.tsx +1 -1
- package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +62 -0
- package/src/components/custom/TimerReadout/TimerReadout.test.tsx +72 -0
- package/src/components/custom/TimerReadout/TimerReadout.tsx +75 -0
- package/src/components/custom/TimerReadout/index.ts +1 -0
- package/src/components/custom/Treemap/Treemap.stories.tsx +1 -1
- package/src/components/custom/Treemap/Treemap.tsx +3 -5
- package/src/components/custom/Typography/Typography.stories.tsx +46 -28
- package/src/components/custom/Typography/Typography.test.tsx +13 -3
- package/src/components/custom/Typography/Typography.tsx +5 -0
- package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +21 -13
- package/src/components/custom/Workout/ActiveWorkoutPage.test.tsx +16 -13
- package/src/components/custom/Workout/ActiveWorkoutPage.tsx +11 -16
- package/src/components/custom/Workout/BaseBadge.stories.tsx +1 -1
- package/src/components/custom/Workout/BodyMap.stories.tsx +1 -1
- package/src/components/custom/Workout/BodyMap.tsx +6 -3
- package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +1 -1
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +6 -3
- package/src/components/custom/Workout/CapacityBandChart.stories.tsx +1 -1
- package/src/components/custom/Workout/CapacityBandChart.test.tsx +2 -2
- package/src/components/custom/Workout/CapacityBandChart.tsx +9 -6
- package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
- package/src/components/custom/Workout/DeviationBar.test.tsx +1 -1
- package/src/components/custom/Workout/DeviationBar.tsx +7 -4
- package/src/components/custom/Workout/ExerciseCard.stories.tsx +51 -66
- package/src/components/custom/Workout/ExerciseCard.test.tsx +146 -143
- package/src/components/custom/Workout/ExerciseCard.tsx +176 -198
- package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +99 -0
- package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +72 -0
- package/src/components/custom/Workout/ExerciseCardHeading.tsx +43 -0
- package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +151 -0
- package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +5 -3
- package/src/components/custom/Workout/ExerciseDetailPage.test.tsx +4 -4
- package/src/components/custom/Workout/ExerciseDetailPage.tsx +6 -6
- package/src/components/custom/Workout/ExerciseHeading.stories.tsx +81 -0
- package/src/components/custom/Workout/ExerciseHeading.test.tsx +77 -0
- package/src/components/custom/Workout/ExerciseHeading.tsx +85 -0
- package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +110 -0
- package/src/components/custom/Workout/ExerciseIndicator.test.tsx +93 -0
- package/src/components/custom/Workout/ExerciseIndicator.tsx +120 -0
- package/src/components/custom/Workout/FatigueMeter.stories.tsx +51 -0
- package/src/components/custom/Workout/FatigueMeter.test.tsx +73 -0
- package/src/components/custom/Workout/FatigueMeter.tsx +82 -0
- package/src/components/custom/Workout/InputBar.stories.tsx +1 -1
- package/src/components/custom/Workout/InputBar.tsx +2 -1
- package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
- package/src/components/custom/Workout/IntensityBar.test.tsx +8 -8
- package/src/components/custom/Workout/IntensityBar.tsx +10 -6
- package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +153 -0
- package/src/components/custom/Workout/LiveAuraFrame.test.tsx +74 -0
- package/src/components/custom/Workout/LiveAuraFrame.tsx +105 -0
- package/src/components/custom/Workout/MesoCard.stories.tsx +1 -1
- package/src/components/custom/Workout/MesoCard.tsx +8 -3
- package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
- package/src/components/custom/Workout/MesoProgressBar.test.tsx +1 -1
- package/src/components/custom/Workout/MesoProgressBar.tsx +3 -2
- package/src/components/custom/Workout/MesoStatusCard.stories.tsx +1 -1
- package/src/components/custom/Workout/MesoStatusCard.tsx +20 -13
- package/src/components/custom/Workout/MetricTiles.stories.tsx +60 -0
- package/src/components/custom/Workout/MetricTiles.test.tsx +58 -0
- package/src/components/custom/Workout/MetricTiles.tsx +48 -0
- package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +1 -1
- package/src/components/custom/Workout/MuscleGroupChip.tsx +7 -4
- package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
- package/src/components/custom/Workout/PrBadge.stories.tsx +1 -1
- package/src/components/custom/Workout/PrBadge.tsx +5 -2
- package/src/components/custom/Workout/PrHistoryModal.stories.tsx +1 -1
- package/src/components/custom/Workout/PrHistoryModal.tsx +4 -3
- package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +4 -16
- package/src/components/custom/Workout/ProgramPlanningPage.tsx +10 -7
- package/src/components/custom/Workout/README.md +146 -4
- package/src/components/custom/Workout/ReadinessCheck.stories.tsx +1 -1
- package/src/components/custom/Workout/ReadinessCheck.tsx +7 -4
- package/src/components/custom/Workout/RestTimer.stories.tsx +1 -1
- package/src/components/custom/Workout/RestTimer.tsx +17 -11
- package/src/components/custom/Workout/RowInventory.stories.tsx +405 -0
- package/src/components/custom/Workout/S3FullRail.stories.tsx +34 -0
- package/src/components/custom/Workout/S3SessionPace.stories.tsx +95 -0
- package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +61 -0
- package/src/components/custom/Workout/S3SetTypes.stories.tsx +176 -0
- package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +240 -0
- package/src/components/custom/Workout/ScheduleTiles.stories.tsx +40 -0
- package/src/components/custom/Workout/ScheduleTiles.test.tsx +34 -0
- package/src/components/custom/Workout/ScheduleTiles.tsx +70 -0
- package/src/components/custom/Workout/SegmentedBar.stories.tsx +99 -0
- package/src/components/custom/Workout/SegmentedBar.test.tsx +77 -0
- package/src/components/custom/Workout/SegmentedBar.tsx +172 -0
- package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +50 -0
- package/src/components/custom/Workout/SegmentedProgressBar.test.tsx +80 -0
- package/src/components/custom/Workout/SegmentedProgressBar.tsx +67 -0
- package/src/components/custom/Workout/SessionHeader.stories.tsx +121 -0
- package/src/components/custom/Workout/SessionHeader.test.tsx +122 -0
- package/src/components/custom/Workout/SessionHeader.tsx +152 -0
- package/src/components/custom/Workout/SessionRail.stories.tsx +153 -0
- package/src/components/custom/Workout/SessionRail.test.tsx +86 -0
- package/src/components/custom/Workout/SessionRail.tsx +126 -0
- package/src/components/custom/Workout/SetBar.stories.tsx +124 -0
- package/src/components/custom/Workout/SetBar.test.tsx +123 -0
- package/src/components/custom/Workout/SetBar.tsx +171 -0
- package/src/components/custom/Workout/SetRow.stories.tsx +50 -100
- package/src/components/custom/Workout/SetRow.test.tsx +94 -166
- package/src/components/custom/Workout/SetRow.tsx +170 -232
- package/src/components/custom/Workout/SetStrip.stories.tsx +154 -0
- package/src/components/custom/Workout/SetStrip.test.tsx +109 -0
- package/src/components/custom/Workout/SetStrip.tsx +71 -0
- package/src/components/custom/Workout/SetTableHeader.stories.tsx +66 -0
- package/src/components/custom/Workout/SetTableHeader.test.tsx +47 -0
- package/src/components/custom/Workout/SetTableHeader.tsx +88 -0
- package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +47 -0
- package/src/components/custom/Workout/SetsRepsLoad.test.tsx +44 -0
- package/src/components/custom/Workout/SetsRepsLoad.tsx +52 -0
- package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
- package/src/components/custom/Workout/Sparkline.tsx +2 -1
- package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
- package/src/components/custom/Workout/StatusDot.test.tsx +2 -2
- package/src/components/custom/Workout/StatusDot.tsx +12 -9
- package/src/components/custom/Workout/StatusPill.stories.tsx +59 -0
- package/src/components/custom/Workout/StatusPill.test.tsx +63 -0
- package/src/components/custom/Workout/StatusPill.tsx +88 -0
- package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +1 -1
- package/src/components/custom/Workout/StrengthTrendChart.tsx +9 -6
- package/src/components/custom/Workout/SupersetWrapper.stories.tsx +1 -1
- package/src/components/custom/Workout/SupersetWrapper.tsx +2 -1
- package/src/components/custom/Workout/TempoBar.stories.tsx +1 -1
- package/src/components/custom/Workout/TempoDisplay.stories.tsx +12 -1
- package/src/components/custom/Workout/TempoDisplay.tsx +29 -36
- package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +1 -1
- package/src/components/custom/Workout/VelocityStrip.modalities.stories.tsx +254 -0
- package/src/components/custom/Workout/VelocityStrip.responsive.stories.tsx +145 -0
- package/src/components/custom/Workout/VelocityStrip.stories.tsx +129 -66
- package/src/components/custom/Workout/VelocityStrip.test.tsx +379 -144
- package/src/components/custom/Workout/VelocityStrip.tsx +508 -120
- package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +73 -0
- package/src/components/custom/Workout/VolumeLandmarkBar.test.tsx +119 -0
- package/src/components/custom/Workout/VolumeLandmarkBar.tsx +154 -0
- package/src/components/custom/Workout/WeekRow.stories.tsx +1 -1
- package/src/components/custom/Workout/WeekRow.tsx +3 -2
- package/src/components/custom/Workout/WeightBadge.stories.tsx +1 -1
- package/src/components/custom/Workout/WeightBadge.tsx +6 -2
- package/src/components/custom/Workout/WorkoutCard.stories.tsx +2 -6
- package/src/components/custom/Workout/WorkoutCard.test.tsx +13 -46
- package/src/components/custom/Workout/WorkoutCard.tsx +5 -2
- package/src/components/custom/Workout/WorkoutPill.stories.tsx +1 -1
- package/src/components/custom/Workout/WorkoutPill.tsx +12 -8
- package/src/components/custom/Workout/ZoneTrack.stories.tsx +140 -0
- package/src/components/custom/Workout/ZoneTrack.test.tsx +200 -0
- package/src/components/custom/Workout/ZoneTrack.tsx +315 -0
- package/src/components/custom/Workout/icons.tsx +6 -67
- package/src/components/custom/Workout/index.ts +55 -2
- package/src/components/custom/Workout/metricText.stories.tsx +69 -0
- package/src/components/custom/Workout/metricText.tsx +34 -0
- package/src/components/custom/Workout/paceTone.test.ts +29 -0
- package/src/components/custom/Workout/paceTone.ts +27 -0
- package/src/components/custom/Workout/setHeadingKit.tsx +177 -0
- package/src/components/custom/index.ts +1 -0
- package/src/components/custom/stepper/Stepper.stories.tsx +1 -1
- package/src/components/icons/SvgIcon.tsx +50 -0
- package/src/components/icons/icons.stories.tsx +122 -0
- package/src/components/icons/icons.test.tsx +73 -0
- package/src/components/icons/icons.tsx +153 -0
- package/src/components/icons/index.ts +4 -0
- package/src/components/index.ts +6 -0
- package/src/components/shell/BrandLockup.stories.tsx +27 -0
- package/src/components/shell/BrandLockup.test.tsx +23 -0
- package/src/components/shell/BrandLockup.tsx +47 -0
- package/src/components/shell/DashboardShell.stories.tsx +65 -0
- package/src/components/shell/DashboardShell.test.tsx +42 -0
- package/src/components/shell/DashboardShell.tsx +74 -0
- package/src/components/shell/DeviceIndicator.stories.tsx +28 -0
- package/src/components/shell/DeviceIndicator.test.tsx +26 -0
- package/src/components/shell/DeviceIndicator.tsx +52 -0
- package/src/components/shell/DeviceMenu.stories.tsx +47 -0
- package/src/components/shell/DeviceMenu.test.tsx +40 -0
- package/src/components/shell/DeviceMenu.tsx +65 -0
- package/src/components/shell/DeviceRow.stories.tsx +38 -0
- package/src/components/shell/DeviceRow.test.tsx +37 -0
- package/src/components/shell/DeviceRow.tsx +58 -0
- package/src/components/shell/NavItem.stories.tsx +52 -0
- package/src/components/shell/NavItem.test.tsx +35 -0
- package/src/components/shell/NavItem.tsx +75 -0
- package/src/components/shell/README.md +116 -0
- package/src/components/shell/SessionRailSpecimen.stories.tsx +753 -0
- package/src/components/shell/SessionStatePill.stories.tsx +27 -0
- package/src/components/shell/SessionStatePill.test.tsx +25 -0
- package/src/components/shell/SessionStatePill.tsx +46 -0
- package/src/components/shell/SideNav.stories.tsx +81 -0
- package/src/components/shell/SideNav.test.tsx +51 -0
- package/src/components/shell/SideNav.tsx +74 -0
- package/src/components/shell/TopBar.stories.tsx +49 -0
- package/src/components/shell/TopBar.test.tsx +36 -0
- package/src/components/shell/TopBar.tsx +89 -0
- package/src/components/shell/index.ts +13 -0
- package/src/components/ui/alert/Alert.stories.tsx +1 -1
- package/src/components/ui/autocomplete/Autocomplete.stories.tsx +1 -1
- package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
- package/src/components/ui/badge/Badge.stories.tsx +1 -1
- package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
- package/src/components/ui/button/Button.stories.tsx +1 -1
- package/src/components/ui/card/Card.stories.tsx +1 -1
- package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
- package/src/components/ui/chip/Chip.stories.tsx +1 -1
- package/src/components/ui/collapse/Collapse.stories.tsx +1 -1
- package/src/components/ui/data-row/DataRow.stories.tsx +1 -1
- package/src/components/ui/divider/Divider.stories.tsx +1 -1
- package/src/components/ui/drawer/Drawer.stories.tsx +1 -1
- package/src/components/ui/form-field/FormField.stories.tsx +1 -1
- package/src/components/ui/help-tip/HelpTip.stories.tsx +1 -1
- package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
- package/src/components/ui/index.ts +1 -0
- package/src/components/ui/indicator/Indicator.stories.tsx +38 -2
- package/src/components/ui/indicator/Indicator.test.tsx +20 -1
- package/src/components/ui/indicator/Indicator.tsx +50 -6
- package/src/components/ui/indicator/index.ts +1 -1
- package/src/components/ui/input/Input.stories.tsx +1 -1
- package/src/components/ui/link/Link.stories.tsx +1 -1
- package/src/components/ui/list-item/ListItem.stories.tsx +1 -1
- package/src/components/ui/menu/Menu.stories.tsx +1 -1
- package/src/components/ui/modal/Modal.stories.tsx +1 -1
- package/src/components/ui/pill/Pill.stories.tsx +1 -1
- package/src/components/ui/popover/Popover.stories.tsx +1 -1
- package/src/components/ui/progress/Progress.stories.tsx +1 -1
- package/src/components/ui/radio/Radio.stories.tsx +1 -1
- package/src/components/ui/section/Section.stories.tsx +1 -1
- package/src/components/ui/select/Select.stories.tsx +1 -1
- package/src/components/ui/skeleton/Skeleton.stories.tsx +1 -1
- package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
- package/src/components/ui/spinner/Spinner.tsx +3 -2
- package/src/components/ui/stack/Stack.stories.tsx +1 -1
- package/src/components/ui/surface/Surface.stories.tsx +1 -1
- package/src/components/ui/switch/Switch.stories.tsx +1 -1
- package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
- package/src/components/ui/tile/Tile.stories.tsx +79 -0
- package/src/components/ui/tile/Tile.test.tsx +48 -0
- package/src/components/ui/tile/Tile.tsx +64 -0
- package/src/components/ui/tile/index.ts +2 -0
- package/src/components/ui/toast/Toast.stories.tsx +1 -1
- package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +1 -1
- package/src/components/ui/toolbar-button/ToolbarButton.tsx +2 -1
- package/src/components/ui/tooltip/Tooltip.stories.tsx +1 -1
- package/src/examples/react-hook-form/ReactHookForm.stories.tsx +1 -1
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useTimer.test.ts +150 -0
- package/src/hooks/useTimer.ts +77 -0
- package/src/index.ts +3 -0
- package/src/pages.ts +1 -1
- package/src/stories/PresetShowcase.stories.tsx +1 -1
- package/src/stories/ThemePresets.stories.tsx +1 -1
- package/src/theme/ColorSystem.stories.tsx +323 -0
- package/src/theme/Colors.stories.tsx +74 -9
- package/src/theme/barrel.ts +1 -0
- package/src/theme/config.ts +20 -3
- package/src/theme/elevation.stories.tsx +1 -1
- package/src/theme/extracted-colors-dataviz.ts +21 -0
- package/src/theme/extracted-colors-ui.ts +20 -0
- package/src/theme/global.css +69 -53
- package/src/theme/gradients.test.ts +25 -0
- package/src/theme/gradients.ts +36 -0
- package/src/theme/shadows.stories.tsx +1 -1
- package/src/theme/tokens/primitives.test.ts +232 -0
- package/src/theme/tokens/primitives.ts +238 -87
- package/src/theme/tokens/semantic.ts +101 -81
- package/src/theme/workout-tokens.ts +26 -21
- package/src/utils/avatar-color.ts +3 -3
- package/tailwind.config.js +15 -3
package/dist/pages.mjs
CHANGED
|
@@ -6,22 +6,160 @@ import { twMerge } from 'tailwind-merge';
|
|
|
6
6
|
|
|
7
7
|
// src/components/custom/Workout/ActiveWorkoutPage.tsx
|
|
8
8
|
|
|
9
|
+
// src/theme/tokens/primitives.ts
|
|
10
|
+
var primitiveColors = {
|
|
11
|
+
// Blue scale
|
|
12
|
+
blue: {
|
|
13
|
+
400: "#60A5FA",
|
|
14
|
+
600: "#5048E5",
|
|
15
|
+
700: "#3832A0"},
|
|
16
|
+
// Red scale
|
|
17
|
+
red: {
|
|
18
|
+
500: "#EF4444",
|
|
19
|
+
600: "#D14343"},
|
|
20
|
+
// Vivid red scale
|
|
21
|
+
redVivid: {
|
|
22
|
+
400: "#FF6070",
|
|
23
|
+
500: "#FF4757",
|
|
24
|
+
700: "#C42539"},
|
|
25
|
+
// Neutral/Gray scale
|
|
26
|
+
neutral: {
|
|
27
|
+
50: "#FAFAFA",
|
|
28
|
+
100: "#F3F4F6",
|
|
29
|
+
300: "#D1D5DB",
|
|
30
|
+
400: "#9CA3AF",
|
|
31
|
+
500: "#6B7280",
|
|
32
|
+
600: "#4B5563",
|
|
33
|
+
900: "#111827"},
|
|
34
|
+
// Charcoal scale (dark backgrounds)
|
|
35
|
+
charcoal: {
|
|
36
|
+
200: "#3C3C3C",
|
|
37
|
+
300: "#2C2C2C",
|
|
38
|
+
400: "#1F1F1F",
|
|
39
|
+
500: "#1C1C1C",
|
|
40
|
+
600: "#191919",
|
|
41
|
+
700: "#161616",
|
|
42
|
+
900: "#101010"
|
|
43
|
+
},
|
|
44
|
+
// Pure colors
|
|
45
|
+
white: "#FFFFFF"};
|
|
46
|
+
var primitiveRamps = {
|
|
47
|
+
red: {
|
|
48
|
+
50: "#FFF4F4",
|
|
49
|
+
500: "#E05254",
|
|
50
|
+
600: "#D14343",
|
|
51
|
+
// pin
|
|
52
|
+
700: "#A4221C",
|
|
53
|
+
800: "#7E1002"},
|
|
54
|
+
orange: {
|
|
55
|
+
200: "#FFC7A2",
|
|
56
|
+
300: "#FFA063",
|
|
57
|
+
400: "#FF7900",
|
|
58
|
+
// pin
|
|
59
|
+
500: "#DA5F00",
|
|
60
|
+
600: "#B94A00"},
|
|
61
|
+
amber: {
|
|
62
|
+
50: "#FFF7DD",
|
|
63
|
+
200: "#FFD352",
|
|
64
|
+
300: "#F9B415",
|
|
65
|
+
// pin
|
|
66
|
+
400: "#E08C00",
|
|
67
|
+
500: "#C27400"},
|
|
68
|
+
green: {
|
|
69
|
+
50: "#E3FFEE",
|
|
70
|
+
200: "#58F69E",
|
|
71
|
+
300: "#2ED573",
|
|
72
|
+
// pin
|
|
73
|
+
400: "#21C05D",
|
|
74
|
+
500: "#22A444",
|
|
75
|
+
600: "#298732"},
|
|
76
|
+
cyan: {
|
|
77
|
+
// pin
|
|
78
|
+
400: "#01B5D1",
|
|
79
|
+
500: "#2697B7",
|
|
80
|
+
600: "#307B9B",
|
|
81
|
+
700: "#2A617F",
|
|
82
|
+
800: "#22465F",
|
|
83
|
+
900: "#0B3149"},
|
|
84
|
+
blue: {
|
|
85
|
+
50: "#EFF8FF",
|
|
86
|
+
300: "#78C2FF",
|
|
87
|
+
500: "#2196F3",
|
|
88
|
+
// pin
|
|
89
|
+
600: "#1072CB"},
|
|
90
|
+
magenta: {
|
|
91
|
+
600: "#BA2996"}
|
|
92
|
+
};
|
|
93
|
+
var sequentialEffort = [
|
|
94
|
+
primitiveRamps.green[300],
|
|
95
|
+
primitiveRamps.amber[200],
|
|
96
|
+
primitiveRamps.amber[300],
|
|
97
|
+
primitiveRamps.orange[400],
|
|
98
|
+
primitiveRamps.red[600],
|
|
99
|
+
primitiveRamps.red[700]
|
|
100
|
+
];
|
|
101
|
+
var discreteRainbow = [
|
|
102
|
+
"#E8ECFB",
|
|
103
|
+
"#D9CCE3",
|
|
104
|
+
"#D1BBD7",
|
|
105
|
+
"#CAACCB",
|
|
106
|
+
"#BA8DB4",
|
|
107
|
+
"#AE76A3",
|
|
108
|
+
"#AA6F9E",
|
|
109
|
+
"#994F88",
|
|
110
|
+
"#882E72",
|
|
111
|
+
"#1965B0",
|
|
112
|
+
"#437DBF",
|
|
113
|
+
"#5289C7",
|
|
114
|
+
"#6195CF",
|
|
115
|
+
"#7BAFDE",
|
|
116
|
+
"#4EB265",
|
|
117
|
+
"#90C987",
|
|
118
|
+
"#CAE0AB",
|
|
119
|
+
"#F7F056",
|
|
120
|
+
"#F7CB45",
|
|
121
|
+
"#F6C141",
|
|
122
|
+
"#F4A736",
|
|
123
|
+
"#F1932D",
|
|
124
|
+
"#EE8026",
|
|
125
|
+
"#E8601C",
|
|
126
|
+
"#E65518",
|
|
127
|
+
"#DC050C",
|
|
128
|
+
"#A5170E",
|
|
129
|
+
"#72190E",
|
|
130
|
+
"#42150A"
|
|
131
|
+
];
|
|
132
|
+
|
|
9
133
|
// src/theme/workout-tokens.ts
|
|
10
134
|
var WORKOUT_TOKENS = {
|
|
11
135
|
// Canonical 4-band performance scale — the single source for BOTH the
|
|
12
136
|
// VelocityStrip zone bars and the SetRow RPE color (TD-03.43). The direction
|
|
13
137
|
// is intentionally inverted between the two consumers: for velocity, green =
|
|
14
|
-
// fastest/best; for RPE, green = easiest.
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
138
|
+
// fastest/best; for RPE, green = easiest. This is the [0,2,3,4] subsample of
|
|
139
|
+
// the canonical `sequentialEffort` primitive: an EVEN hue walk across the ramp
|
|
140
|
+
// (green → gold → orange → red). The earlier [0,1,2,4] spent two of its four
|
|
141
|
+
// bands on adjacent yellows (amber-200 + amber-300) and skipped orange, reading
|
|
142
|
+
// yellow-heavy with an abrupt jump to red; sampling amber-300 + orange-400
|
|
143
|
+
// instead gives four cleanly separable bands that hold at 3px strip scale.
|
|
144
|
+
// Consumed inline (RN).
|
|
19
145
|
scale: {
|
|
20
|
-
green:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
146
|
+
green: sequentialEffort[0],
|
|
147
|
+
// green-300
|
|
148
|
+
yellow: sequentialEffort[2],
|
|
149
|
+
// amber-300 (gold)
|
|
150
|
+
orange: sequentialEffort[3],
|
|
151
|
+
// orange-400 (true orange)
|
|
152
|
+
red: sequentialEffort[4]
|
|
153
|
+
// red-600
|
|
24
154
|
},
|
|
155
|
+
// Surface and border colors were removed here: those flip with the theme, so
|
|
156
|
+
// components use the CSS custom properties (var(--color-surface-*/border-*))
|
|
157
|
+
// directly. Only theme-independent data-viz values remain below.
|
|
158
|
+
// Intensity bar specific — over-target tiers deepen along the red ramp.
|
|
159
|
+
intensity: {
|
|
160
|
+
// matches status-error
|
|
161
|
+
over2: primitiveRamps.red[700],
|
|
162
|
+
over3: primitiveRamps.red[800]},
|
|
25
163
|
// Placeholder strip
|
|
26
164
|
placeholder: {
|
|
27
165
|
fill: "#3A3A3A"
|
|
@@ -31,12 +169,6 @@ var WORKOUT_TOKENS = {
|
|
|
31
169
|
function roundRpe(rpe) {
|
|
32
170
|
return Math.round(rpe * 2) / 2;
|
|
33
171
|
}
|
|
34
|
-
function rpeColor(rpe) {
|
|
35
|
-
if (rpe >= 9.5) return WORKOUT_TOKENS.scale.red;
|
|
36
|
-
if (rpe >= 8.5) return WORKOUT_TOKENS.scale.orange;
|
|
37
|
-
if (rpe >= 7) return WORKOUT_TOKENS.scale.yellow;
|
|
38
|
-
return WORKOUT_TOKENS.scale.green;
|
|
39
|
-
}
|
|
40
172
|
function roundWeight(weight) {
|
|
41
173
|
return Math.round(weight);
|
|
42
174
|
}
|
|
@@ -64,14 +196,258 @@ function wrapJsx(fn) {
|
|
|
64
196
|
var jsx = wrapJsx(jsx$1);
|
|
65
197
|
var jsxs = wrapJsx(jsxs$1);
|
|
66
198
|
|
|
199
|
+
// src/components/custom/Workout/SegmentedBar.tsx
|
|
200
|
+
var PULSE_HALF_MS = 950;
|
|
201
|
+
var PULSE_MIN_OPACITY = 0.45;
|
|
202
|
+
var SEGMENTED_BAR_GAP = 5;
|
|
203
|
+
function usePulse(active) {
|
|
204
|
+
const [value] = useState(() => new Animated.Value(0));
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
if (!active) return;
|
|
207
|
+
const loop = Animated.loop(
|
|
208
|
+
Animated.sequence([
|
|
209
|
+
Animated.timing(value, {
|
|
210
|
+
toValue: 1,
|
|
211
|
+
duration: PULSE_HALF_MS,
|
|
212
|
+
easing: Easing.inOut(Easing.ease),
|
|
213
|
+
useNativeDriver: false
|
|
214
|
+
}),
|
|
215
|
+
Animated.timing(value, {
|
|
216
|
+
toValue: 0,
|
|
217
|
+
duration: PULSE_HALF_MS,
|
|
218
|
+
easing: Easing.inOut(Easing.ease),
|
|
219
|
+
useNativeDriver: false
|
|
220
|
+
})
|
|
221
|
+
])
|
|
222
|
+
);
|
|
223
|
+
loop.start();
|
|
224
|
+
return () => loop.stop();
|
|
225
|
+
}, [active, value]);
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
228
|
+
function SegmentedBar({
|
|
229
|
+
segments,
|
|
230
|
+
height = 8,
|
|
231
|
+
gap = SEGMENTED_BAR_GAP,
|
|
232
|
+
radius = 2,
|
|
233
|
+
marker = null,
|
|
234
|
+
segmentTestID,
|
|
235
|
+
style,
|
|
236
|
+
...props
|
|
237
|
+
}) {
|
|
238
|
+
const pulse = usePulse(segments.some((s) => s.pulse));
|
|
239
|
+
return /* @__PURE__ */ jsxs(View, { style: [{ flexDirection: "row", height, gap, position: "relative" }, style], ...props, children: [
|
|
240
|
+
segments.map((seg, i) => {
|
|
241
|
+
const fillStyle = {
|
|
242
|
+
width: `${(seg.fill ?? 1) * 100}%`,
|
|
243
|
+
height: "100%",
|
|
244
|
+
backgroundColor: seg.color,
|
|
245
|
+
opacity: seg.opacity
|
|
246
|
+
};
|
|
247
|
+
const testID = segmentTestID?.(seg, i) ?? "segmented-bar-segment";
|
|
248
|
+
return /* @__PURE__ */ jsx(
|
|
249
|
+
View,
|
|
250
|
+
{
|
|
251
|
+
style: {
|
|
252
|
+
flex: seg.weight ?? 1,
|
|
253
|
+
minWidth: 0,
|
|
254
|
+
height: "100%",
|
|
255
|
+
marginLeft: seg.leadingGap,
|
|
256
|
+
borderRadius: radius,
|
|
257
|
+
overflow: "hidden"
|
|
258
|
+
},
|
|
259
|
+
children: seg.pulse ? /* @__PURE__ */ jsx(
|
|
260
|
+
Animated.View,
|
|
261
|
+
{
|
|
262
|
+
style: {
|
|
263
|
+
...fillStyle,
|
|
264
|
+
...seg.pulseColor ? {
|
|
265
|
+
backgroundColor: pulse.interpolate({
|
|
266
|
+
inputRange: [0, 1],
|
|
267
|
+
outputRange: seg.pulseColor
|
|
268
|
+
})
|
|
269
|
+
} : {
|
|
270
|
+
opacity: pulse.interpolate({
|
|
271
|
+
inputRange: [0, 1],
|
|
272
|
+
outputRange: [PULSE_MIN_OPACITY, 1]
|
|
273
|
+
})
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
accessibilityElementsHidden: true,
|
|
277
|
+
testID
|
|
278
|
+
}
|
|
279
|
+
) : /* @__PURE__ */ jsx(View, { style: fillStyle, accessibilityElementsHidden: true, testID })
|
|
280
|
+
},
|
|
281
|
+
i
|
|
282
|
+
);
|
|
283
|
+
}),
|
|
284
|
+
marker ? /* @__PURE__ */ jsx(
|
|
285
|
+
View,
|
|
286
|
+
{
|
|
287
|
+
style: {
|
|
288
|
+
position: "absolute",
|
|
289
|
+
left: `${marker.position * 100}%`,
|
|
290
|
+
top: 0,
|
|
291
|
+
bottom: 0,
|
|
292
|
+
width: 2,
|
|
293
|
+
backgroundColor: marker.color
|
|
294
|
+
},
|
|
295
|
+
accessibilityElementsHidden: true,
|
|
296
|
+
testID: "segmented-bar-marker"
|
|
297
|
+
}
|
|
298
|
+
) : null
|
|
299
|
+
] });
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/components/custom/Workout/SetBar.tsx
|
|
303
|
+
var SET_STRIP_ZONES = {
|
|
304
|
+
slow: primitiveRamps.red[600],
|
|
305
|
+
moderate: primitiveRamps.orange[400],
|
|
306
|
+
fast: primitiveRamps.amber[300],
|
|
307
|
+
fastest: primitiveRamps.green[300]
|
|
308
|
+
};
|
|
309
|
+
var TODO_COLOR = primitiveColors.charcoal[300];
|
|
310
|
+
var SET_STRIP_VARIABLE_COLOR = primitiveRamps.cyan[900];
|
|
311
|
+
var NOTCH_GAP = 2;
|
|
312
|
+
var CLUSTER_GAP = 3;
|
|
313
|
+
var MYO_UPCOMING_CLUSTERS = 3;
|
|
314
|
+
var MYO_UPCOMING_CLUSTER_LEN = 5;
|
|
315
|
+
var MYO_UPCOMING_FADE = 0.6;
|
|
316
|
+
var PULSE_RANGE = {
|
|
317
|
+
[SET_STRIP_ZONES.slow]: [primitiveRamps.red[500], primitiveRamps.red[700]],
|
|
318
|
+
[SET_STRIP_ZONES.moderate]: [primitiveRamps.orange[300], primitiveRamps.orange[500]],
|
|
319
|
+
[SET_STRIP_ZONES.fast]: [primitiveRamps.amber[200], primitiveRamps.amber[400]],
|
|
320
|
+
[SET_STRIP_ZONES.fastest]: [primitiveRamps.green[200], primitiveRamps.green[400]]
|
|
321
|
+
};
|
|
322
|
+
function velocityZoneColor(v) {
|
|
323
|
+
if (v < 0.5) return SET_STRIP_ZONES.slow;
|
|
324
|
+
if (v < 0.75) return SET_STRIP_ZONES.moderate;
|
|
325
|
+
if (v < 1) return SET_STRIP_ZONES.fast;
|
|
326
|
+
return SET_STRIP_ZONES.fastest;
|
|
327
|
+
}
|
|
328
|
+
function chunkedSegments(chunks, gap) {
|
|
329
|
+
return chunks.flatMap(
|
|
330
|
+
(vels, ci) => vels.map((v, ri) => ({
|
|
331
|
+
color: velocityZoneColor(v),
|
|
332
|
+
...ci > 0 && ri === 0 ? { leadingGap: gap } : {}
|
|
333
|
+
}))
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
function rangeSegments(floor, max, doneVels) {
|
|
337
|
+
return Array.from({ length: max }, (_, i) => {
|
|
338
|
+
if (i < doneVels.length) return { color: velocityZoneColor(doneVels[i]) };
|
|
339
|
+
return { color: i < floor ? TODO_COLOR : SET_STRIP_VARIABLE_COLOR };
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function myoUpcomingSegments(activationLen, clusterCount) {
|
|
343
|
+
const activation = Array.from({ length: activationLen }, () => ({ color: TODO_COLOR }));
|
|
344
|
+
const trail = Array.from(
|
|
345
|
+
{ length: clusterCount },
|
|
346
|
+
(_, ci) => Array.from({ length: MYO_UPCOMING_CLUSTER_LEN }, (_2, ri) => ({
|
|
347
|
+
color: SET_STRIP_VARIABLE_COLOR,
|
|
348
|
+
opacity: MYO_UPCOMING_FADE ** ci,
|
|
349
|
+
...ri === 0 ? { leadingGap: CLUSTER_GAP } : {}
|
|
350
|
+
}))
|
|
351
|
+
).flat();
|
|
352
|
+
return [...activation, ...trail];
|
|
353
|
+
}
|
|
354
|
+
function setSegments(set) {
|
|
355
|
+
if (set.status === "todo") {
|
|
356
|
+
return [{ color: TODO_COLOR }];
|
|
357
|
+
}
|
|
358
|
+
if (set.status === "done") {
|
|
359
|
+
return set.velocities.map((v) => ({ color: velocityZoneColor(v) }));
|
|
360
|
+
}
|
|
361
|
+
if (set.status === "range") {
|
|
362
|
+
return rangeSegments(set.floor, set.max, set.doneVels);
|
|
363
|
+
}
|
|
364
|
+
if (set.status === "drop") {
|
|
365
|
+
return chunkedSegments(set.subloads, NOTCH_GAP);
|
|
366
|
+
}
|
|
367
|
+
if (set.status === "myo") {
|
|
368
|
+
return chunkedSegments([set.activation, ...set.clusters], CLUSTER_GAP);
|
|
369
|
+
}
|
|
370
|
+
if (set.status === "myo-upcoming") {
|
|
371
|
+
return myoUpcomingSegments(set.activationLen, set.clusterCount ?? MYO_UPCOMING_CLUSTERS);
|
|
372
|
+
}
|
|
373
|
+
const performed = set.velocities.map((v) => {
|
|
374
|
+
const color = velocityZoneColor(v);
|
|
375
|
+
return { color, pulse: true, pulseColor: PULSE_RANGE[color] };
|
|
376
|
+
});
|
|
377
|
+
const remaining = Math.max(0, set.planned - set.velocities.length);
|
|
378
|
+
return [...performed, ...Array.from({ length: remaining }, () => ({ color: TODO_COLOR }))];
|
|
379
|
+
}
|
|
380
|
+
function setBarSegmentTestID(seg) {
|
|
381
|
+
if (seg.pulse) return "set-strip-pulse";
|
|
382
|
+
if (seg.color === SET_STRIP_VARIABLE_COLOR) return "set-strip-variable";
|
|
383
|
+
return seg.color === TODO_COLOR ? "set-strip-empty" : "set-strip-fill";
|
|
384
|
+
}
|
|
385
|
+
function SetBar({ set, height = 8 }) {
|
|
386
|
+
return /* @__PURE__ */ jsx(
|
|
387
|
+
SegmentedBar,
|
|
388
|
+
{
|
|
389
|
+
segments: setSegments(set),
|
|
390
|
+
height,
|
|
391
|
+
gap: 0,
|
|
392
|
+
radius: 0,
|
|
393
|
+
segmentTestID: setBarSegmentTestID,
|
|
394
|
+
style: { flex: 1, minWidth: 0, borderRadius: 2, overflow: "hidden" },
|
|
395
|
+
testID: "set-strip-set"
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/components/custom/Workout/SetStrip.tsx
|
|
401
|
+
var SET_STRIP_GAP = 5;
|
|
402
|
+
function setCategory(set) {
|
|
403
|
+
switch (set.status) {
|
|
404
|
+
case "done":
|
|
405
|
+
case "drop":
|
|
406
|
+
case "myo":
|
|
407
|
+
return "done";
|
|
408
|
+
case "active":
|
|
409
|
+
return "active";
|
|
410
|
+
case "range":
|
|
411
|
+
return set.doneVels.length > 0 ? "active" : "upcoming";
|
|
412
|
+
case "todo":
|
|
413
|
+
case "myo-upcoming":
|
|
414
|
+
return "upcoming";
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
function describeSets(sets) {
|
|
418
|
+
const done = sets.filter((s) => setCategory(s) === "done").length;
|
|
419
|
+
const active = sets.filter((s) => setCategory(s) === "active").length;
|
|
420
|
+
const upcoming = sets.filter((s) => setCategory(s) === "upcoming").length;
|
|
421
|
+
return `Set progress: ${done} done, ${active} in progress, ${upcoming} upcoming`;
|
|
422
|
+
}
|
|
423
|
+
function SetStrip({ sets, height = 8, className, ...props }) {
|
|
424
|
+
return /* @__PURE__ */ jsx(
|
|
425
|
+
View,
|
|
426
|
+
{
|
|
427
|
+
className,
|
|
428
|
+
style: { flexDirection: "row", width: "100%", height, gap: SET_STRIP_GAP },
|
|
429
|
+
accessibilityRole: "image",
|
|
430
|
+
accessibilityLabel: describeSets(sets),
|
|
431
|
+
testID: "set-strip",
|
|
432
|
+
...props,
|
|
433
|
+
children: sets.map((set, i) => /* @__PURE__ */ jsx(SetBar, { set, height }, i))
|
|
434
|
+
}
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
|
|
67
438
|
// src/components/custom/Workout/VelocityStrip.tsx
|
|
68
439
|
var VEL_COLORS = WORKOUT_TOKENS.scale;
|
|
69
|
-
var
|
|
70
|
-
speed:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
440
|
+
var bandIdToEffortColor = {
|
|
441
|
+
speed: sequentialEffort[0],
|
|
442
|
+
// green-300
|
|
443
|
+
power: sequentialEffort[2],
|
|
444
|
+
// amber-300 (gold)
|
|
445
|
+
strengthSpeed: sequentialEffort[3],
|
|
446
|
+
// orange-400
|
|
447
|
+
maximalStrength: sequentialEffort[4],
|
|
448
|
+
// red-600
|
|
449
|
+
grinding: sequentialEffort[5]
|
|
450
|
+
// red-700 — the distinct 5th band
|
|
75
451
|
};
|
|
76
452
|
function getVelocityZoneColor(velocity) {
|
|
77
453
|
if (velocity >= 1) return "vel-green";
|
|
@@ -110,14 +486,132 @@ function classifyBand(velocity, bands) {
|
|
|
110
486
|
return bands[bands.length - 1];
|
|
111
487
|
}
|
|
112
488
|
function bandColor(band) {
|
|
113
|
-
|
|
114
|
-
return token ? VEL_COLORS[token] : VEL_COLORS.green;
|
|
489
|
+
return bandIdToEffortColor[band.id] ?? VEL_COLORS.green;
|
|
115
490
|
}
|
|
116
491
|
function getLossStyle(loss) {
|
|
117
492
|
if (loss > 25) return { color: VEL_COLORS.red };
|
|
118
493
|
if (loss > 20) return { color: VEL_COLORS.orange };
|
|
119
494
|
return null;
|
|
120
495
|
}
|
|
496
|
+
var REP_GAP = 2;
|
|
497
|
+
var WIDE_GAP = 8;
|
|
498
|
+
var TODO_COLOR2 = primitiveColors.charcoal[300];
|
|
499
|
+
var CONTINUE_OUTLINE = primitiveRamps.cyan[800];
|
|
500
|
+
function deriveDoneVelocities(set) {
|
|
501
|
+
switch (set.type) {
|
|
502
|
+
case "drop":
|
|
503
|
+
return set.subloads.flat();
|
|
504
|
+
case "myo":
|
|
505
|
+
return [...set.activation, ...set.clusters.flat()];
|
|
506
|
+
default:
|
|
507
|
+
return set.velocities;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function chunkedRepSlots(chunks) {
|
|
511
|
+
const slots = [];
|
|
512
|
+
chunks.forEach((chunk) => {
|
|
513
|
+
chunk.forEach((velocity, ri) => {
|
|
514
|
+
const first = slots.length === 0;
|
|
515
|
+
slots.push({ kind: "rep", velocity, leadingGap: first ? 0 : ri === 0 ? WIDE_GAP : REP_GAP });
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
return slots;
|
|
519
|
+
}
|
|
520
|
+
function buildSlots(set) {
|
|
521
|
+
switch (set.type) {
|
|
522
|
+
case "straight": {
|
|
523
|
+
const total = Math.max(set.velocities.length, set.planned ?? set.velocities.length);
|
|
524
|
+
return Array.from({ length: total }, (_, i) => {
|
|
525
|
+
const done = i < set.velocities.length;
|
|
526
|
+
return {
|
|
527
|
+
kind: done ? "rep" : "todo",
|
|
528
|
+
velocity: done ? set.velocities[i] : void 0,
|
|
529
|
+
leadingGap: i === 0 ? 0 : REP_GAP
|
|
530
|
+
};
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
case "range": {
|
|
534
|
+
const total = Math.max(set.max, set.velocities.length);
|
|
535
|
+
return Array.from({ length: total }, (_, i) => {
|
|
536
|
+
const kind = i < set.velocities.length ? "rep" : i < set.floor ? "todo" : "variable";
|
|
537
|
+
return {
|
|
538
|
+
kind,
|
|
539
|
+
velocity: kind === "rep" ? set.velocities[i] : void 0,
|
|
540
|
+
leadingGap: i === 0 ? 0 : REP_GAP
|
|
541
|
+
};
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
case "amrap": {
|
|
545
|
+
const reps = set.velocities.map((velocity, i) => ({
|
|
546
|
+
kind: "rep",
|
|
547
|
+
velocity,
|
|
548
|
+
leadingGap: i === 0 ? 0 : REP_GAP
|
|
549
|
+
}));
|
|
550
|
+
reps.push({ kind: "continue", leadingGap: reps.length === 0 ? 0 : REP_GAP });
|
|
551
|
+
return reps;
|
|
552
|
+
}
|
|
553
|
+
case "drop":
|
|
554
|
+
return chunkedRepSlots(set.subloads);
|
|
555
|
+
case "myo": {
|
|
556
|
+
const slots = chunkedRepSlots([set.activation, ...set.clusters]);
|
|
557
|
+
if (set.open) slots.push({ kind: "continue", leadingGap: slots.length === 0 ? 0 : REP_GAP });
|
|
558
|
+
return slots;
|
|
559
|
+
}
|
|
560
|
+
case "cluster": {
|
|
561
|
+
const total = Math.max(set.velocities.length, set.planned ?? set.velocities.length);
|
|
562
|
+
return Array.from({ length: total }, (_, i) => {
|
|
563
|
+
const done = i < set.velocities.length;
|
|
564
|
+
const boundary = i > 0 && i % set.groupSize === 0;
|
|
565
|
+
return {
|
|
566
|
+
kind: done ? "rep" : "todo",
|
|
567
|
+
velocity: done ? set.velocities[i] : void 0,
|
|
568
|
+
leadingGap: i === 0 ? 0 : boundary ? WIDE_GAP : REP_GAP
|
|
569
|
+
};
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
function setAccessibilityLabel(set, repCount) {
|
|
575
|
+
switch (set.type) {
|
|
576
|
+
case "straight":
|
|
577
|
+
return `Velocity strip, straight set, ${repCount} reps`;
|
|
578
|
+
case "range":
|
|
579
|
+
return `Velocity strip, rep-range set, floor ${set.floor} to ${set.max}, ${repCount} reps done`;
|
|
580
|
+
case "amrap":
|
|
581
|
+
return `Velocity strip, AMRAP set, ${repCount} reps and counting`;
|
|
582
|
+
case "drop":
|
|
583
|
+
return `Velocity strip, drop set, ${set.subloads.length} loads, ${repCount} reps`;
|
|
584
|
+
case "myo":
|
|
585
|
+
return `Velocity strip, myo-reps set, ${set.clusters.length} clusters${set.open ? ", open" : ""}, ${repCount} reps`;
|
|
586
|
+
case "cluster":
|
|
587
|
+
return `Velocity strip, cluster set, groups of ${set.groupSize}, ${repCount} reps`;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function slotAccessibilityLabel(slot, index) {
|
|
591
|
+
switch (slot.kind) {
|
|
592
|
+
case "rep":
|
|
593
|
+
return `Rep ${index + 1}: ${formatVelocity(slot.velocity ?? 0)} meters per second`;
|
|
594
|
+
case "todo":
|
|
595
|
+
return `Rep ${index + 1}: planned`;
|
|
596
|
+
case "variable":
|
|
597
|
+
return `Rep ${index + 1}: variable`;
|
|
598
|
+
case "continue":
|
|
599
|
+
return "Keep going";
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
var EXPANDED_TODO_STUB_PCT = 16;
|
|
603
|
+
var EXPANDED_ENCODED_PCT = 45;
|
|
604
|
+
var EXPANDED_HEIGHT = 60;
|
|
605
|
+
var FIXED_MAX_VELOCITY = 1.15;
|
|
606
|
+
var BARE_STUB_HEIGHT = 3;
|
|
607
|
+
function scaleDenominator(scale, maxVelocity) {
|
|
608
|
+
return scale === "fixed" ? FIXED_MAX_VELOCITY : maxVelocity * 1.15;
|
|
609
|
+
}
|
|
610
|
+
function bareSlotHeight(slot, height, denom) {
|
|
611
|
+
if (slot.kind !== "rep" || denom <= 0) return BARE_STUB_HEIGHT;
|
|
612
|
+
const ratio = Math.min(1, (slot.velocity ?? 0) / denom);
|
|
613
|
+
return Math.max(BARE_STUB_HEIGHT, ratio * height);
|
|
614
|
+
}
|
|
121
615
|
function getReducedMotionPreference() {
|
|
122
616
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
123
617
|
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
@@ -139,31 +633,48 @@ var ANIMATION_EASING = Easing.bezier(0.22, 1, 0.36, 1);
|
|
|
139
633
|
var POP_EASING = Easing.bezier(0.34, 1.56, 0.64, 1);
|
|
140
634
|
function VelocityStrip({
|
|
141
635
|
velocities,
|
|
636
|
+
set,
|
|
142
637
|
zones,
|
|
143
638
|
liveRepIndex,
|
|
144
|
-
expanded =
|
|
639
|
+
expanded = true,
|
|
145
640
|
onToggle,
|
|
146
641
|
onRepPress,
|
|
147
|
-
variant = "
|
|
642
|
+
variant = "expanded",
|
|
643
|
+
height = EXPANDED_HEIGHT,
|
|
644
|
+
scale = "peak",
|
|
645
|
+
showNumbers = true,
|
|
148
646
|
showInfo = true,
|
|
149
647
|
className,
|
|
150
648
|
...props
|
|
151
649
|
}) {
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
|
|
650
|
+
const doneVelocities = set ? deriveDoneVelocities(set) : velocities ?? [];
|
|
651
|
+
const slots = set ? buildSlots(set) : doneVelocities.map((v, i) => ({
|
|
652
|
+
kind: "rep",
|
|
653
|
+
velocity: v,
|
|
654
|
+
leadingGap: i === 0 ? 0 : REP_GAP
|
|
655
|
+
}));
|
|
656
|
+
const maxVelocity = Math.max(...doneVelocities, 0);
|
|
657
|
+
const meanVelocity = calculateMeanVelocity(doneVelocities);
|
|
658
|
+
const loss = calculateVelocityLoss(doneVelocities);
|
|
659
|
+
const framed = showNumbers || showInfo;
|
|
660
|
+
const scaleDenom = scaleDenominator(scale, maxVelocity);
|
|
155
661
|
const hasZones = zones != null && zones.length > 0;
|
|
156
662
|
const barColorFor = (v) => hasZones ? bandColor(classifyBand(v, zones)) : zoneHexMap[getVelocityZoneColor(v)];
|
|
663
|
+
const slotColor = (slot) => {
|
|
664
|
+
if (slot.kind === "rep") return barColorFor(slot.velocity ?? 0);
|
|
665
|
+
if (slot.kind === "todo") return TODO_COLOR2;
|
|
666
|
+
return SET_STRIP_VARIABLE_COLOR;
|
|
667
|
+
};
|
|
157
668
|
const meanZone = hasZones ? classifyBand(meanVelocity, zones)?.label ?? "" : getVelocityZoneName(meanVelocity);
|
|
158
669
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
159
|
-
const [heightAnim] = useState(() => new Animated.Value(expanded ?
|
|
670
|
+
const [heightAnim] = useState(() => new Animated.Value(expanded ? height : 3));
|
|
160
671
|
const [labelOpacity] = useState(() => new Animated.Value(expanded ? 1 : 0));
|
|
161
672
|
const [infoOpacity] = useState(() => new Animated.Value(expanded ? 1 : 0));
|
|
162
673
|
const [liveScale] = useState(() => new Animated.Value(1));
|
|
163
|
-
const liveVelocity = liveRepIndex != null ?
|
|
674
|
+
const liveVelocity = liveRepIndex != null ? doneVelocities[liveRepIndex] : void 0;
|
|
164
675
|
const isNewPeak = liveVelocity != null && maxVelocity > 0 && liveVelocity === maxVelocity;
|
|
165
676
|
useEffect(() => {
|
|
166
|
-
if (variant
|
|
677
|
+
if (variant !== "expanded" || !framed || liveRepIndex == null || liveVelocity == null) return;
|
|
167
678
|
if (prefersReducedMotion) {
|
|
168
679
|
liveScale.setValue(1);
|
|
169
680
|
return;
|
|
@@ -193,12 +704,12 @@ function VelocityStrip({
|
|
|
193
704
|
useNativeDriver: true
|
|
194
705
|
}).start();
|
|
195
706
|
}
|
|
196
|
-
}, [variant, liveRepIndex, liveVelocity, isNewPeak, prefersReducedMotion, liveScale]);
|
|
707
|
+
}, [variant, framed, liveRepIndex, liveVelocity, isNewPeak, prefersReducedMotion, liveScale]);
|
|
197
708
|
useEffect(() => {
|
|
198
|
-
if (variant
|
|
709
|
+
if (variant !== "expanded" || !framed) return;
|
|
199
710
|
Animated.parallel([
|
|
200
711
|
Animated.timing(heightAnim, {
|
|
201
|
-
toValue: expanded ?
|
|
712
|
+
toValue: expanded ? height : 3,
|
|
202
713
|
duration: ANIMATION_DURATION,
|
|
203
714
|
easing: ANIMATION_EASING,
|
|
204
715
|
useNativeDriver: false
|
|
@@ -216,39 +727,118 @@ function VelocityStrip({
|
|
|
216
727
|
useNativeDriver: false
|
|
217
728
|
})
|
|
218
729
|
]).start();
|
|
219
|
-
}, [expanded, variant, heightAnim, labelOpacity, infoOpacity]);
|
|
730
|
+
}, [expanded, variant, framed, height, heightAnim, labelOpacity, infoOpacity]);
|
|
731
|
+
if (set == null && velocities == null) return null;
|
|
732
|
+
const repCount = doneVelocities.length;
|
|
733
|
+
const miniLabel = set ? setAccessibilityLabel(set, repCount) : `Velocity strip, ${repCount} reps`;
|
|
220
734
|
if (variant === "mini") {
|
|
221
735
|
const { style: externalStyle, ...restProps } = props;
|
|
222
736
|
return /* @__PURE__ */ jsx(
|
|
223
737
|
View,
|
|
224
738
|
{
|
|
225
739
|
className,
|
|
226
|
-
style: [
|
|
740
|
+
style: [
|
|
741
|
+
{ flexDirection: "row", height: 3, gap: REP_GAP, borderRadius: 2, overflow: "hidden" },
|
|
742
|
+
externalStyle
|
|
743
|
+
],
|
|
227
744
|
accessibilityRole: "image",
|
|
228
|
-
accessibilityLabel:
|
|
745
|
+
accessibilityLabel: miniLabel,
|
|
229
746
|
testID: "velocity-strip-mini",
|
|
230
747
|
...restProps,
|
|
231
|
-
children:
|
|
748
|
+
children: slots.map((slot, i) => /* @__PURE__ */ jsx(
|
|
232
749
|
View,
|
|
233
750
|
{
|
|
234
751
|
style: {
|
|
235
752
|
flex: 1,
|
|
236
|
-
backgroundColor:
|
|
753
|
+
backgroundColor: slotColor(slot),
|
|
237
754
|
borderRadius: 1,
|
|
238
755
|
minWidth: 4,
|
|
239
|
-
height: "100%"
|
|
756
|
+
height: "100%",
|
|
757
|
+
// The container's uniform 2px gap covers rep spacing; a wide slot adds
|
|
758
|
+
// only the EXTRA (WIDE_GAP − REP_GAP) so the notch totals WIDE_GAP.
|
|
759
|
+
marginLeft: Math.max(0, slot.leadingGap - REP_GAP),
|
|
760
|
+
...slot.kind === "continue" ? { borderWidth: 1, borderColor: CONTINUE_OUTLINE } : {}
|
|
761
|
+
},
|
|
762
|
+
accessibilityElementsHidden: true,
|
|
763
|
+
testID: slot.kind === "rep" ? `velocity-bar-${i}` : `velocity-slot-${slot.kind}`
|
|
764
|
+
},
|
|
765
|
+
i
|
|
766
|
+
))
|
|
767
|
+
}
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
if (!framed) {
|
|
771
|
+
const { style: externalStyle, ...restProps } = props;
|
|
772
|
+
return /* @__PURE__ */ jsx(
|
|
773
|
+
View,
|
|
774
|
+
{
|
|
775
|
+
className,
|
|
776
|
+
style: [
|
|
777
|
+
{ flexDirection: "row", height, gap: REP_GAP, alignItems: "flex-end" },
|
|
778
|
+
externalStyle
|
|
779
|
+
],
|
|
780
|
+
accessibilityRole: "image",
|
|
781
|
+
accessibilityLabel: miniLabel,
|
|
782
|
+
testID: "velocity-strip-compact",
|
|
783
|
+
...restProps,
|
|
784
|
+
children: slots.map((slot, i) => /* @__PURE__ */ jsx(
|
|
785
|
+
View,
|
|
786
|
+
{
|
|
787
|
+
style: {
|
|
788
|
+
flex: 1,
|
|
789
|
+
minWidth: 4,
|
|
790
|
+
height: bareSlotHeight(slot, height, scaleDenom),
|
|
791
|
+
// Top-rounded to match the framed chart's bars (the "rounded tops from
|
|
792
|
+
// the numbers one"); square bottoms since bars sit on the baseline.
|
|
793
|
+
borderTopLeftRadius: 2,
|
|
794
|
+
borderTopRightRadius: 2,
|
|
795
|
+
backgroundColor: slotColor(slot),
|
|
796
|
+
marginLeft: Math.max(0, slot.leadingGap - REP_GAP),
|
|
797
|
+
...slot.kind === "continue" ? { borderWidth: 1, borderColor: CONTINUE_OUTLINE } : {}
|
|
240
798
|
},
|
|
241
799
|
accessibilityElementsHidden: true,
|
|
242
|
-
testID: `velocity-bar-${i}`
|
|
800
|
+
testID: slot.kind === "rep" ? `velocity-bar-${i}` : `velocity-slot-${slot.kind}`
|
|
243
801
|
},
|
|
244
802
|
i
|
|
245
803
|
))
|
|
246
804
|
}
|
|
247
805
|
);
|
|
248
806
|
}
|
|
249
|
-
const stripLabel = `Velocity chart for set, ${
|
|
807
|
+
const stripLabel = set ? `${setAccessibilityLabel(set, repCount)}, tap to ${expanded ? "collapse" : "expand"}` : `Velocity chart for set, ${repCount} reps, tap to ${expanded ? "collapse" : "expand"}`;
|
|
250
808
|
const hasInteractiveContainer = onToggle != null;
|
|
251
809
|
const hasInteractiveReps = onRepPress != null && expanded;
|
|
810
|
+
const setBars = set != null && slots.map((slot, i) => {
|
|
811
|
+
const isStraightRep = set.type === "straight" && slot.kind === "rep";
|
|
812
|
+
const heightPct = isStraightRep ? scaleDenom > 0 ? Math.round((slot.velocity ?? 0) / scaleDenom * 100) : 0 : set.type === "straight" ? EXPANDED_TODO_STUB_PCT : EXPANDED_ENCODED_PCT;
|
|
813
|
+
return /* @__PURE__ */ jsx(
|
|
814
|
+
View,
|
|
815
|
+
{
|
|
816
|
+
style: {
|
|
817
|
+
flex: 1,
|
|
818
|
+
height: "100%",
|
|
819
|
+
justifyContent: "flex-end",
|
|
820
|
+
marginLeft: slot.leadingGap
|
|
821
|
+
},
|
|
822
|
+
children: /* @__PURE__ */ jsx(
|
|
823
|
+
View,
|
|
824
|
+
{
|
|
825
|
+
style: {
|
|
826
|
+
height: `${heightPct}%`,
|
|
827
|
+
minHeight: 2,
|
|
828
|
+
borderTopLeftRadius: 2,
|
|
829
|
+
borderTopRightRadius: 2,
|
|
830
|
+
backgroundColor: slotColor(slot),
|
|
831
|
+
...slot.kind === "continue" ? { borderWidth: 1, borderColor: CONTINUE_OUTLINE } : {}
|
|
832
|
+
},
|
|
833
|
+
testID: slot.kind === "rep" ? `velocity-bar-${i}` : `velocity-slot-${slot.kind}`,
|
|
834
|
+
accessibilityRole: "image",
|
|
835
|
+
accessibilityLabel: slotAccessibilityLabel(slot, i)
|
|
836
|
+
}
|
|
837
|
+
)
|
|
838
|
+
},
|
|
839
|
+
i
|
|
840
|
+
);
|
|
841
|
+
});
|
|
252
842
|
const stripContent = /* @__PURE__ */ jsxs(
|
|
253
843
|
Animated.View,
|
|
254
844
|
{
|
|
@@ -261,7 +851,9 @@ function VelocityStrip({
|
|
|
261
851
|
borderRadius: expanded ? 6 : 2,
|
|
262
852
|
paddingTop: expanded ? 16 : 0,
|
|
263
853
|
paddingBottom: expanded ? 24 : 0,
|
|
264
|
-
|
|
854
|
+
// No horizontal inset — the framed chart's bars span full width, matching
|
|
855
|
+
// the bare spotlight and mini. Numbers/info sit in the vertical padding.
|
|
856
|
+
paddingHorizontal: 0,
|
|
265
857
|
paddingVertical: expanded ? void 0 : 8,
|
|
266
858
|
overflow: expanded ? "visible" : "hidden"
|
|
267
859
|
}
|
|
@@ -271,46 +863,65 @@ function VelocityStrip({
|
|
|
271
863
|
testID: "velocity-strip",
|
|
272
864
|
...props,
|
|
273
865
|
children: [
|
|
274
|
-
/* @__PURE__ */ jsx(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
)
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
866
|
+
/* @__PURE__ */ jsx(View, { style: { flexDirection: "row", flex: 1, gap: set ? 0 : 2, alignItems: "flex-end" }, children: set ? setBars : doneVelocities.map((v, i) => {
|
|
867
|
+
const barBackground = barColorFor(v);
|
|
868
|
+
const barHeightPct = scaleDenom > 0 ? Math.round(v / scaleDenom * 100) : 0;
|
|
869
|
+
const isLive = liveRepIndex === i;
|
|
870
|
+
const liveLabelSuffix = isLive ? isNewPeak ? ", latest rep, new set peak" : ", latest rep" : "";
|
|
871
|
+
const barStyle = expanded ? {
|
|
872
|
+
height: `${barHeightPct}%`,
|
|
873
|
+
minHeight: 2,
|
|
874
|
+
borderTopLeftRadius: 2,
|
|
875
|
+
borderTopRightRadius: 2,
|
|
876
|
+
backgroundColor: barBackground
|
|
877
|
+
} : {
|
|
878
|
+
minHeight: "100%",
|
|
879
|
+
borderTopLeftRadius: 2,
|
|
880
|
+
borderTopRightRadius: 2,
|
|
881
|
+
borderBottomLeftRadius: 0,
|
|
882
|
+
borderBottomRightRadius: 0,
|
|
883
|
+
backgroundColor: barBackground
|
|
884
|
+
};
|
|
885
|
+
const barInner = isLive ? /* @__PURE__ */ jsx(
|
|
886
|
+
Animated.View,
|
|
887
|
+
{
|
|
888
|
+
style: [barStyle, { transform: [{ scale: liveScale }] }],
|
|
889
|
+
testID: `velocity-bar-${i}`,
|
|
890
|
+
accessibilityRole: "image",
|
|
891
|
+
accessibilityLabel: `Rep ${i + 1}: ${formatVelocity(v)} meters per second${liveLabelSuffix}`
|
|
892
|
+
}
|
|
893
|
+
) : /* @__PURE__ */ jsx(
|
|
894
|
+
View,
|
|
895
|
+
{
|
|
896
|
+
style: barStyle,
|
|
897
|
+
testID: `velocity-bar-${i}`,
|
|
898
|
+
accessibilityRole: "image",
|
|
899
|
+
accessibilityLabel: `Rep ${i + 1}: ${formatVelocity(v)} meters per second`
|
|
900
|
+
}
|
|
901
|
+
);
|
|
902
|
+
const bar = /* @__PURE__ */ jsxs(
|
|
903
|
+
View,
|
|
904
|
+
{
|
|
905
|
+
style: {
|
|
906
|
+
flex: 1,
|
|
907
|
+
height: "100%",
|
|
908
|
+
justifyContent: "flex-end",
|
|
909
|
+
position: "relative"
|
|
910
|
+
},
|
|
911
|
+
children: [
|
|
912
|
+
expanded && showNumbers && /* @__PURE__ */ jsx(
|
|
913
|
+
Animated.View,
|
|
914
|
+
{
|
|
915
|
+
style: {
|
|
916
|
+
opacity: labelOpacity,
|
|
917
|
+
alignItems: "center",
|
|
918
|
+
position: "absolute",
|
|
919
|
+
top: -13,
|
|
920
|
+
left: 0,
|
|
921
|
+
right: 0
|
|
922
|
+
},
|
|
923
|
+
accessibilityElementsHidden: true,
|
|
924
|
+
children: /* @__PURE__ */ jsx(
|
|
314
925
|
Text,
|
|
315
926
|
{
|
|
316
927
|
className: "text-text-secondary",
|
|
@@ -318,30 +929,30 @@ function VelocityStrip({
|
|
|
318
929
|
testID: `velocity-label-${i}`,
|
|
319
930
|
children: formatVelocity(v)
|
|
320
931
|
}
|
|
321
|
-
)
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
})
|
|
932
|
+
)
|
|
933
|
+
}
|
|
934
|
+
),
|
|
935
|
+
barInner
|
|
936
|
+
]
|
|
937
|
+
},
|
|
938
|
+
i
|
|
939
|
+
);
|
|
940
|
+
if (onRepPress && expanded) {
|
|
941
|
+
return /* @__PURE__ */ jsx(
|
|
942
|
+
Pressable,
|
|
943
|
+
{
|
|
944
|
+
style: { flex: 1, height: "100%" },
|
|
945
|
+
onPress: () => onRepPress(i, v),
|
|
946
|
+
accessibilityRole: "button",
|
|
947
|
+
accessibilityLabel: `Rep ${i + 1}: ${formatVelocity(v)} meters per second, tap for details`,
|
|
948
|
+
testID: `velocity-bar-pressable-${i}`,
|
|
949
|
+
children: bar
|
|
950
|
+
},
|
|
951
|
+
i
|
|
952
|
+
);
|
|
343
953
|
}
|
|
344
|
-
|
|
954
|
+
return bar;
|
|
955
|
+
}) }),
|
|
345
956
|
expanded && showInfo && /* @__PURE__ */ jsxs(
|
|
346
957
|
Animated.View,
|
|
347
958
|
{
|
|
@@ -487,12 +1098,14 @@ function PlaceholderStrip({
|
|
|
487
1098
|
return /* @__PURE__ */ jsx(SingleStrip, { ...props });
|
|
488
1099
|
}
|
|
489
1100
|
|
|
490
|
-
// src/components/
|
|
491
|
-
function
|
|
1101
|
+
// src/components/icons/SvgIcon.tsx
|
|
1102
|
+
function SvgIcon({
|
|
492
1103
|
size = 24,
|
|
493
1104
|
color = "currentColor",
|
|
1105
|
+
strokeWidth = 2,
|
|
494
1106
|
fill = "none",
|
|
495
|
-
|
|
1107
|
+
title,
|
|
1108
|
+
children
|
|
496
1109
|
}) {
|
|
497
1110
|
return /* @__PURE__ */ jsxs(
|
|
498
1111
|
"svg",
|
|
@@ -505,36 +1118,59 @@ function DumbbellIcon({
|
|
|
505
1118
|
strokeWidth,
|
|
506
1119
|
strokeLinecap: "round",
|
|
507
1120
|
strokeLinejoin: "round",
|
|
1121
|
+
...title ? { role: "img", "aria-label": title } : { "aria-hidden": true },
|
|
508
1122
|
children: [
|
|
509
|
-
/* @__PURE__ */ jsx("
|
|
510
|
-
|
|
511
|
-
/* @__PURE__ */ jsx("path", { d: "m21.5 21.5-1.4-1.4" }),
|
|
512
|
-
/* @__PURE__ */ jsx("path", { d: "M3.9 3.9 2.5 2.5" }),
|
|
513
|
-
/* @__PURE__ */ jsx("path", { d: "M6.404 12.768a2 2 0 1 1-2.829-2.829l1.768-1.767a2 2 0 1 1-2.828-2.829l2.828-2.828a2 2 0 1 1 2.829 2.828l1.767-1.768a2 2 0 1 1 2.829 2.829z" })
|
|
1123
|
+
title ? /* @__PURE__ */ jsx("title", { children: title }) : null,
|
|
1124
|
+
children
|
|
514
1125
|
]
|
|
515
1126
|
}
|
|
516
1127
|
);
|
|
517
1128
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
return /* @__PURE__ */
|
|
525
|
-
"
|
|
526
|
-
{
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}
|
|
537
|
-
);
|
|
1129
|
+
|
|
1130
|
+
// src/components/icons/icons.tsx
|
|
1131
|
+
function StarIcon(props) {
|
|
1132
|
+
return /* @__PURE__ */ jsx(SvgIcon, { ...props, children: /* @__PURE__ */ jsx("path", { d: "M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z" }) });
|
|
1133
|
+
}
|
|
1134
|
+
function ScaleIcon(props) {
|
|
1135
|
+
return /* @__PURE__ */ jsxs(SvgIcon, { ...props, children: [
|
|
1136
|
+
/* @__PURE__ */ jsx("path", { d: "m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" }),
|
|
1137
|
+
/* @__PURE__ */ jsx("path", { d: "m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z" }),
|
|
1138
|
+
/* @__PURE__ */ jsx("path", { d: "M7 21h10" }),
|
|
1139
|
+
/* @__PURE__ */ jsx("path", { d: "M12 3v18" }),
|
|
1140
|
+
/* @__PURE__ */ jsx("path", { d: "M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2" })
|
|
1141
|
+
] });
|
|
1142
|
+
}
|
|
1143
|
+
function AlertTriangleIcon(props) {
|
|
1144
|
+
return /* @__PURE__ */ jsxs(SvgIcon, { ...props, children: [
|
|
1145
|
+
/* @__PURE__ */ jsx("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" }),
|
|
1146
|
+
/* @__PURE__ */ jsx("path", { d: "M12 9v4" }),
|
|
1147
|
+
/* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
|
|
1148
|
+
] });
|
|
1149
|
+
}
|
|
1150
|
+
function TrendingDownIcon(props) {
|
|
1151
|
+
return /* @__PURE__ */ jsxs(SvgIcon, { ...props, children: [
|
|
1152
|
+
/* @__PURE__ */ jsx("path", { d: "M16 17h6v-6" }),
|
|
1153
|
+
/* @__PURE__ */ jsx("path", { d: "m22 17-8.5-8.5-5 5L2 7" })
|
|
1154
|
+
] });
|
|
1155
|
+
}
|
|
1156
|
+
function CircleSlashIcon(props) {
|
|
1157
|
+
return /* @__PURE__ */ jsxs(SvgIcon, { ...props, children: [
|
|
1158
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1159
|
+
/* @__PURE__ */ jsx("path", { d: "m9 15 6-6" })
|
|
1160
|
+
] });
|
|
1161
|
+
}
|
|
1162
|
+
function AwardIcon(props) {
|
|
1163
|
+
return /* @__PURE__ */ jsxs(SvgIcon, { ...props, children: [
|
|
1164
|
+
/* @__PURE__ */ jsx("path", { d: "m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526" }),
|
|
1165
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "8", r: "6" })
|
|
1166
|
+
] });
|
|
1167
|
+
}
|
|
1168
|
+
function InfoIcon(props) {
|
|
1169
|
+
return /* @__PURE__ */ jsxs(SvgIcon, { ...props, children: [
|
|
1170
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1171
|
+
/* @__PURE__ */ jsx("path", { d: "M12 16v-4" }),
|
|
1172
|
+
/* @__PURE__ */ jsx("path", { d: "M12 8h.01" })
|
|
1173
|
+
] });
|
|
538
1174
|
}
|
|
539
1175
|
var baseBadgeSizeConfig = {
|
|
540
1176
|
sm: { fontSize: 9, paddingH: 6, paddingV: 2, iconSize: 10 },
|
|
@@ -614,105 +1250,286 @@ function BaseBadge({
|
|
|
614
1250
|
return badge;
|
|
615
1251
|
}
|
|
616
1252
|
|
|
617
|
-
// src/
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
1253
|
+
// src/theme/tokens/semantic.ts
|
|
1254
|
+
var semanticColorsLight = {
|
|
1255
|
+
// Brand colors (brand-*)
|
|
1256
|
+
"brand-primary": primitiveRamps.orange[400],
|
|
1257
|
+
"brand-primary-light": primitiveRamps.orange[300],
|
|
1258
|
+
"brand-primary-dark": primitiveRamps.orange[500],
|
|
1259
|
+
"brand-primary-subtle": "rgba(255, 121, 0, 0.08)",
|
|
1260
|
+
"brand-primary-hover": primitiveRamps.orange[500],
|
|
1261
|
+
"brand-primary-active": primitiveRamps.orange[600],
|
|
1262
|
+
"brand-secondary": primitiveRamps.cyan[600],
|
|
1263
|
+
"brand-secondary-light": primitiveRamps.cyan[500],
|
|
1264
|
+
"brand-secondary-dark": primitiveRamps.cyan[700],
|
|
1265
|
+
"brand-secondary-subtle": "rgba(48, 123, 155, 0.08)",
|
|
1266
|
+
"brand-secondary-hover": primitiveRamps.cyan[700],
|
|
1267
|
+
"brand-secondary-active": primitiveRamps.cyan[800],
|
|
1268
|
+
// Text on brand backgrounds (on-*)
|
|
1269
|
+
"on-brand-primary": primitiveColors.white,
|
|
1270
|
+
"on-brand-secondary": primitiveColors.white,
|
|
1271
|
+
// Status colors (status-*)
|
|
1272
|
+
"status-success": primitiveRamps.green[300],
|
|
1273
|
+
"status-success-light": primitiveRamps.green[200],
|
|
1274
|
+
"status-success-dark": primitiveRamps.green[600],
|
|
1275
|
+
"status-success-subtle": primitiveRamps.green[50],
|
|
1276
|
+
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
1277
|
+
"status-live": primitiveRamps.green[300],
|
|
1278
|
+
"status-live-muted": primitiveRamps.green[500],
|
|
1279
|
+
"status-error": primitiveRamps.red[600],
|
|
1280
|
+
"status-error-light": primitiveRamps.red[500],
|
|
1281
|
+
"status-error-dark": primitiveRamps.red[700],
|
|
1282
|
+
"status-error-subtle": primitiveRamps.red[50],
|
|
1283
|
+
"status-error-vivid": primitiveColors.redVivid[500],
|
|
1284
|
+
// vivid alert red
|
|
1285
|
+
"status-error-vivid-light": primitiveColors.redVivid[400],
|
|
1286
|
+
"status-error-vivid-dark": primitiveColors.redVivid[700],
|
|
1287
|
+
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
1288
|
+
"status-warning": primitiveRamps.amber[300],
|
|
1289
|
+
"status-warning-light": primitiveRamps.amber[200],
|
|
1290
|
+
"status-warning-dark": primitiveRamps.amber[500],
|
|
1291
|
+
"status-warning-subtle": primitiveRamps.amber[50],
|
|
1292
|
+
"status-info": primitiveRamps.blue[500],
|
|
1293
|
+
"status-info-light": primitiveRamps.blue[300],
|
|
1294
|
+
"status-info-dark": primitiveRamps.blue[600],
|
|
1295
|
+
"status-info-subtle": primitiveRamps.blue[50],
|
|
1296
|
+
// Text on status backgrounds (on-status-*)
|
|
1297
|
+
"on-status-success": primitiveColors.white,
|
|
1298
|
+
"on-status-error": primitiveColors.white,
|
|
1299
|
+
"on-status-warning": primitiveColors.white,
|
|
1300
|
+
"on-status-info": primitiveColors.white,
|
|
1301
|
+
// Result/outcome indicators (result-*)
|
|
1302
|
+
"result-improve": "#4caf50",
|
|
1303
|
+
// Green - positive outcome
|
|
1304
|
+
"result-improve-light": "rgba(76, 175, 80, 0.12)",
|
|
1305
|
+
"result-improve-dark": "#248a24",
|
|
1306
|
+
"result-degrade": "#ef5350",
|
|
1307
|
+
// Red - negative outcome
|
|
1308
|
+
"result-degrade-light": "rgba(239, 83, 80, 0.12)",
|
|
1309
|
+
"result-degrade-dark": "#b30000",
|
|
1310
|
+
"result-inconclusive": "#9E9A97",
|
|
1311
|
+
// Gray - no clear result
|
|
1312
|
+
"result-inconclusive-light": "rgba(158, 154, 151, 0.12)",
|
|
1313
|
+
"result-neutral": primitiveColors.neutral[500],
|
|
1314
|
+
// Neutral baseline
|
|
1315
|
+
// Text on result backgrounds (on-result-*)
|
|
1316
|
+
"on-result-improve": primitiveColors.white,
|
|
1317
|
+
"on-result-degrade": primitiveColors.white,
|
|
1318
|
+
"on-result-inconclusive": primitiveColors.white,
|
|
1319
|
+
// Data visualization colors (data-*)
|
|
1320
|
+
// First 10 colors from discrete rainbow optimized for charts
|
|
1321
|
+
"data-1": discreteRainbow[9],
|
|
1322
|
+
// Blue
|
|
1323
|
+
"data-2": discreteRainbow[14],
|
|
1324
|
+
// Green
|
|
1325
|
+
"data-3": discreteRainbow[17],
|
|
1326
|
+
// Yellow
|
|
1327
|
+
"data-4": discreteRainbow[25],
|
|
1328
|
+
// Red
|
|
1329
|
+
"data-5": discreteRainbow[8],
|
|
1330
|
+
// Purple
|
|
1331
|
+
"data-6": discreteRainbow[20],
|
|
1332
|
+
// Orange
|
|
1333
|
+
"data-7": discreteRainbow[13],
|
|
1334
|
+
// Light Blue
|
|
1335
|
+
"data-8": discreteRainbow[15],
|
|
1336
|
+
// Light Green
|
|
1337
|
+
"data-9": discreteRainbow[3],
|
|
1338
|
+
// Lavender
|
|
1339
|
+
"data-10": discreteRainbow[22],
|
|
1340
|
+
// Dark Orange
|
|
1341
|
+
// Text colors (text-*)
|
|
1342
|
+
"text-primary": "#121828",
|
|
1343
|
+
"text-secondary": "#65748B",
|
|
1344
|
+
"text-tertiary": primitiveColors.neutral[400],
|
|
1345
|
+
"text-disabled": "rgba(55, 65, 81, 0.48)",
|
|
1346
|
+
"text-inverse": primitiveColors.white,
|
|
1347
|
+
"text-link": primitiveColors.blue[600],
|
|
1348
|
+
"text-link-hover": primitiveColors.blue[700],
|
|
1349
|
+
// Surface colors (surface-*) - for elevated containers
|
|
1350
|
+
"surface-base": primitiveColors.white,
|
|
1351
|
+
"surface-elevated": primitiveColors.neutral[50],
|
|
1352
|
+
// slightly off-white for elevated cards
|
|
1353
|
+
"surface-raised": primitiveColors.neutral[100],
|
|
1354
|
+
// light gray for raised cards
|
|
1355
|
+
"surface-overlay": primitiveColors.white,
|
|
1356
|
+
"surface-input": primitiveColors.neutral[50],
|
|
1357
|
+
// Input field background (filled variant)
|
|
1358
|
+
// Background colors (background-*)
|
|
1359
|
+
"background-base": "#EBEBEB",
|
|
1360
|
+
"background-default": primitiveColors.white,
|
|
1361
|
+
"background-subtle": primitiveColors.neutral[50],
|
|
1362
|
+
// Border colors (border-*)
|
|
1363
|
+
"border-default": "#E8E9EB",
|
|
1364
|
+
"border-subtle": primitiveColors.neutral[100],
|
|
1365
|
+
"border-strong": primitiveColors.neutral[300],
|
|
1366
|
+
"border-prominent": primitiveColors.neutral[400],
|
|
1367
|
+
// high-visibility divider
|
|
1368
|
+
"border-focus": primitiveColors.blue[600],
|
|
1369
|
+
"border-input": primitiveColors.neutral[300],
|
|
1370
|
+
// Input field border
|
|
1371
|
+
"border-input-hover": primitiveColors.neutral[400],
|
|
1372
|
+
// Input field border on hover
|
|
1373
|
+
"border-input-focus": primitiveColors.blue[600],
|
|
1374
|
+
// Input field border on focus
|
|
1375
|
+
"border-input-error": primitiveColors.red[600],
|
|
1376
|
+
// Input field border on error
|
|
1377
|
+
// Interactive states (interactive-*)
|
|
1378
|
+
"interactive-hover": "rgba(55, 65, 81, 0.04)",
|
|
1379
|
+
"interactive-focus": "rgba(55, 65, 81, 0.12)",
|
|
1380
|
+
"interactive-active": "rgba(55, 65, 81, 0.16)",
|
|
1381
|
+
"interactive-selected": "rgba(55, 65, 81, 0.08)",
|
|
1382
|
+
"interactive-disabled": "rgba(55, 65, 81, 0.12)",
|
|
1383
|
+
"interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
|
|
1384
|
+
// Divider
|
|
1385
|
+
"divider": "#E8E9EB",
|
|
1386
|
+
// Avatar default
|
|
1387
|
+
"avatar-background": primitiveColors.neutral[500],
|
|
1388
|
+
"avatar-text": primitiveColors.white
|
|
1389
|
+
};
|
|
1390
|
+
var semanticColorsDark = {
|
|
1391
|
+
// Brand colors stay the same in dark mode
|
|
1392
|
+
"brand-primary": primitiveRamps.orange[400],
|
|
1393
|
+
"brand-primary-light": primitiveRamps.orange[300],
|
|
1394
|
+
"brand-primary-dark": primitiveRamps.orange[500],
|
|
1395
|
+
"brand-primary-subtle": "rgba(255, 121, 0, 0.12)",
|
|
1396
|
+
"brand-primary-hover": primitiveRamps.orange[300],
|
|
1397
|
+
"brand-primary-active": primitiveRamps.orange[200],
|
|
1398
|
+
"brand-secondary": primitiveRamps.cyan[600],
|
|
1399
|
+
"brand-secondary-light": primitiveRamps.cyan[500],
|
|
1400
|
+
"brand-secondary-dark": primitiveRamps.cyan[700],
|
|
1401
|
+
"brand-secondary-subtle": "rgba(48, 123, 155, 0.12)",
|
|
1402
|
+
"brand-secondary-hover": primitiveRamps.cyan[500],
|
|
1403
|
+
"brand-secondary-active": primitiveRamps.cyan[400],
|
|
1404
|
+
// Text on brand backgrounds
|
|
1405
|
+
"on-brand-primary": primitiveColors.white,
|
|
1406
|
+
"on-brand-secondary": primitiveColors.white,
|
|
1407
|
+
// Status colors
|
|
1408
|
+
"status-success": primitiveRamps.green[300],
|
|
1409
|
+
"status-success-light": primitiveRamps.green[200],
|
|
1410
|
+
"status-success-dark": primitiveRamps.green[600],
|
|
1411
|
+
"status-success-subtle": "rgba(46, 213, 115, 0.12)",
|
|
1412
|
+
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
1413
|
+
"status-live": primitiveRamps.green[300],
|
|
1414
|
+
"status-live-muted": primitiveRamps.green[500],
|
|
1415
|
+
"status-error": primitiveRamps.red[600],
|
|
1416
|
+
"status-error-light": primitiveRamps.red[500],
|
|
1417
|
+
"status-error-dark": primitiveRamps.red[700],
|
|
1418
|
+
"status-error-subtle": "rgba(209, 67, 67, 0.12)",
|
|
1419
|
+
"status-error-vivid": primitiveColors.redVivid[500],
|
|
1420
|
+
"status-error-vivid-light": primitiveColors.redVivid[400],
|
|
1421
|
+
"status-error-vivid-dark": primitiveColors.redVivid[700],
|
|
1422
|
+
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
1423
|
+
"status-warning": primitiveRamps.amber[300],
|
|
1424
|
+
"status-warning-light": primitiveRamps.amber[200],
|
|
1425
|
+
"status-warning-dark": primitiveRamps.amber[500],
|
|
1426
|
+
"status-warning-subtle": "rgba(249, 180, 21, 0.12)",
|
|
1427
|
+
"status-info": primitiveRamps.blue[500],
|
|
1428
|
+
"status-info-light": primitiveRamps.blue[300],
|
|
1429
|
+
"status-info-dark": primitiveRamps.blue[600],
|
|
1430
|
+
"status-info-subtle": "rgba(33, 150, 243, 0.12)",
|
|
1431
|
+
// Text on status backgrounds
|
|
1432
|
+
"on-status-success": primitiveColors.white,
|
|
1433
|
+
"on-status-error": primitiveColors.white,
|
|
1434
|
+
"on-status-warning": primitiveColors.white,
|
|
1435
|
+
"on-status-info": primitiveColors.white,
|
|
1436
|
+
// Result/outcome indicators (result-*)
|
|
1437
|
+
"result-improve": "#4caf50",
|
|
1438
|
+
"result-improve-light": "rgba(76, 175, 80, 0.16)",
|
|
1439
|
+
"result-improve-dark": "#248a24",
|
|
1440
|
+
"result-degrade": "#ef5350",
|
|
1441
|
+
"result-degrade-light": "rgba(239, 83, 80, 0.16)",
|
|
1442
|
+
"result-degrade-dark": "#b30000",
|
|
1443
|
+
"result-inconclusive": "#9E9A97",
|
|
1444
|
+
"result-inconclusive-light": "rgba(158, 154, 151, 0.16)",
|
|
1445
|
+
"result-neutral": primitiveColors.neutral[400],
|
|
1446
|
+
// Text on result backgrounds
|
|
1447
|
+
"on-result-improve": primitiveColors.white,
|
|
1448
|
+
"on-result-degrade": primitiveColors.white,
|
|
1449
|
+
"on-result-inconclusive": primitiveColors.white,
|
|
1450
|
+
// Data visualization colors (same in dark mode for consistency)
|
|
1451
|
+
"data-1": discreteRainbow[9],
|
|
1452
|
+
"data-2": discreteRainbow[14],
|
|
1453
|
+
"data-3": discreteRainbow[17],
|
|
1454
|
+
"data-4": discreteRainbow[25],
|
|
1455
|
+
"data-5": discreteRainbow[8],
|
|
1456
|
+
"data-6": discreteRainbow[20],
|
|
1457
|
+
"data-7": discreteRainbow[13],
|
|
1458
|
+
"data-8": discreteRainbow[15],
|
|
1459
|
+
"data-9": discreteRainbow[3],
|
|
1460
|
+
"data-10": discreteRainbow[22],
|
|
1461
|
+
// Text colors - inverted for dark mode
|
|
1462
|
+
"text-primary": primitiveColors.neutral[100],
|
|
1463
|
+
"text-secondary": primitiveColors.neutral[400],
|
|
1464
|
+
"text-tertiary": primitiveColors.neutral[500],
|
|
1465
|
+
"text-disabled": "rgba(255, 255, 255, 0.38)",
|
|
1466
|
+
"text-inverse": primitiveColors.neutral[900],
|
|
1467
|
+
"text-link": "#828DF8",
|
|
1468
|
+
"text-link-hover": primitiveColors.blue[400],
|
|
1469
|
+
// Surface colors - dark backgrounds
|
|
1470
|
+
"surface-base": primitiveColors.charcoal[700],
|
|
1471
|
+
// main surface
|
|
1472
|
+
"surface-elevated": primitiveColors.charcoal[600],
|
|
1473
|
+
// elevated surface
|
|
1474
|
+
"surface-raised": primitiveColors.charcoal[500],
|
|
1475
|
+
// raised surface
|
|
1476
|
+
"surface-overlay": primitiveColors.charcoal[600],
|
|
1477
|
+
// overlay surface
|
|
1478
|
+
"surface-input": primitiveColors.charcoal[600],
|
|
1479
|
+
// input surface
|
|
1480
|
+
// Background colors
|
|
1481
|
+
"background-base": primitiveColors.charcoal[900],
|
|
1482
|
+
// darkest charcoal
|
|
1483
|
+
"background-default": primitiveColors.charcoal[700],
|
|
1484
|
+
// main background
|
|
1485
|
+
"background-subtle": primitiveColors.charcoal[500],
|
|
1486
|
+
// subtle background
|
|
1487
|
+
// Border colors
|
|
1488
|
+
"border-default": primitiveColors.charcoal[400],
|
|
1489
|
+
// default border
|
|
1490
|
+
"border-subtle": primitiveColors.charcoal[500],
|
|
1491
|
+
// subtle border
|
|
1492
|
+
"border-strong": primitiveColors.charcoal[300],
|
|
1493
|
+
// strong border
|
|
1494
|
+
"border-prominent": primitiveColors.charcoal[200],
|
|
1495
|
+
// high-visibility divider
|
|
1496
|
+
"border-focus": "#828DF8",
|
|
1497
|
+
"border-input": primitiveColors.neutral[600],
|
|
1498
|
+
"border-input-hover": primitiveColors.neutral[500],
|
|
1499
|
+
"border-input-focus": "#828DF8",
|
|
1500
|
+
"border-input-error": primitiveColors.red[500],
|
|
1501
|
+
// Interactive states
|
|
1502
|
+
"interactive-hover": "rgba(255, 255, 255, 0.04)",
|
|
1503
|
+
"interactive-focus": "rgba(255, 255, 255, 0.12)",
|
|
1504
|
+
"interactive-active": "rgba(255, 255, 255, 0.16)",
|
|
1505
|
+
"interactive-selected": "rgba(255, 255, 255, 0.08)",
|
|
1506
|
+
"interactive-disabled": "rgba(255, 255, 255, 0.12)",
|
|
1507
|
+
"interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
|
|
1508
|
+
// Divider
|
|
1509
|
+
"divider": primitiveColors.charcoal[400],
|
|
1510
|
+
// divider color
|
|
1511
|
+
// Avatar default
|
|
1512
|
+
"avatar-background": primitiveColors.neutral[600],
|
|
1513
|
+
"avatar-text": primitiveColors.white
|
|
1514
|
+
};
|
|
1515
|
+
function getSemanticColors(mode) {
|
|
1516
|
+
return mode === "dark" ? semanticColorsDark : semanticColorsLight;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
// src/components/custom/Workout/PrBadge.tsx
|
|
1520
|
+
var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
|
|
1521
|
+
var typeLabels = {
|
|
1522
|
+
e1rm: "PR e1RM",
|
|
1523
|
+
weight: "PR Weight",
|
|
1524
|
+
reps: "PR Reps",
|
|
1525
|
+
volume: "PR Volume",
|
|
1526
|
+
velocity: "PR Velocity"
|
|
1527
|
+
};
|
|
1528
|
+
function PrBadge({
|
|
1529
|
+
type = "e1rm",
|
|
1530
|
+
label: labelProp,
|
|
1531
|
+
compact = false,
|
|
1532
|
+
animate = true,
|
|
716
1533
|
className,
|
|
717
1534
|
...props
|
|
718
1535
|
}) {
|
|
@@ -744,7 +1561,7 @@ function PrBadge({
|
|
|
744
1561
|
accessibilityLabel: `Personal record: ${resolvedLabel}`,
|
|
745
1562
|
testID: "pr-badge-star",
|
|
746
1563
|
...props,
|
|
747
|
-
children: /* @__PURE__ */ jsx(StarIcon, { size: 14, color:
|
|
1564
|
+
children: /* @__PURE__ */ jsx(StarIcon, { size: 14, color: BRAND_PRIMARY, fill: BRAND_PRIMARY, strokeWidth: 2 })
|
|
748
1565
|
}
|
|
749
1566
|
) : /* @__PURE__ */ jsx(
|
|
750
1567
|
BaseBadge,
|
|
@@ -758,7 +1575,7 @@ function PrBadge({
|
|
|
758
1575
|
{
|
|
759
1576
|
style: {
|
|
760
1577
|
fontSize: 12,
|
|
761
|
-
color:
|
|
1578
|
+
color: BRAND_PRIMARY,
|
|
762
1579
|
fontWeight: "700",
|
|
763
1580
|
fontFamily: "Inter, sans-serif"
|
|
764
1581
|
},
|
|
@@ -783,6 +1600,204 @@ function PrBadge({
|
|
|
783
1600
|
}
|
|
784
1601
|
return badge;
|
|
785
1602
|
}
|
|
1603
|
+
var DARK = getSemanticColors("dark");
|
|
1604
|
+
var TEXT_ACTIVE = DARK["text-primary"];
|
|
1605
|
+
var TEXT_MUTED = DARK["text-secondary"];
|
|
1606
|
+
var COL = { set: 36, reps: 44, load: 56, rpe: 36 };
|
|
1607
|
+
var cellText = { fontFamily: "Inter, sans-serif", fontSize: 13, fontWeight: "600" };
|
|
1608
|
+
var typeBadge = {
|
|
1609
|
+
fontSize: 10,
|
|
1610
|
+
fontWeight: "700",
|
|
1611
|
+
fontFamily: "Inter, sans-serif",
|
|
1612
|
+
color: WORKOUT_TOKENS.scale.orange,
|
|
1613
|
+
backgroundColor: "rgba(255,165,2,0.12)",
|
|
1614
|
+
paddingVertical: 1,
|
|
1615
|
+
paddingHorizontal: 5,
|
|
1616
|
+
borderRadius: 3,
|
|
1617
|
+
overflow: "hidden"
|
|
1618
|
+
};
|
|
1619
|
+
function displayReps(set) {
|
|
1620
|
+
return set.state === "done" ? set.reps : set.target.reps;
|
|
1621
|
+
}
|
|
1622
|
+
function displayWeight(set) {
|
|
1623
|
+
return set.state === "done" ? set.weight : set.target.weight;
|
|
1624
|
+
}
|
|
1625
|
+
function plannedReps(set) {
|
|
1626
|
+
if (set.state === "done") return set.velocities.length;
|
|
1627
|
+
if (set.state === "live") return set.target.reps;
|
|
1628
|
+
return set.planned ?? set.target.reps;
|
|
1629
|
+
}
|
|
1630
|
+
function accessibilityLabel(set) {
|
|
1631
|
+
const base = `Set ${set.setNumber}: ${displayReps(set)} reps at ${roundWeight(displayWeight(set))} ${set.unit}`;
|
|
1632
|
+
if (set.state === "live") return `${base}, in progress`;
|
|
1633
|
+
if (set.state === "todo") return `${base}, upcoming`;
|
|
1634
|
+
return base;
|
|
1635
|
+
}
|
|
1636
|
+
function Cell({
|
|
1637
|
+
width,
|
|
1638
|
+
children,
|
|
1639
|
+
testID
|
|
1640
|
+
}) {
|
|
1641
|
+
return /* @__PURE__ */ jsx(View, { style: { width, alignItems: "center", justifyContent: "center" }, testID, children });
|
|
1642
|
+
}
|
|
1643
|
+
function RowStrip({ set }) {
|
|
1644
|
+
const zones = set.velocityZones;
|
|
1645
|
+
if (set.state === "live") {
|
|
1646
|
+
return /* @__PURE__ */ jsx(
|
|
1647
|
+
VelocityStrip,
|
|
1648
|
+
{
|
|
1649
|
+
variant: "expanded",
|
|
1650
|
+
showNumbers: false,
|
|
1651
|
+
showInfo: false,
|
|
1652
|
+
height: 24,
|
|
1653
|
+
scale: "fixed",
|
|
1654
|
+
set: { type: "straight", velocities: set.velocities, planned: set.target.reps },
|
|
1655
|
+
zones
|
|
1656
|
+
}
|
|
1657
|
+
);
|
|
1658
|
+
}
|
|
1659
|
+
const velocities = set.state === "done" ? set.velocities : [];
|
|
1660
|
+
return /* @__PURE__ */ jsx(
|
|
1661
|
+
VelocityStrip,
|
|
1662
|
+
{
|
|
1663
|
+
variant: "mini",
|
|
1664
|
+
set: { type: "straight", velocities, planned: plannedReps(set) },
|
|
1665
|
+
zones
|
|
1666
|
+
}
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
function SetRow(set) {
|
|
1670
|
+
const live = set.state === "live";
|
|
1671
|
+
const valueColor = live ? TEXT_ACTIVE : TEXT_MUTED;
|
|
1672
|
+
const rpe = set.state === "todo" ? null : set.rpe;
|
|
1673
|
+
return /* @__PURE__ */ jsxs(
|
|
1674
|
+
View,
|
|
1675
|
+
{
|
|
1676
|
+
style: { paddingVertical: 6, paddingHorizontal: 8 },
|
|
1677
|
+
accessibilityLabel: accessibilityLabel(set),
|
|
1678
|
+
testID: "set-row",
|
|
1679
|
+
children: [
|
|
1680
|
+
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { justifyContent: "space-between" }, children: [
|
|
1681
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.set, testID: "set-row-set-number", children: set.setType ? /* @__PURE__ */ jsx(Text, { style: typeBadge, testID: "set-row-type-badge", children: set.setType }) : /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: valueColor, fontWeight: live ? "700" : "600" }, children: set.setNumber }) }),
|
|
1682
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.reps, testID: "set-row-reps", children: /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: valueColor }, children: displayReps(set) }) }),
|
|
1683
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.load, testID: "set-row-weight", children: /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: valueColor }, children: roundWeight(displayWeight(set)) }) }),
|
|
1684
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.rpe, testID: "set-row-rpe", children: /* @__PURE__ */ jsx(Text, { style: { ...cellText, color: TEXT_MUTED }, children: rpe != null ? roundRpe(rpe) : "\u2014" }) })
|
|
1685
|
+
] }),
|
|
1686
|
+
/* @__PURE__ */ jsx(View, { style: { marginTop: live ? 6 : 4 }, testID: "set-row-strip", children: /* @__PURE__ */ jsx(RowStrip, { set }) })
|
|
1687
|
+
]
|
|
1688
|
+
}
|
|
1689
|
+
);
|
|
1690
|
+
}
|
|
1691
|
+
var PREV_COLUMN = { label: "PREV", width: void 0 };
|
|
1692
|
+
function buildColumns(unit, showPrevious) {
|
|
1693
|
+
return [
|
|
1694
|
+
{ label: "SET", width: 36 },
|
|
1695
|
+
...showPrevious ? [PREV_COLUMN] : [],
|
|
1696
|
+
{ label: "REPS", width: 44 },
|
|
1697
|
+
{ label: unit.toUpperCase(), width: 56 },
|
|
1698
|
+
{ label: "RPE", width: 36 }
|
|
1699
|
+
];
|
|
1700
|
+
}
|
|
1701
|
+
function SetTableHeader({
|
|
1702
|
+
unit = "lbs",
|
|
1703
|
+
showPrevious = true,
|
|
1704
|
+
testID = "table-header"
|
|
1705
|
+
}) {
|
|
1706
|
+
const columns = buildColumns(unit, showPrevious);
|
|
1707
|
+
return /* @__PURE__ */ jsx(
|
|
1708
|
+
View,
|
|
1709
|
+
{
|
|
1710
|
+
className: "flex-row",
|
|
1711
|
+
style: {
|
|
1712
|
+
paddingVertical: 8,
|
|
1713
|
+
paddingHorizontal: 8,
|
|
1714
|
+
paddingBottom: 4,
|
|
1715
|
+
...showPrevious ? {} : { justifyContent: "space-between" }
|
|
1716
|
+
},
|
|
1717
|
+
testID,
|
|
1718
|
+
children: columns.map(({ label, width }) => {
|
|
1719
|
+
const isFlex = width === void 0;
|
|
1720
|
+
return /* @__PURE__ */ jsx(
|
|
1721
|
+
View,
|
|
1722
|
+
{
|
|
1723
|
+
style: {
|
|
1724
|
+
...isFlex ? { minWidth: 44 } : { width, flexShrink: 1 },
|
|
1725
|
+
alignItems: "center",
|
|
1726
|
+
justifyContent: "center",
|
|
1727
|
+
gap: 8
|
|
1728
|
+
},
|
|
1729
|
+
...isFlex ? { className: "flex-1" } : {},
|
|
1730
|
+
children: /* @__PURE__ */ jsx(
|
|
1731
|
+
Text,
|
|
1732
|
+
{
|
|
1733
|
+
className: "text-text-tertiary",
|
|
1734
|
+
style: {
|
|
1735
|
+
fontSize: 10,
|
|
1736
|
+
fontWeight: "600",
|
|
1737
|
+
fontFamily: "Inter, sans-serif",
|
|
1738
|
+
textTransform: "uppercase",
|
|
1739
|
+
letterSpacing: 0.8
|
|
1740
|
+
},
|
|
1741
|
+
children: label
|
|
1742
|
+
}
|
|
1743
|
+
)
|
|
1744
|
+
},
|
|
1745
|
+
label
|
|
1746
|
+
);
|
|
1747
|
+
})
|
|
1748
|
+
}
|
|
1749
|
+
);
|
|
1750
|
+
}
|
|
1751
|
+
var METRIC_FONT = "Inter, sans-serif";
|
|
1752
|
+
function MetricCell({ children, color, fontSize = 11 }) {
|
|
1753
|
+
return /* @__PURE__ */ jsx(
|
|
1754
|
+
Text,
|
|
1755
|
+
{
|
|
1756
|
+
style: {
|
|
1757
|
+
fontFamily: METRIC_FONT,
|
|
1758
|
+
fontSize,
|
|
1759
|
+
color,
|
|
1760
|
+
fontWeight: "600",
|
|
1761
|
+
letterSpacing: 1
|
|
1762
|
+
},
|
|
1763
|
+
children
|
|
1764
|
+
}
|
|
1765
|
+
);
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
// src/components/custom/Workout/SetsRepsLoad.tsx
|
|
1769
|
+
var t = getSemanticColors("dark");
|
|
1770
|
+
var TIMES = "\xD7";
|
|
1771
|
+
var AT = "@";
|
|
1772
|
+
function SetsRepsLoad({
|
|
1773
|
+
sets,
|
|
1774
|
+
reps,
|
|
1775
|
+
load,
|
|
1776
|
+
unit = "lb",
|
|
1777
|
+
className,
|
|
1778
|
+
...props
|
|
1779
|
+
}) {
|
|
1780
|
+
const value = t["text-primary"];
|
|
1781
|
+
const sep = t["text-tertiary"];
|
|
1782
|
+
return /* @__PURE__ */ jsxs(
|
|
1783
|
+
View,
|
|
1784
|
+
{
|
|
1785
|
+
className,
|
|
1786
|
+
style: { flexDirection: "row", alignItems: "baseline" },
|
|
1787
|
+
accessibilityLabel: `${sets} sets of ${reps} reps at ${load} ${unit}`,
|
|
1788
|
+
testID: "sets-reps-load",
|
|
1789
|
+
...props,
|
|
1790
|
+
children: [
|
|
1791
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, children: sets }),
|
|
1792
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${TIMES} ` }),
|
|
1793
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, children: reps }),
|
|
1794
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${AT} ` }),
|
|
1795
|
+
/* @__PURE__ */ jsx(MetricCell, { color: value, children: load }),
|
|
1796
|
+
/* @__PURE__ */ jsx(MetricCell, { color: sep, children: ` ${unit}` })
|
|
1797
|
+
]
|
|
1798
|
+
}
|
|
1799
|
+
);
|
|
1800
|
+
}
|
|
786
1801
|
function hexToRgb(hex) {
|
|
787
1802
|
const cleaned = hex.replace("#", "");
|
|
788
1803
|
let r, g, b;
|
|
@@ -1092,452 +2107,54 @@ function alpha(color, opacity) {
|
|
|
1092
2107
|
}
|
|
1093
2108
|
return color;
|
|
1094
2109
|
}
|
|
2110
|
+
var t2 = getSemanticColors("dark");
|
|
2111
|
+
var TEMPO_PACING = {
|
|
2112
|
+
behindThresholdPct: 0.15,
|
|
2113
|
+
minPhaseDurationMs: 500
|
|
2114
|
+
};
|
|
2115
|
+
function getTempoPacingState(elapsedMs, targetMs) {
|
|
2116
|
+
if (!targetMs || targetMs < TEMPO_PACING.minPhaseDurationMs) return "none";
|
|
2117
|
+
const ratio = elapsedMs / targetMs;
|
|
2118
|
+
if (ratio > 1 + TEMPO_PACING.behindThresholdPct) return "behind";
|
|
2119
|
+
return "on-pace";
|
|
2120
|
+
}
|
|
2121
|
+
function getTempoFillPct(elapsedMs, targetMs) {
|
|
2122
|
+
if (!targetMs) return 100;
|
|
2123
|
+
return Math.min(100, elapsedMs / targetMs * 100);
|
|
2124
|
+
}
|
|
2125
|
+
({
|
|
2126
|
+
concentric: { color: t2["status-success"]},
|
|
2127
|
+
hold: { color: t2["brand-primary"]},
|
|
2128
|
+
eccentric: { color: t2["status-warning"]}
|
|
2129
|
+
});
|
|
1095
2130
|
|
|
1096
|
-
// src/
|
|
1097
|
-
var
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
400: "#FFBF4C",
|
|
1124
|
-
// Warning light
|
|
1125
|
-
500: "#FFB020",
|
|
1126
|
-
// Warning main
|
|
1127
|
-
600: "#B27B16"},
|
|
1128
|
-
// Sky/Blue scale (info)
|
|
1129
|
-
sky: {
|
|
1130
|
-
50: "#F0F9FF",
|
|
1131
|
-
400: "#64B6F7",
|
|
1132
|
-
// Info light
|
|
1133
|
-
500: "#2196F3",
|
|
1134
|
-
700: "#0B79D0"},
|
|
1135
|
-
// Neutral/Gray scale
|
|
1136
|
-
neutral: {
|
|
1137
|
-
50: "#FAFAFA",
|
|
1138
|
-
100: "#F3F4F6",
|
|
1139
|
-
300: "#D1D5DB",
|
|
1140
|
-
400: "#9CA3AF",
|
|
1141
|
-
500: "#6B7280",
|
|
1142
|
-
600: "#4B5563",
|
|
1143
|
-
900: "#111827"},
|
|
1144
|
-
// Orange scale (accent/brand color)
|
|
1145
|
-
accent: {
|
|
1146
|
-
200: "#FF9630",
|
|
1147
|
-
300: "#FF8500",
|
|
1148
|
-
400: "#FF7900",
|
|
1149
|
-
500: "#F56C00",
|
|
1150
|
-
600: "#E06D10",
|
|
1151
|
-
700: "#D0620C"},
|
|
1152
|
-
// Charcoal scale (dark backgrounds)
|
|
1153
|
-
charcoal: {
|
|
1154
|
-
300: "#2C2C2C",
|
|
1155
|
-
400: "#1F1F1F",
|
|
1156
|
-
500: "#1C1C1C",
|
|
1157
|
-
600: "#191919",
|
|
1158
|
-
700: "#161616",
|
|
1159
|
-
900: "#101010"
|
|
1160
|
-
},
|
|
1161
|
-
// Steel scale (cool accent)
|
|
1162
|
-
steel: {
|
|
1163
|
-
300: "#678498",
|
|
1164
|
-
400: "#557488",
|
|
1165
|
-
500: "#406D87",
|
|
1166
|
-
600: "#39617A",
|
|
1167
|
-
700: "#32556D"},
|
|
1168
|
-
// Pure colors
|
|
1169
|
-
white: "#FFFFFF"};
|
|
1170
|
-
var discreteRainbow = [
|
|
1171
|
-
"#E8ECFB",
|
|
1172
|
-
"#D9CCE3",
|
|
1173
|
-
"#D1BBD7",
|
|
1174
|
-
"#CAACCB",
|
|
1175
|
-
"#BA8DB4",
|
|
1176
|
-
"#AE76A3",
|
|
1177
|
-
"#AA6F9E",
|
|
1178
|
-
"#994F88",
|
|
1179
|
-
"#882E72",
|
|
1180
|
-
"#1965B0",
|
|
1181
|
-
"#437DBF",
|
|
1182
|
-
"#5289C7",
|
|
1183
|
-
"#6195CF",
|
|
1184
|
-
"#7BAFDE",
|
|
1185
|
-
"#4EB265",
|
|
1186
|
-
"#90C987",
|
|
1187
|
-
"#CAE0AB",
|
|
1188
|
-
"#F7F056",
|
|
1189
|
-
"#F7CB45",
|
|
1190
|
-
"#F6C141",
|
|
1191
|
-
"#F4A736",
|
|
1192
|
-
"#F1932D",
|
|
1193
|
-
"#EE8026",
|
|
1194
|
-
"#E8601C",
|
|
1195
|
-
"#E65518",
|
|
1196
|
-
"#DC050C",
|
|
1197
|
-
"#A5170E",
|
|
1198
|
-
"#72190E",
|
|
1199
|
-
"#42150A"
|
|
1200
|
-
];
|
|
1201
|
-
|
|
1202
|
-
// src/theme/tokens/semantic.ts
|
|
1203
|
-
var semanticColorsLight = {
|
|
1204
|
-
// Brand colors (brand-*)
|
|
1205
|
-
"brand-primary": primitiveColors.accent[400],
|
|
1206
|
-
// #FF7900
|
|
1207
|
-
"brand-primary-light": primitiveColors.accent[200],
|
|
1208
|
-
// #FF9630
|
|
1209
|
-
"brand-primary-dark": primitiveColors.accent[700],
|
|
1210
|
-
// #D0620C
|
|
1211
|
-
"brand-primary-subtle": "rgba(255, 121, 0, 0.08)",
|
|
1212
|
-
"brand-primary-hover": primitiveColors.accent[500],
|
|
1213
|
-
"brand-primary-active": primitiveColors.accent[600],
|
|
1214
|
-
"brand-secondary": primitiveColors.steel[500],
|
|
1215
|
-
// #406D87
|
|
1216
|
-
"brand-secondary-light": primitiveColors.steel[300],
|
|
1217
|
-
// #678498
|
|
1218
|
-
"brand-secondary-dark": primitiveColors.steel[700],
|
|
1219
|
-
// #32556D
|
|
1220
|
-
"brand-secondary-subtle": "rgba(64, 109, 135, 0.08)",
|
|
1221
|
-
"brand-secondary-hover": primitiveColors.steel[600],
|
|
1222
|
-
"brand-secondary-active": primitiveColors.steel[700],
|
|
1223
|
-
// Text on brand backgrounds (on-*)
|
|
1224
|
-
"on-brand-primary": primitiveColors.white,
|
|
1225
|
-
"on-brand-secondary": primitiveColors.white,
|
|
1226
|
-
// Status colors (status-*)
|
|
1227
|
-
"status-success": primitiveColors.teal[500],
|
|
1228
|
-
// #14B8A6
|
|
1229
|
-
"status-success-light": primitiveColors.teal[400],
|
|
1230
|
-
// #43C6B7
|
|
1231
|
-
"status-success-dark": primitiveColors.teal[700],
|
|
1232
|
-
// #0E8074
|
|
1233
|
-
"status-success-subtle": primitiveColors.teal[50],
|
|
1234
|
-
"status-error": primitiveColors.red[600],
|
|
1235
|
-
// #D14343
|
|
1236
|
-
"status-error-light": primitiveColors.red[400],
|
|
1237
|
-
// #DA6868
|
|
1238
|
-
"status-error-dark": primitiveColors.red[700],
|
|
1239
|
-
// #922E2E
|
|
1240
|
-
"status-error-subtle": primitiveColors.red[50],
|
|
1241
|
-
"status-warning": primitiveColors.amber[500],
|
|
1242
|
-
// #FFB020
|
|
1243
|
-
"status-warning-light": primitiveColors.amber[400],
|
|
1244
|
-
// #FFBF4C
|
|
1245
|
-
"status-warning-dark": primitiveColors.amber[600],
|
|
1246
|
-
// #B27B16
|
|
1247
|
-
"status-warning-subtle": primitiveColors.amber[50],
|
|
1248
|
-
"status-info": primitiveColors.sky[500],
|
|
1249
|
-
// #2196F3
|
|
1250
|
-
"status-info-light": primitiveColors.sky[400],
|
|
1251
|
-
// #64B6F7
|
|
1252
|
-
"status-info-dark": primitiveColors.sky[700],
|
|
1253
|
-
// #0B79D0
|
|
1254
|
-
"status-info-subtle": primitiveColors.sky[50],
|
|
1255
|
-
// Text on status backgrounds (on-status-*)
|
|
1256
|
-
"on-status-success": primitiveColors.white,
|
|
1257
|
-
"on-status-error": primitiveColors.white,
|
|
1258
|
-
"on-status-warning": primitiveColors.white,
|
|
1259
|
-
"on-status-info": primitiveColors.white,
|
|
1260
|
-
// Result/outcome indicators (result-*)
|
|
1261
|
-
"result-improve": "#4caf50",
|
|
1262
|
-
// Green - positive outcome
|
|
1263
|
-
"result-improve-light": "rgba(76, 175, 80, 0.12)",
|
|
1264
|
-
"result-improve-dark": "#248a24",
|
|
1265
|
-
"result-degrade": "#ef5350",
|
|
1266
|
-
// Red - negative outcome
|
|
1267
|
-
"result-degrade-light": "rgba(239, 83, 80, 0.12)",
|
|
1268
|
-
"result-degrade-dark": "#b30000",
|
|
1269
|
-
"result-inconclusive": "#9E9A97",
|
|
1270
|
-
// Gray - no clear result
|
|
1271
|
-
"result-inconclusive-light": "rgba(158, 154, 151, 0.12)",
|
|
1272
|
-
"result-neutral": primitiveColors.neutral[500],
|
|
1273
|
-
// Neutral baseline
|
|
1274
|
-
// Text on result backgrounds (on-result-*)
|
|
1275
|
-
"on-result-improve": primitiveColors.white,
|
|
1276
|
-
"on-result-degrade": primitiveColors.white,
|
|
1277
|
-
"on-result-inconclusive": primitiveColors.white,
|
|
1278
|
-
// Data visualization colors (data-*)
|
|
1279
|
-
// First 10 colors from discrete rainbow optimized for charts
|
|
1280
|
-
"data-1": discreteRainbow[9],
|
|
1281
|
-
// #1965B0 - Blue
|
|
1282
|
-
"data-2": discreteRainbow[14],
|
|
1283
|
-
// #4EB265 - Green
|
|
1284
|
-
"data-3": discreteRainbow[17],
|
|
1285
|
-
// #F7F056 - Yellow
|
|
1286
|
-
"data-4": discreteRainbow[25],
|
|
1287
|
-
// #DC050C - Red
|
|
1288
|
-
"data-5": discreteRainbow[8],
|
|
1289
|
-
// #882E72 - Purple
|
|
1290
|
-
"data-6": discreteRainbow[20],
|
|
1291
|
-
// #F4A736 - Orange
|
|
1292
|
-
"data-7": discreteRainbow[13],
|
|
1293
|
-
// #7BAFDE - Light Blue
|
|
1294
|
-
"data-8": discreteRainbow[15],
|
|
1295
|
-
// #90C987 - Light Green
|
|
1296
|
-
"data-9": discreteRainbow[3],
|
|
1297
|
-
// #CAACCB - Lavender
|
|
1298
|
-
"data-10": discreteRainbow[22],
|
|
1299
|
-
// #EE8026 - Dark Orange
|
|
1300
|
-
// Text colors (text-*)
|
|
1301
|
-
"text-primary": "#121828",
|
|
1302
|
-
"text-secondary": "#65748B",
|
|
1303
|
-
"text-tertiary": primitiveColors.neutral[400],
|
|
1304
|
-
"text-disabled": "rgba(55, 65, 81, 0.48)",
|
|
1305
|
-
"text-inverse": primitiveColors.white,
|
|
1306
|
-
"text-link": primitiveColors.blue[600],
|
|
1307
|
-
"text-link-hover": primitiveColors.blue[700],
|
|
1308
|
-
// Surface colors (surface-*) - for elevated containers
|
|
1309
|
-
"surface-base": primitiveColors.white,
|
|
1310
|
-
"surface-elevated": primitiveColors.neutral[50],
|
|
1311
|
-
// #FAFAFA - slightly off-white for elevated cards
|
|
1312
|
-
"surface-raised": primitiveColors.neutral[100],
|
|
1313
|
-
// #F3F4F6 - light gray for raised cards
|
|
1314
|
-
"surface-overlay": primitiveColors.white,
|
|
1315
|
-
"surface-input": primitiveColors.neutral[50],
|
|
1316
|
-
// Input field background (filled variant)
|
|
1317
|
-
// Background colors (background-*)
|
|
1318
|
-
"background-base": "#EBEBEB",
|
|
1319
|
-
"background-default": primitiveColors.white,
|
|
1320
|
-
"background-subtle": primitiveColors.neutral[50],
|
|
1321
|
-
// Border colors (border-*)
|
|
1322
|
-
"border-default": "#E8E9EB",
|
|
1323
|
-
"border-subtle": primitiveColors.neutral[100],
|
|
1324
|
-
"border-strong": primitiveColors.neutral[300],
|
|
1325
|
-
"border-focus": primitiveColors.blue[600],
|
|
1326
|
-
"border-input": primitiveColors.neutral[300],
|
|
1327
|
-
// Input field border
|
|
1328
|
-
"border-input-hover": primitiveColors.neutral[400],
|
|
1329
|
-
// Input field border on hover
|
|
1330
|
-
"border-input-focus": primitiveColors.blue[600],
|
|
1331
|
-
// Input field border on focus
|
|
1332
|
-
"border-input-error": primitiveColors.red[600],
|
|
1333
|
-
// Input field border on error
|
|
1334
|
-
// Interactive states (interactive-*)
|
|
1335
|
-
"interactive-hover": "rgba(55, 65, 81, 0.04)",
|
|
1336
|
-
"interactive-focus": "rgba(55, 65, 81, 0.12)",
|
|
1337
|
-
"interactive-active": "rgba(55, 65, 81, 0.16)",
|
|
1338
|
-
"interactive-selected": "rgba(55, 65, 81, 0.08)",
|
|
1339
|
-
"interactive-disabled": "rgba(55, 65, 81, 0.12)",
|
|
1340
|
-
"interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
|
|
1341
|
-
// Divider
|
|
1342
|
-
"divider": "#E8E9EB",
|
|
1343
|
-
// Avatar default
|
|
1344
|
-
"avatar-background": primitiveColors.neutral[500],
|
|
1345
|
-
"avatar-text": primitiveColors.white
|
|
1346
|
-
};
|
|
1347
|
-
var semanticColorsDark = {
|
|
1348
|
-
// Brand colors stay the same in dark mode
|
|
1349
|
-
"brand-primary": primitiveColors.accent[400],
|
|
1350
|
-
"brand-primary-light": primitiveColors.accent[200],
|
|
1351
|
-
"brand-primary-dark": primitiveColors.accent[700],
|
|
1352
|
-
"brand-primary-subtle": "rgba(255, 121, 0, 0.12)",
|
|
1353
|
-
"brand-primary-hover": primitiveColors.accent[300],
|
|
1354
|
-
"brand-primary-active": primitiveColors.accent[200],
|
|
1355
|
-
"brand-secondary": primitiveColors.steel[500],
|
|
1356
|
-
"brand-secondary-light": primitiveColors.steel[300],
|
|
1357
|
-
"brand-secondary-dark": primitiveColors.steel[700],
|
|
1358
|
-
"brand-secondary-subtle": "rgba(64, 109, 135, 0.12)",
|
|
1359
|
-
"brand-secondary-hover": primitiveColors.steel[400],
|
|
1360
|
-
"brand-secondary-active": primitiveColors.steel[300],
|
|
1361
|
-
// Text on brand backgrounds
|
|
1362
|
-
"on-brand-primary": primitiveColors.white,
|
|
1363
|
-
"on-brand-secondary": primitiveColors.white,
|
|
1364
|
-
// Status colors
|
|
1365
|
-
"status-success": primitiveColors.teal[500],
|
|
1366
|
-
"status-success-light": primitiveColors.teal[400],
|
|
1367
|
-
"status-success-dark": primitiveColors.teal[700],
|
|
1368
|
-
"status-success-subtle": "rgba(20, 184, 166, 0.12)",
|
|
1369
|
-
"status-error": primitiveColors.red[600],
|
|
1370
|
-
"status-error-light": primitiveColors.red[400],
|
|
1371
|
-
"status-error-dark": primitiveColors.red[700],
|
|
1372
|
-
"status-error-subtle": "rgba(209, 67, 67, 0.12)",
|
|
1373
|
-
"status-warning": primitiveColors.amber[500],
|
|
1374
|
-
"status-warning-light": primitiveColors.amber[400],
|
|
1375
|
-
"status-warning-dark": primitiveColors.amber[600],
|
|
1376
|
-
"status-warning-subtle": "rgba(255, 176, 32, 0.12)",
|
|
1377
|
-
"status-info": primitiveColors.sky[500],
|
|
1378
|
-
"status-info-light": primitiveColors.sky[400],
|
|
1379
|
-
"status-info-dark": primitiveColors.sky[700],
|
|
1380
|
-
"status-info-subtle": "rgba(33, 150, 243, 0.12)",
|
|
1381
|
-
// Text on status backgrounds
|
|
1382
|
-
"on-status-success": primitiveColors.white,
|
|
1383
|
-
"on-status-error": primitiveColors.white,
|
|
1384
|
-
"on-status-warning": primitiveColors.white,
|
|
1385
|
-
"on-status-info": primitiveColors.white,
|
|
1386
|
-
// Result/outcome indicators (result-*)
|
|
1387
|
-
"result-improve": "#4caf50",
|
|
1388
|
-
"result-improve-light": "rgba(76, 175, 80, 0.16)",
|
|
1389
|
-
"result-improve-dark": "#248a24",
|
|
1390
|
-
"result-degrade": "#ef5350",
|
|
1391
|
-
"result-degrade-light": "rgba(239, 83, 80, 0.16)",
|
|
1392
|
-
"result-degrade-dark": "#b30000",
|
|
1393
|
-
"result-inconclusive": "#9E9A97",
|
|
1394
|
-
"result-inconclusive-light": "rgba(158, 154, 151, 0.16)",
|
|
1395
|
-
"result-neutral": primitiveColors.neutral[400],
|
|
1396
|
-
// Text on result backgrounds
|
|
1397
|
-
"on-result-improve": primitiveColors.white,
|
|
1398
|
-
"on-result-degrade": primitiveColors.white,
|
|
1399
|
-
"on-result-inconclusive": primitiveColors.white,
|
|
1400
|
-
// Data visualization colors (same in dark mode for consistency)
|
|
1401
|
-
"data-1": discreteRainbow[9],
|
|
1402
|
-
"data-2": discreteRainbow[14],
|
|
1403
|
-
"data-3": discreteRainbow[17],
|
|
1404
|
-
"data-4": discreteRainbow[25],
|
|
1405
|
-
"data-5": discreteRainbow[8],
|
|
1406
|
-
"data-6": discreteRainbow[20],
|
|
1407
|
-
"data-7": discreteRainbow[13],
|
|
1408
|
-
"data-8": discreteRainbow[15],
|
|
1409
|
-
"data-9": discreteRainbow[3],
|
|
1410
|
-
"data-10": discreteRainbow[22],
|
|
1411
|
-
// Text colors - inverted for dark mode
|
|
1412
|
-
"text-primary": primitiveColors.neutral[100],
|
|
1413
|
-
"text-secondary": primitiveColors.neutral[400],
|
|
1414
|
-
"text-tertiary": primitiveColors.neutral[500],
|
|
1415
|
-
"text-disabled": "rgba(255, 255, 255, 0.38)",
|
|
1416
|
-
"text-inverse": primitiveColors.neutral[900],
|
|
1417
|
-
"text-link": "#828DF8",
|
|
1418
|
-
"text-link-hover": primitiveColors.blue[400],
|
|
1419
|
-
// Surface colors - dark backgrounds
|
|
1420
|
-
"surface-base": primitiveColors.charcoal[700],
|
|
1421
|
-
// #161616 - main surface
|
|
1422
|
-
"surface-elevated": primitiveColors.charcoal[600],
|
|
1423
|
-
// #191919 - elevated surface
|
|
1424
|
-
"surface-raised": primitiveColors.charcoal[500],
|
|
1425
|
-
// #1C1C1C - raised surface
|
|
1426
|
-
"surface-overlay": primitiveColors.charcoal[600],
|
|
1427
|
-
// #191919 - overlay surface
|
|
1428
|
-
"surface-input": primitiveColors.charcoal[600],
|
|
1429
|
-
// #191919 - input surface
|
|
1430
|
-
// Background colors
|
|
1431
|
-
"background-base": primitiveColors.charcoal[900],
|
|
1432
|
-
// #101010 - darkest charcoal
|
|
1433
|
-
"background-default": primitiveColors.charcoal[700],
|
|
1434
|
-
// #161616 - main background
|
|
1435
|
-
"background-subtle": primitiveColors.charcoal[500],
|
|
1436
|
-
// #1C1C1C - subtle background
|
|
1437
|
-
// Border colors
|
|
1438
|
-
"border-default": primitiveColors.charcoal[400],
|
|
1439
|
-
// #1F1F1F - default border
|
|
1440
|
-
"border-subtle": primitiveColors.charcoal[500],
|
|
1441
|
-
// #1C1C1C - subtle border
|
|
1442
|
-
"border-strong": primitiveColors.charcoal[300],
|
|
1443
|
-
// #2C2C2C - strong border
|
|
1444
|
-
"border-focus": "#828DF8",
|
|
1445
|
-
"border-input": primitiveColors.neutral[600],
|
|
1446
|
-
"border-input-hover": primitiveColors.neutral[500],
|
|
1447
|
-
"border-input-focus": "#828DF8",
|
|
1448
|
-
"border-input-error": primitiveColors.red[500],
|
|
1449
|
-
// Interactive states
|
|
1450
|
-
"interactive-hover": "rgba(255, 255, 255, 0.04)",
|
|
1451
|
-
"interactive-focus": "rgba(255, 255, 255, 0.12)",
|
|
1452
|
-
"interactive-active": "rgba(255, 255, 255, 0.16)",
|
|
1453
|
-
"interactive-selected": "rgba(255, 255, 255, 0.08)",
|
|
1454
|
-
"interactive-disabled": "rgba(255, 255, 255, 0.12)",
|
|
1455
|
-
"interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
|
|
1456
|
-
// Divider
|
|
1457
|
-
"divider": primitiveColors.charcoal[400],
|
|
1458
|
-
// #1F1F1F - divider color
|
|
1459
|
-
// Avatar default
|
|
1460
|
-
"avatar-background": primitiveColors.neutral[600],
|
|
1461
|
-
"avatar-text": primitiveColors.white
|
|
1462
|
-
};
|
|
1463
|
-
function getSemanticColors(mode) {
|
|
1464
|
-
return mode === "dark" ? semanticColorsDark : semanticColorsLight;
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
// src/components/custom/Workout/TempoBar.tsx
|
|
1468
|
-
var t = getSemanticColors("dark");
|
|
1469
|
-
var TEMPO_PACING = {
|
|
1470
|
-
behindThresholdPct: 0.15,
|
|
1471
|
-
minPhaseDurationMs: 500
|
|
1472
|
-
};
|
|
1473
|
-
function getTempoPacingState(elapsedMs, targetMs) {
|
|
1474
|
-
if (!targetMs || targetMs < TEMPO_PACING.minPhaseDurationMs) return "none";
|
|
1475
|
-
const ratio = elapsedMs / targetMs;
|
|
1476
|
-
if (ratio > 1 + TEMPO_PACING.behindThresholdPct) return "behind";
|
|
1477
|
-
return "on-pace";
|
|
1478
|
-
}
|
|
1479
|
-
function getTempoFillPct(elapsedMs, targetMs) {
|
|
1480
|
-
if (!targetMs) return 100;
|
|
1481
|
-
return Math.min(100, elapsedMs / targetMs * 100);
|
|
1482
|
-
}
|
|
1483
|
-
({
|
|
1484
|
-
concentric: { color: t["status-success"]},
|
|
1485
|
-
hold: { color: t["brand-primary"]},
|
|
1486
|
-
eccentric: { color: t["status-warning"]}
|
|
1487
|
-
});
|
|
1488
|
-
|
|
1489
|
-
// src/components/custom/Workout/TempoDisplay.tsx
|
|
1490
|
-
var INTER = "Inter, sans-serif";
|
|
1491
|
-
var TEXT_TERTIARY = "#6B7280";
|
|
1492
|
-
var STATUS_ERROR = "#D14343";
|
|
1493
|
-
var phaseColors = {
|
|
1494
|
-
eccentric: "#FFB020",
|
|
1495
|
-
// status-warning (amber)
|
|
1496
|
-
pauseBottom: TEXT_TERTIARY,
|
|
1497
|
-
concentric: "#14B8A6",
|
|
1498
|
-
// status-success (teal)
|
|
1499
|
-
pauseTop: TEXT_TERTIARY,
|
|
1500
|
-
dash: TEXT_TERTIARY
|
|
1501
|
-
};
|
|
1502
|
-
function TempoValue({
|
|
1503
|
-
value,
|
|
1504
|
-
color,
|
|
1505
|
-
fontSize
|
|
1506
|
-
}) {
|
|
1507
|
-
return /* @__PURE__ */ jsx(
|
|
1508
|
-
Text,
|
|
1509
|
-
{
|
|
1510
|
-
style: {
|
|
1511
|
-
fontFamily: INTER,
|
|
1512
|
-
fontSize,
|
|
1513
|
-
color,
|
|
1514
|
-
fontWeight: "600",
|
|
1515
|
-
letterSpacing: 1
|
|
1516
|
-
},
|
|
1517
|
-
children: value
|
|
1518
|
-
}
|
|
1519
|
-
);
|
|
1520
|
-
}
|
|
1521
|
-
function TempoSeparator({ color, fontSize }) {
|
|
1522
|
-
return /* @__PURE__ */ jsx(
|
|
1523
|
-
Text,
|
|
1524
|
-
{
|
|
1525
|
-
style: {
|
|
1526
|
-
fontFamily: INTER,
|
|
1527
|
-
fontSize,
|
|
1528
|
-
color,
|
|
1529
|
-
fontWeight: "600",
|
|
1530
|
-
letterSpacing: 1
|
|
1531
|
-
},
|
|
1532
|
-
children: "-"
|
|
1533
|
-
}
|
|
1534
|
-
);
|
|
1535
|
-
}
|
|
1536
|
-
var LIVE_PHASES = [
|
|
1537
|
-
{ key: "eccentric", color: phaseColors.eccentric },
|
|
1538
|
-
{ key: "pauseBottom", color: phaseColors.pauseBottom },
|
|
1539
|
-
{ key: "concentric", color: phaseColors.concentric },
|
|
1540
|
-
{ key: "pauseTop", color: phaseColors.pauseTop }
|
|
2131
|
+
// src/components/custom/Workout/TempoDisplay.tsx
|
|
2132
|
+
var t3 = getSemanticColors("dark");
|
|
2133
|
+
var INTER = "Inter, sans-serif";
|
|
2134
|
+
var TEXT_TERTIARY = "#6B7280";
|
|
2135
|
+
var STATUS_ERROR = t3["status-error"];
|
|
2136
|
+
var phaseColors = {
|
|
2137
|
+
eccentric: t3["status-warning"],
|
|
2138
|
+
pauseBottom: TEXT_TERTIARY,
|
|
2139
|
+
concentric: t3["status-success"],
|
|
2140
|
+
pauseTop: TEXT_TERTIARY,
|
|
2141
|
+
dash: TEXT_TERTIARY
|
|
2142
|
+
};
|
|
2143
|
+
function TempoValue({
|
|
2144
|
+
value,
|
|
2145
|
+
color,
|
|
2146
|
+
fontSize
|
|
2147
|
+
}) {
|
|
2148
|
+
return /* @__PURE__ */ jsx(MetricCell, { color, fontSize, children: value });
|
|
2149
|
+
}
|
|
2150
|
+
function TempoSeparator({ color, fontSize }) {
|
|
2151
|
+
return /* @__PURE__ */ jsx(MetricCell, { color, fontSize, children: "-" });
|
|
2152
|
+
}
|
|
2153
|
+
var LIVE_PHASES = [
|
|
2154
|
+
{ key: "eccentric", color: phaseColors.eccentric },
|
|
2155
|
+
{ key: "pauseBottom", color: phaseColors.pauseBottom },
|
|
2156
|
+
{ key: "concentric", color: phaseColors.concentric },
|
|
2157
|
+
{ key: "pauseTop", color: phaseColors.pauseTop }
|
|
1541
2158
|
];
|
|
1542
2159
|
function LiveTempoCell({
|
|
1543
2160
|
value,
|
|
@@ -1593,6 +2210,7 @@ function TempoDisplay({
|
|
|
1593
2210
|
tempo,
|
|
1594
2211
|
size = "md",
|
|
1595
2212
|
colored = true,
|
|
2213
|
+
showLabel = true,
|
|
1596
2214
|
showInfo = true,
|
|
1597
2215
|
live,
|
|
1598
2216
|
onPress,
|
|
@@ -1626,7 +2244,7 @@ function TempoDisplay({
|
|
|
1626
2244
|
},
|
|
1627
2245
|
...props,
|
|
1628
2246
|
children: [
|
|
1629
|
-
/* @__PURE__ */ jsx(
|
|
2247
|
+
showLabel && /* @__PURE__ */ jsx(
|
|
1630
2248
|
Text,
|
|
1631
2249
|
{
|
|
1632
2250
|
style: {
|
|
@@ -1704,301 +2322,177 @@ function TempoDisplay({
|
|
|
1704
2322
|
testID: "tempo-tooltip",
|
|
1705
2323
|
children: [
|
|
1706
2324
|
/* @__PURE__ */ jsxs(
|
|
1707
|
-
View,
|
|
1708
|
-
{
|
|
1709
|
-
style: {
|
|
1710
|
-
backgroundColor: "#191919",
|
|
1711
|
-
borderRadius: 6,
|
|
1712
|
-
paddingVertical: 8,
|
|
1713
|
-
paddingHorizontal: 12,
|
|
1714
|
-
borderWidth: 1,
|
|
1715
|
-
borderColor: "#2C2C2C"
|
|
1716
|
-
},
|
|
1717
|
-
children: [
|
|
1718
|
-
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
1719
|
-
"Eccentric: ",
|
|
1720
|
-
eccentric,
|
|
1721
|
-
"s"
|
|
1722
|
-
] }),
|
|
1723
|
-
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
1724
|
-
"Pause (bottom): ",
|
|
1725
|
-
pauseBottom,
|
|
1726
|
-
"s"
|
|
1727
|
-
] }),
|
|
1728
|
-
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
1729
|
-
"Concentric: ",
|
|
1730
|
-
concentric,
|
|
1731
|
-
"s"
|
|
1732
|
-
] }),
|
|
1733
|
-
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
1734
|
-
"Pause (top): ",
|
|
1735
|
-
pauseTop,
|
|
1736
|
-
"s"
|
|
1737
|
-
] })
|
|
1738
|
-
]
|
|
1739
|
-
}
|
|
1740
|
-
),
|
|
1741
|
-
/* @__PURE__ */ jsx(
|
|
1742
|
-
View,
|
|
1743
|
-
{
|
|
1744
|
-
style: {
|
|
1745
|
-
width: 0,
|
|
1746
|
-
height: 0,
|
|
1747
|
-
borderLeftWidth: 5,
|
|
1748
|
-
borderRightWidth: 5,
|
|
1749
|
-
borderTopWidth: 5,
|
|
1750
|
-
borderLeftColor: "transparent",
|
|
1751
|
-
borderRightColor: "transparent",
|
|
1752
|
-
borderTopColor: "#2C2C2C"
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
)
|
|
1756
|
-
]
|
|
1757
|
-
}
|
|
1758
|
-
)
|
|
1759
|
-
]
|
|
1760
|
-
}
|
|
1761
|
-
);
|
|
1762
|
-
}
|
|
1763
|
-
function formatAccessibilityLabel(setNumber, reps, weight, unit) {
|
|
1764
|
-
const repsText = reps != null ? `${reps} reps` : "no reps";
|
|
1765
|
-
const weightText = weight != null ? `at ${roundWeight(weight)} ${unit}` : "";
|
|
1766
|
-
return `Set ${setNumber}: ${repsText}${weightText ? ` ${weightText}` : ""}`;
|
|
1767
|
-
}
|
|
1768
|
-
function SetRow({
|
|
1769
|
-
mode,
|
|
1770
|
-
setNumber,
|
|
1771
|
-
previous,
|
|
1772
|
-
reps,
|
|
1773
|
-
weight,
|
|
1774
|
-
rpe,
|
|
1775
|
-
unit,
|
|
1776
|
-
velocities,
|
|
1777
|
-
velocityZones,
|
|
1778
|
-
velocityLiveRepIndex,
|
|
1779
|
-
velocityExpanded,
|
|
1780
|
-
onVelocityToggle,
|
|
1781
|
-
setType,
|
|
1782
|
-
prBadges,
|
|
1783
|
-
isNextSet,
|
|
1784
|
-
targets
|
|
1785
|
-
}) {
|
|
1786
|
-
const isActive = mode === "active";
|
|
1787
|
-
const isCompleted = mode === "completed";
|
|
1788
|
-
const rowStyle = {
|
|
1789
|
-
flexDirection: "row",
|
|
1790
|
-
alignItems: "center",
|
|
1791
|
-
padding: 7,
|
|
1792
|
-
paddingHorizontal: 8,
|
|
1793
|
-
gap: 8,
|
|
1794
|
-
borderRadius: 8
|
|
1795
|
-
};
|
|
1796
|
-
if (isActive && isNextSet) {
|
|
1797
|
-
rowStyle.backgroundColor = "rgba(255,121,0,0.06)";
|
|
1798
|
-
rowStyle.borderWidth = 1;
|
|
1799
|
-
rowStyle.borderColor = "rgba(255,121,0,0.15)";
|
|
1800
|
-
}
|
|
1801
|
-
if (isCompleted && !isNextSet) {
|
|
1802
|
-
rowStyle.opacity = 0.55;
|
|
1803
|
-
}
|
|
1804
|
-
return /* @__PURE__ */ jsxs(
|
|
1805
|
-
View,
|
|
1806
|
-
{
|
|
1807
|
-
style: rowStyle,
|
|
1808
|
-
accessibilityLabel: formatAccessibilityLabel(
|
|
1809
|
-
setNumber,
|
|
1810
|
-
reps,
|
|
1811
|
-
weight,
|
|
1812
|
-
unit
|
|
1813
|
-
),
|
|
1814
|
-
testID: "set-row",
|
|
1815
|
-
children: [
|
|
1816
|
-
/* @__PURE__ */ jsx(
|
|
1817
|
-
View,
|
|
1818
|
-
{
|
|
1819
|
-
style: { width: 36, alignItems: "center", justifyContent: "center" },
|
|
1820
|
-
testID: "set-row-set-number",
|
|
1821
|
-
children: setType ? /* @__PURE__ */ jsx(
|
|
1822
|
-
Text,
|
|
1823
|
-
{
|
|
1824
|
-
style: {
|
|
1825
|
-
fontSize: 10,
|
|
1826
|
-
fontWeight: "700",
|
|
1827
|
-
fontFamily: "Inter, sans-serif",
|
|
1828
|
-
color: "#ffa502",
|
|
1829
|
-
backgroundColor: "rgba(255,165,2,0.12)",
|
|
1830
|
-
paddingVertical: 1,
|
|
1831
|
-
paddingHorizontal: 5,
|
|
1832
|
-
borderRadius: 3,
|
|
1833
|
-
overflow: "hidden"
|
|
1834
|
-
},
|
|
1835
|
-
testID: "set-row-type-badge",
|
|
1836
|
-
children: setType
|
|
1837
|
-
}
|
|
1838
|
-
) : /* @__PURE__ */ jsx(
|
|
1839
|
-
Text,
|
|
1840
|
-
{
|
|
1841
|
-
className: "text-text-secondary",
|
|
1842
|
-
style: {
|
|
1843
|
-
fontSize: 13,
|
|
1844
|
-
fontWeight: "600",
|
|
1845
|
-
fontFamily: "Inter, sans-serif"
|
|
1846
|
-
},
|
|
1847
|
-
children: setNumber
|
|
1848
|
-
}
|
|
1849
|
-
)
|
|
1850
|
-
}
|
|
1851
|
-
),
|
|
1852
|
-
/* @__PURE__ */ jsx(
|
|
1853
|
-
View,
|
|
1854
|
-
{
|
|
1855
|
-
className: "flex-1",
|
|
1856
|
-
testID: "set-row-previous",
|
|
1857
|
-
children: /* @__PURE__ */ jsx(
|
|
1858
|
-
Text,
|
|
1859
|
-
{
|
|
1860
|
-
className: "text-text-secondary",
|
|
1861
|
-
style: {
|
|
1862
|
-
fontSize: 12,
|
|
1863
|
-
fontFamily: "Inter, sans-serif"
|
|
1864
|
-
},
|
|
1865
|
-
children: previous ? `${previous.reps} x ${roundWeight(previous.weight)}` : "\u2014"
|
|
1866
|
-
}
|
|
1867
|
-
)
|
|
1868
|
-
}
|
|
1869
|
-
),
|
|
1870
|
-
/* @__PURE__ */ jsx(
|
|
1871
|
-
View,
|
|
1872
|
-
{
|
|
1873
|
-
style: { width: 44, alignItems: "center", justifyContent: "center" },
|
|
1874
|
-
testID: "set-row-reps",
|
|
1875
|
-
children: isActive && reps == null && targets ? /* @__PURE__ */ jsx(
|
|
1876
|
-
Text,
|
|
1877
|
-
{
|
|
1878
|
-
className: "text-text-tertiary",
|
|
1879
|
-
style: {
|
|
1880
|
-
fontSize: 13,
|
|
1881
|
-
fontStyle: "italic",
|
|
1882
|
-
fontFamily: "Inter, sans-serif"
|
|
1883
|
-
},
|
|
1884
|
-
testID: "set-row-target-reps",
|
|
1885
|
-
children: targets.reps
|
|
1886
|
-
}
|
|
1887
|
-
) : /* @__PURE__ */ jsx(
|
|
1888
|
-
Text,
|
|
1889
|
-
{
|
|
1890
|
-
className: reps != null ? "text-text-primary" : "text-text-tertiary",
|
|
1891
|
-
style: {
|
|
1892
|
-
fontSize: 14,
|
|
1893
|
-
fontWeight: "600",
|
|
1894
|
-
fontFamily: "Inter, sans-serif"
|
|
1895
|
-
},
|
|
1896
|
-
children: reps != null ? reps : "\u2014"
|
|
1897
|
-
}
|
|
1898
|
-
)
|
|
1899
|
-
}
|
|
1900
|
-
),
|
|
1901
|
-
/* @__PURE__ */ jsx(
|
|
1902
|
-
View,
|
|
1903
|
-
{
|
|
1904
|
-
style: { width: 56, alignItems: "center", justifyContent: "center" },
|
|
1905
|
-
testID: "set-row-weight",
|
|
1906
|
-
children: isActive && weight == null && targets ? /* @__PURE__ */ jsx(
|
|
1907
|
-
Text,
|
|
1908
|
-
{
|
|
1909
|
-
className: "text-text-tertiary",
|
|
1910
|
-
style: {
|
|
1911
|
-
fontSize: 13,
|
|
1912
|
-
fontStyle: "italic",
|
|
1913
|
-
fontFamily: "Inter, sans-serif"
|
|
1914
|
-
},
|
|
1915
|
-
testID: "set-row-target-weight",
|
|
1916
|
-
children: roundWeight(targets.weight)
|
|
1917
|
-
}
|
|
1918
|
-
) : /* @__PURE__ */ jsx(
|
|
1919
|
-
Text,
|
|
1920
|
-
{
|
|
1921
|
-
className: weight != null ? "text-text-primary" : "text-text-tertiary",
|
|
1922
|
-
style: {
|
|
1923
|
-
fontSize: 14,
|
|
1924
|
-
fontWeight: "600",
|
|
1925
|
-
fontFamily: "Inter, sans-serif"
|
|
1926
|
-
},
|
|
1927
|
-
children: weight != null ? roundWeight(weight) : "\u2014"
|
|
1928
|
-
}
|
|
1929
|
-
)
|
|
1930
|
-
}
|
|
1931
|
-
),
|
|
1932
|
-
/* @__PURE__ */ jsx(
|
|
1933
|
-
View,
|
|
1934
|
-
{
|
|
1935
|
-
style: { width: 36, alignItems: "center", justifyContent: "center" },
|
|
1936
|
-
testID: "set-row-rpe",
|
|
1937
|
-
children: /* @__PURE__ */ jsx(
|
|
1938
|
-
Text,
|
|
1939
|
-
{
|
|
1940
|
-
className: rpe != null ? void 0 : "text-text-tertiary",
|
|
1941
|
-
style: {
|
|
1942
|
-
fontSize: 13,
|
|
1943
|
-
fontWeight: "600",
|
|
1944
|
-
fontFamily: "Inter, sans-serif",
|
|
1945
|
-
// rpeColor returns a concrete hex (native-safe); only the tertiary
|
|
1946
|
-
// fallback needs the className token.
|
|
1947
|
-
color: rpe != null ? rpeColor(rpe) : void 0
|
|
1948
|
-
},
|
|
1949
|
-
children: rpe != null ? roundRpe(rpe) : "\u2014"
|
|
1950
|
-
}
|
|
1951
|
-
)
|
|
1952
|
-
}
|
|
1953
|
-
),
|
|
1954
|
-
prBadges && prBadges.length > 0 && /* @__PURE__ */ jsx(
|
|
1955
|
-
View,
|
|
1956
|
-
{
|
|
1957
|
-
className: "flex-row items-center",
|
|
1958
|
-
style: { gap: 4 },
|
|
1959
|
-
testID: "set-row-pr-badges",
|
|
1960
|
-
children: prBadges.map((badge, i) => /* @__PURE__ */ jsx(
|
|
1961
|
-
PrBadge,
|
|
1962
|
-
{
|
|
1963
|
-
type: badge.type,
|
|
1964
|
-
label: badge.label,
|
|
1965
|
-
animate: false,
|
|
1966
|
-
compact: true
|
|
1967
|
-
},
|
|
1968
|
-
i
|
|
1969
|
-
))
|
|
1970
|
-
}
|
|
1971
|
-
),
|
|
1972
|
-
velocities && velocities.length > 0 && /* @__PURE__ */ jsx(
|
|
1973
|
-
View,
|
|
1974
|
-
{
|
|
1975
|
-
style: { position: "absolute", bottom: 0, left: 8, right: 8 },
|
|
1976
|
-
testID: "set-row-velocity-strip",
|
|
1977
|
-
children: /* @__PURE__ */ jsx(
|
|
1978
|
-
VelocityStrip,
|
|
1979
|
-
{
|
|
1980
|
-
velocities,
|
|
1981
|
-
zones: velocityZones,
|
|
1982
|
-
liveRepIndex: velocityLiveRepIndex,
|
|
1983
|
-
expanded: velocityExpanded,
|
|
1984
|
-
onToggle: onVelocityToggle,
|
|
1985
|
-
variant: onVelocityToggle ? "full" : "mini"
|
|
1986
|
-
}
|
|
1987
|
-
)
|
|
2325
|
+
View,
|
|
2326
|
+
{
|
|
2327
|
+
style: {
|
|
2328
|
+
backgroundColor: "#191919",
|
|
2329
|
+
borderRadius: 6,
|
|
2330
|
+
paddingVertical: 8,
|
|
2331
|
+
paddingHorizontal: 12,
|
|
2332
|
+
borderWidth: 1,
|
|
2333
|
+
borderColor: "#2C2C2C"
|
|
2334
|
+
},
|
|
2335
|
+
children: [
|
|
2336
|
+
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
2337
|
+
"Eccentric: ",
|
|
2338
|
+
eccentric,
|
|
2339
|
+
"s"
|
|
2340
|
+
] }),
|
|
2341
|
+
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
2342
|
+
"Pause (bottom): ",
|
|
2343
|
+
pauseBottom,
|
|
2344
|
+
"s"
|
|
2345
|
+
] }),
|
|
2346
|
+
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
2347
|
+
"Concentric: ",
|
|
2348
|
+
concentric,
|
|
2349
|
+
"s"
|
|
2350
|
+
] }),
|
|
2351
|
+
/* @__PURE__ */ jsxs(Text, { style: { fontSize: 10, lineHeight: 16, color: "#9CA3AF", fontFamily: INTER }, children: [
|
|
2352
|
+
"Pause (top): ",
|
|
2353
|
+
pauseTop,
|
|
2354
|
+
"s"
|
|
2355
|
+
] })
|
|
2356
|
+
]
|
|
2357
|
+
}
|
|
2358
|
+
),
|
|
2359
|
+
/* @__PURE__ */ jsx(
|
|
2360
|
+
View,
|
|
2361
|
+
{
|
|
2362
|
+
style: {
|
|
2363
|
+
width: 0,
|
|
2364
|
+
height: 0,
|
|
2365
|
+
borderLeftWidth: 5,
|
|
2366
|
+
borderRightWidth: 5,
|
|
2367
|
+
borderTopWidth: 5,
|
|
2368
|
+
borderLeftColor: "transparent",
|
|
2369
|
+
borderRightColor: "transparent",
|
|
2370
|
+
borderTopColor: "#2C2C2C"
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
)
|
|
2374
|
+
]
|
|
1988
2375
|
}
|
|
1989
2376
|
)
|
|
1990
2377
|
]
|
|
1991
2378
|
}
|
|
1992
2379
|
);
|
|
1993
2380
|
}
|
|
1994
|
-
|
|
1995
|
-
|
|
2381
|
+
var t4 = getSemanticColors("dark");
|
|
2382
|
+
var INDICATOR_CONFIG = {
|
|
2383
|
+
imbalance: { Icon: ScaleIcon, color: t4["status-error"], label: "Left/right imbalance" },
|
|
2384
|
+
overshoot: { Icon: AlertTriangleIcon, color: t4["status-error"], label: "Load overshoot" },
|
|
2385
|
+
"velocity-loss": { Icon: TrendingDownIcon, color: t4["status-warning"], label: "Velocity loss" },
|
|
2386
|
+
"missed-reps": { Icon: CircleSlashIcon, color: t4["status-warning"], label: "Missed reps" },
|
|
2387
|
+
pr: { Icon: AwardIcon, color: t4["status-success"], label: "Personal record" },
|
|
2388
|
+
info: { Icon: InfoIcon, color: t4["status-info"], label: "More info" }
|
|
2389
|
+
};
|
|
2390
|
+
function ExerciseIndicator({ kind, onPress, className, ...props }) {
|
|
2391
|
+
const { Icon, color, label } = INDICATOR_CONFIG[kind];
|
|
2392
|
+
const chip = /* @__PURE__ */ jsx(
|
|
2393
|
+
View,
|
|
2394
|
+
{
|
|
2395
|
+
className,
|
|
2396
|
+
style: {
|
|
2397
|
+
width: 16,
|
|
2398
|
+
height: 16,
|
|
2399
|
+
borderRadius: 8,
|
|
2400
|
+
borderWidth: 1,
|
|
2401
|
+
borderColor: color,
|
|
2402
|
+
alignItems: "center",
|
|
2403
|
+
justifyContent: "center"
|
|
2404
|
+
},
|
|
2405
|
+
accessibilityRole: "image",
|
|
2406
|
+
accessibilityLabel: label,
|
|
2407
|
+
testID: "exercise-indicator",
|
|
2408
|
+
...props,
|
|
2409
|
+
children: /* @__PURE__ */ jsx(Icon, { size: 11, color })
|
|
2410
|
+
}
|
|
2411
|
+
);
|
|
2412
|
+
if (onPress) {
|
|
2413
|
+
return /* @__PURE__ */ jsx(Pressable, { onPress, accessibilityRole: "button", accessibilityLabel: label, children: chip });
|
|
2414
|
+
}
|
|
2415
|
+
return chip;
|
|
1996
2416
|
}
|
|
1997
2417
|
|
|
1998
|
-
// src/components/custom/Workout/
|
|
1999
|
-
function
|
|
2000
|
-
return
|
|
2418
|
+
// src/components/custom/Workout/ExerciseHeading.tsx
|
|
2419
|
+
function headingLabel(name, sets, reps, load, unit) {
|
|
2420
|
+
return `${name}, ${sets}\xD7${reps} @ ${roundWeight(load)} ${unit}`;
|
|
2421
|
+
}
|
|
2422
|
+
function ExerciseHeading({
|
|
2423
|
+
name,
|
|
2424
|
+
sets,
|
|
2425
|
+
reps,
|
|
2426
|
+
load,
|
|
2427
|
+
unit = "lbs",
|
|
2428
|
+
tempo,
|
|
2429
|
+
indicator,
|
|
2430
|
+
dimmed,
|
|
2431
|
+
onPress
|
|
2432
|
+
}) {
|
|
2433
|
+
return /* @__PURE__ */ jsxs(View, { style: { opacity: dimmed ? 0.55 : 1 }, testID: "exercise-heading", children: [
|
|
2434
|
+
/* @__PURE__ */ jsxs(
|
|
2435
|
+
Pressable,
|
|
2436
|
+
{
|
|
2437
|
+
onPress,
|
|
2438
|
+
accessibilityRole: "button",
|
|
2439
|
+
accessibilityLabel: headingLabel(name, sets, reps, load, unit),
|
|
2440
|
+
className: "flex-row items-center",
|
|
2441
|
+
style: { gap: 8 },
|
|
2442
|
+
testID: "exercise-card-header",
|
|
2443
|
+
children: [
|
|
2444
|
+
/* @__PURE__ */ jsx(
|
|
2445
|
+
Text,
|
|
2446
|
+
{
|
|
2447
|
+
className: "text-text-primary",
|
|
2448
|
+
style: { fontSize: 14, fontFamily: '"Space Grotesk", sans-serif', fontWeight: "700" },
|
|
2449
|
+
testID: "exercise-card-name",
|
|
2450
|
+
children: name
|
|
2451
|
+
}
|
|
2452
|
+
),
|
|
2453
|
+
/* @__PURE__ */ jsx(View, { className: "flex-1" }),
|
|
2454
|
+
indicator && /* @__PURE__ */ jsx(ExerciseIndicator, { kind: indicator })
|
|
2455
|
+
]
|
|
2456
|
+
}
|
|
2457
|
+
),
|
|
2458
|
+
/* @__PURE__ */ jsxs(
|
|
2459
|
+
View,
|
|
2460
|
+
{
|
|
2461
|
+
className: "flex-row items-center",
|
|
2462
|
+
style: { gap: 8, marginTop: 1 },
|
|
2463
|
+
testID: "exercise-card-summary",
|
|
2464
|
+
children: [
|
|
2465
|
+
/* @__PURE__ */ jsx(SetsRepsLoad, { sets, reps, load, unit }),
|
|
2466
|
+
/* @__PURE__ */ jsx(View, { className: "flex-1" }),
|
|
2467
|
+
tempo && /* @__PURE__ */ jsx(TempoDisplay, { tempo, size: "sm", showLabel: false, showInfo: false })
|
|
2468
|
+
]
|
|
2469
|
+
}
|
|
2470
|
+
)
|
|
2471
|
+
] });
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
// src/components/custom/Workout/ExerciseCardHeading.tsx
|
|
2475
|
+
function ExerciseCardHeading({
|
|
2476
|
+
setStates,
|
|
2477
|
+
stripHeight = 8,
|
|
2478
|
+
dimmed,
|
|
2479
|
+
testID = "exercise-card",
|
|
2480
|
+
...heading
|
|
2481
|
+
}) {
|
|
2482
|
+
return /* @__PURE__ */ jsxs(
|
|
2483
|
+
View,
|
|
2484
|
+
{
|
|
2485
|
+
style: { paddingVertical: 9, paddingHorizontal: 12, opacity: dimmed ? 0.55 : 1 },
|
|
2486
|
+
testID,
|
|
2487
|
+
children: [
|
|
2488
|
+
/* @__PURE__ */ jsx(ExerciseHeading, { ...heading }),
|
|
2489
|
+
setStates.length > 0 && /* @__PURE__ */ jsx(View, { style: { marginTop: 7 }, testID: "exercise-card-strip", children: /* @__PURE__ */ jsx(SetStrip, { sets: setStates, height: stripHeight }) })
|
|
2490
|
+
]
|
|
2491
|
+
}
|
|
2492
|
+
);
|
|
2001
2493
|
}
|
|
2494
|
+
|
|
2495
|
+
// src/components/custom/Workout/ExerciseCard.tsx
|
|
2002
2496
|
function getSupersetBorderRadius(position) {
|
|
2003
2497
|
switch (position) {
|
|
2004
2498
|
case "first":
|
|
@@ -2041,7 +2535,7 @@ function formatSummary(summary) {
|
|
|
2041
2535
|
if (!summary) return "";
|
|
2042
2536
|
return `${summary.sets}\xD7${summary.reps} @ ${roundWeight(summary.weight)} ${summary.unit}`;
|
|
2043
2537
|
}
|
|
2044
|
-
function
|
|
2538
|
+
function formatAccessibilityLabel(name, summary, prescription) {
|
|
2045
2539
|
if (summary) return `${name}, ${formatSummary(summary)}`;
|
|
2046
2540
|
if (prescription) return `${name}, ${prescription}`;
|
|
2047
2541
|
return name;
|
|
@@ -2050,7 +2544,6 @@ function CollapsedCard({
|
|
|
2050
2544
|
name,
|
|
2051
2545
|
onToggle,
|
|
2052
2546
|
summary,
|
|
2053
|
-
e1rm,
|
|
2054
2547
|
isPR,
|
|
2055
2548
|
setVelocities,
|
|
2056
2549
|
velocityZones,
|
|
@@ -2069,7 +2562,7 @@ function CollapsedCard({
|
|
|
2069
2562
|
onPressIn: () => setPressed(true),
|
|
2070
2563
|
onPressOut: () => setPressed(false),
|
|
2071
2564
|
accessibilityRole: "button",
|
|
2072
|
-
accessibilityLabel:
|
|
2565
|
+
accessibilityLabel: formatAccessibilityLabel(name, summary, void 0),
|
|
2073
2566
|
testID: "exercise-card",
|
|
2074
2567
|
children: /* @__PURE__ */ jsxs(
|
|
2075
2568
|
View,
|
|
@@ -2083,100 +2576,93 @@ function CollapsedCard({
|
|
|
2083
2576
|
...supersetMargin
|
|
2084
2577
|
},
|
|
2085
2578
|
children: [
|
|
2086
|
-
/* @__PURE__ */ jsxs(
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
{
|
|
2136
|
-
className: "flex-row",
|
|
2137
|
-
style: { marginTop: 6, gap: 4 },
|
|
2138
|
-
testID: "exercise-card-strips",
|
|
2139
|
-
children: [
|
|
2140
|
-
setVelocities?.map((velocities, i) => /* @__PURE__ */ jsx(
|
|
2141
|
-
VelocityStrip,
|
|
2142
|
-
{
|
|
2143
|
-
velocities,
|
|
2144
|
-
zones: velocityZones,
|
|
2145
|
-
variant: "mini",
|
|
2146
|
-
testID: `exercise-card-velocity-strip-${i}`
|
|
2147
|
-
},
|
|
2148
|
-
i
|
|
2149
|
-
)),
|
|
2150
|
-
Array.from({ length: remaining }, (_, i) => /* @__PURE__ */ jsx(
|
|
2151
|
-
PlaceholderStrip,
|
|
2152
|
-
{
|
|
2153
|
-
testID: `exercise-card-placeholder-${i}`
|
|
2154
|
-
},
|
|
2155
|
-
`placeholder-${i}`
|
|
2156
|
-
))
|
|
2157
|
-
]
|
|
2158
|
-
}
|
|
2159
|
-
)
|
|
2579
|
+
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center", testID: "exercise-card-header", children: [
|
|
2580
|
+
/* @__PURE__ */ jsx(
|
|
2581
|
+
Text,
|
|
2582
|
+
{
|
|
2583
|
+
className: "text-text-primary",
|
|
2584
|
+
style: {
|
|
2585
|
+
fontSize: 14,
|
|
2586
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
2587
|
+
fontWeight: "700"
|
|
2588
|
+
},
|
|
2589
|
+
testID: "exercise-card-name",
|
|
2590
|
+
children: name
|
|
2591
|
+
}
|
|
2592
|
+
),
|
|
2593
|
+
/* @__PURE__ */ jsx(View, { className: "flex-1" }),
|
|
2594
|
+
summary && /* @__PURE__ */ jsx(
|
|
2595
|
+
Text,
|
|
2596
|
+
{
|
|
2597
|
+
className: "text-text-secondary",
|
|
2598
|
+
style: {
|
|
2599
|
+
fontSize: 12,
|
|
2600
|
+
fontFamily: "Inter, sans-serif",
|
|
2601
|
+
marginRight: 8
|
|
2602
|
+
},
|
|
2603
|
+
testID: "exercise-card-summary",
|
|
2604
|
+
children: formatSummary(summary)
|
|
2605
|
+
}
|
|
2606
|
+
),
|
|
2607
|
+
isPR && /* @__PURE__ */ jsx(View, { style: { marginLeft: 4 }, children: /* @__PURE__ */ jsx(PrBadge, { type: "e1rm", compact: true, animate: false }) })
|
|
2608
|
+
] }),
|
|
2609
|
+
(completedSets > 0 || remaining > 0) && /* @__PURE__ */ jsxs(View, { className: "flex-row", style: { marginTop: 6, gap: 4 }, testID: "exercise-card-strips", children: [
|
|
2610
|
+
setVelocities?.map((velocities, i) => /* @__PURE__ */ jsx(
|
|
2611
|
+
VelocityStrip,
|
|
2612
|
+
{
|
|
2613
|
+
velocities,
|
|
2614
|
+
zones: velocityZones,
|
|
2615
|
+
variant: "mini",
|
|
2616
|
+
testID: `exercise-card-velocity-strip-${i}`
|
|
2617
|
+
},
|
|
2618
|
+
i
|
|
2619
|
+
)),
|
|
2620
|
+
Array.from({ length: remaining }, (_, i) => /* @__PURE__ */ jsx(
|
|
2621
|
+
PlaceholderStrip,
|
|
2622
|
+
{
|
|
2623
|
+
testID: `exercise-card-placeholder-${i}`
|
|
2624
|
+
},
|
|
2625
|
+
`placeholder-${i}`
|
|
2626
|
+
))
|
|
2627
|
+
] })
|
|
2160
2628
|
]
|
|
2161
2629
|
}
|
|
2162
2630
|
)
|
|
2163
2631
|
}
|
|
2164
2632
|
);
|
|
2165
2633
|
}
|
|
2634
|
+
var DARK2 = getSemanticColors("dark");
|
|
2635
|
+
var BODY_DIVIDER = DARK2["border-subtle"];
|
|
2636
|
+
function deriveHeaderSetStates(sets) {
|
|
2637
|
+
return sets.map((set) => {
|
|
2638
|
+
switch (set.state) {
|
|
2639
|
+
case "live":
|
|
2640
|
+
return { status: "active", velocities: set.velocities, planned: set.target.reps };
|
|
2641
|
+
case "done":
|
|
2642
|
+
return { status: "done", velocities: set.velocities };
|
|
2643
|
+
case "todo":
|
|
2644
|
+
return { status: "todo", planned: set.planned ?? set.target.reps };
|
|
2645
|
+
}
|
|
2646
|
+
});
|
|
2647
|
+
}
|
|
2166
2648
|
function ExpandedCard({
|
|
2167
2649
|
name,
|
|
2168
2650
|
onToggle,
|
|
2169
2651
|
summary,
|
|
2170
|
-
e1rm,
|
|
2171
2652
|
isPR,
|
|
2172
2653
|
sets,
|
|
2173
2654
|
tempo,
|
|
2655
|
+
indicator,
|
|
2656
|
+
setStates,
|
|
2657
|
+
stripHeight = 8,
|
|
2658
|
+
velocityZones,
|
|
2174
2659
|
supersetPosition
|
|
2175
2660
|
}) {
|
|
2176
2661
|
const borderRadius = getSupersetBorderRadius(supersetPosition);
|
|
2177
2662
|
const supersetMargin = getSupersetMargin(supersetPosition);
|
|
2178
2663
|
const unit = summary?.unit ?? sets?.[0]?.unit ?? "lbs";
|
|
2179
|
-
const
|
|
2664
|
+
const headerStates = setStates ?? (sets ? deriveHeaderSetStates(sets) : []);
|
|
2665
|
+
const headerIndicator = indicator ?? (isPR ? "pr" : void 0);
|
|
2180
2666
|
return /* @__PURE__ */ jsxs(
|
|
2181
2667
|
View,
|
|
2182
2668
|
{
|
|
@@ -2189,114 +2675,32 @@ function ExpandedCard({
|
|
|
2189
2675
|
testID: "exercise-card",
|
|
2190
2676
|
children: [
|
|
2191
2677
|
/* @__PURE__ */ jsx(
|
|
2192
|
-
|
|
2678
|
+
ExerciseCardHeading,
|
|
2193
2679
|
{
|
|
2680
|
+
name,
|
|
2681
|
+
sets: summary?.sets ?? sets?.length ?? 0,
|
|
2682
|
+
reps: summary?.reps ?? 0,
|
|
2683
|
+
load: summary?.weight ?? 0,
|
|
2684
|
+
unit,
|
|
2685
|
+
tempo,
|
|
2686
|
+
indicator: headerIndicator,
|
|
2687
|
+
setStates: headerStates,
|
|
2688
|
+
stripHeight,
|
|
2194
2689
|
onPress: onToggle,
|
|
2195
|
-
|
|
2196
|
-
accessibilityLabel: formatAccessibilityLabel2(name, summary, void 0),
|
|
2197
|
-
"aria-expanded": true,
|
|
2198
|
-
testID: "exercise-card-header",
|
|
2199
|
-
children: /* @__PURE__ */ jsxs(
|
|
2200
|
-
View,
|
|
2201
|
-
{
|
|
2202
|
-
className: "flex-row items-center",
|
|
2203
|
-
style: {
|
|
2204
|
-
padding: 12,
|
|
2205
|
-
paddingHorizontal: 14,
|
|
2206
|
-
paddingBottom: 10,
|
|
2207
|
-
borderBottomWidth: 1,
|
|
2208
|
-
borderBottomColor: resolveColor("border-default")
|
|
2209
|
-
},
|
|
2210
|
-
children: [
|
|
2211
|
-
/* @__PURE__ */ jsx(
|
|
2212
|
-
Text,
|
|
2213
|
-
{
|
|
2214
|
-
className: "text-text-primary",
|
|
2215
|
-
style: {
|
|
2216
|
-
fontSize: 14,
|
|
2217
|
-
fontFamily: '"Space Grotesk", sans-serif',
|
|
2218
|
-
fontWeight: "700"
|
|
2219
|
-
},
|
|
2220
|
-
testID: "exercise-card-name",
|
|
2221
|
-
children: name
|
|
2222
|
-
}
|
|
2223
|
-
),
|
|
2224
|
-
/* @__PURE__ */ jsx(View, { className: "flex-1" }),
|
|
2225
|
-
summary && /* @__PURE__ */ jsx(
|
|
2226
|
-
Text,
|
|
2227
|
-
{
|
|
2228
|
-
className: "text-text-secondary",
|
|
2229
|
-
style: {
|
|
2230
|
-
fontSize: 12,
|
|
2231
|
-
fontFamily: "Inter, sans-serif",
|
|
2232
|
-
marginRight: 8
|
|
2233
|
-
},
|
|
2234
|
-
testID: "exercise-card-summary",
|
|
2235
|
-
children: formatSummary(summary)
|
|
2236
|
-
}
|
|
2237
|
-
),
|
|
2238
|
-
e1rm && /* @__PURE__ */ jsx(
|
|
2239
|
-
WeightBadge,
|
|
2240
|
-
{
|
|
2241
|
-
value: roundWeight(e1rm.value),
|
|
2242
|
-
unit: e1rm.unit,
|
|
2243
|
-
size: "sm",
|
|
2244
|
-
showIcon: false,
|
|
2245
|
-
testID: "exercise-card-e1rm"
|
|
2246
|
-
}
|
|
2247
|
-
),
|
|
2248
|
-
isPR && /* @__PURE__ */ jsx(View, { style: { marginLeft: 4 }, children: /* @__PURE__ */ jsx(PrBadge, { type: "e1rm", compact: true, animate: false }) })
|
|
2249
|
-
]
|
|
2250
|
-
}
|
|
2251
|
-
)
|
|
2690
|
+
testID: "exercise-card-heading"
|
|
2252
2691
|
}
|
|
2253
2692
|
),
|
|
2254
|
-
|
|
2255
|
-
/* @__PURE__ */ jsx(
|
|
2693
|
+
/* @__PURE__ */ jsxs(
|
|
2256
2694
|
View,
|
|
2257
2695
|
{
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
testID: "exercise-card-column-headers",
|
|
2265
|
-
children: columnHeaders.map((header, i) => {
|
|
2266
|
-
const widths = [36, void 0, 44, 56, 36];
|
|
2267
|
-
const width = widths[i];
|
|
2268
|
-
const isFlex = width === void 0;
|
|
2269
|
-
return /* @__PURE__ */ jsx(
|
|
2270
|
-
View,
|
|
2271
|
-
{
|
|
2272
|
-
style: {
|
|
2273
|
-
...isFlex ? {} : { width },
|
|
2274
|
-
alignItems: "center",
|
|
2275
|
-
justifyContent: "center",
|
|
2276
|
-
gap: 8
|
|
2277
|
-
},
|
|
2278
|
-
...isFlex ? { className: "flex-1" } : {},
|
|
2279
|
-
children: /* @__PURE__ */ jsx(
|
|
2280
|
-
Text,
|
|
2281
|
-
{
|
|
2282
|
-
className: "text-text-tertiary",
|
|
2283
|
-
style: {
|
|
2284
|
-
fontSize: 10,
|
|
2285
|
-
fontWeight: "600",
|
|
2286
|
-
fontFamily: "Inter, sans-serif",
|
|
2287
|
-
textTransform: "uppercase",
|
|
2288
|
-
letterSpacing: 0.8
|
|
2289
|
-
},
|
|
2290
|
-
children: header
|
|
2291
|
-
}
|
|
2292
|
-
)
|
|
2293
|
-
},
|
|
2294
|
-
header
|
|
2295
|
-
);
|
|
2296
|
-
})
|
|
2696
|
+
style: { borderTopWidth: 1, borderTopColor: BODY_DIVIDER, paddingBottom: 6 },
|
|
2697
|
+
testID: "exercise-card-body",
|
|
2698
|
+
children: [
|
|
2699
|
+
/* @__PURE__ */ jsx(SetTableHeader, { unit, showPrevious: false, testID: "exercise-card-column-headers" }),
|
|
2700
|
+
sets && /* @__PURE__ */ jsx(View, { testID: "exercise-card-sets", children: sets.map((set, i) => /* @__PURE__ */ jsx(SetRow, { ...set, velocityZones: set.velocityZones ?? velocityZones }, i)) })
|
|
2701
|
+
]
|
|
2297
2702
|
}
|
|
2298
|
-
)
|
|
2299
|
-
sets && /* @__PURE__ */ jsx(View, { testID: "exercise-card-sets", children: sets.map((setProps, i) => /* @__PURE__ */ jsx(SetRow, { ...setProps }, i)) })
|
|
2703
|
+
)
|
|
2300
2704
|
]
|
|
2301
2705
|
}
|
|
2302
2706
|
);
|
|
@@ -2305,11 +2709,12 @@ function UpcomingCard({
|
|
|
2305
2709
|
name,
|
|
2306
2710
|
prescription,
|
|
2307
2711
|
previousBest,
|
|
2308
|
-
supersetPosition
|
|
2712
|
+
supersetPosition,
|
|
2713
|
+
onToggle
|
|
2309
2714
|
}) {
|
|
2310
2715
|
const borderRadius = getSupersetBorderRadius(supersetPosition);
|
|
2311
2716
|
const supersetMargin = getSupersetMargin(supersetPosition);
|
|
2312
|
-
return /* @__PURE__ */ jsx(
|
|
2717
|
+
return /* @__PURE__ */ jsx(Pressable, { onPress: onToggle, accessibilityRole: "button", children: /* @__PURE__ */ jsx(
|
|
2313
2718
|
View,
|
|
2314
2719
|
{
|
|
2315
2720
|
style: {
|
|
@@ -2319,7 +2724,7 @@ function UpcomingCard({
|
|
|
2319
2724
|
...borderRadius,
|
|
2320
2725
|
...supersetMargin
|
|
2321
2726
|
},
|
|
2322
|
-
accessibilityLabel:
|
|
2727
|
+
accessibilityLabel: formatAccessibilityLabel(name, void 0, prescription),
|
|
2323
2728
|
testID: "exercise-card",
|
|
2324
2729
|
children: /* @__PURE__ */ jsxs(View, { className: "flex-row items-center", children: [
|
|
2325
2730
|
/* @__PURE__ */ jsx(
|
|
@@ -2327,6 +2732,7 @@ function UpcomingCard({
|
|
|
2327
2732
|
{
|
|
2328
2733
|
className: "text-text-primary",
|
|
2329
2734
|
style: {
|
|
2735
|
+
flexShrink: 0,
|
|
2330
2736
|
fontSize: 14,
|
|
2331
2737
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
2332
2738
|
fontWeight: "700"
|
|
@@ -2339,7 +2745,9 @@ function UpcomingCard({
|
|
|
2339
2745
|
Text,
|
|
2340
2746
|
{
|
|
2341
2747
|
className: "text-text-secondary",
|
|
2748
|
+
numberOfLines: 1,
|
|
2342
2749
|
style: {
|
|
2750
|
+
flexShrink: 1,
|
|
2343
2751
|
fontSize: 12,
|
|
2344
2752
|
fontFamily: "Inter, sans-serif",
|
|
2345
2753
|
marginLeft: 8
|
|
@@ -2348,12 +2756,14 @@ function UpcomingCard({
|
|
|
2348
2756
|
children: prescription
|
|
2349
2757
|
}
|
|
2350
2758
|
),
|
|
2351
|
-
/* @__PURE__ */ jsx(View, { className: "flex-1" }),
|
|
2759
|
+
/* @__PURE__ */ jsx(View, { className: "flex-1", style: { minWidth: 8 } }),
|
|
2352
2760
|
previousBest && /* @__PURE__ */ jsx(
|
|
2353
2761
|
Text,
|
|
2354
2762
|
{
|
|
2355
2763
|
className: "text-text-tertiary",
|
|
2764
|
+
numberOfLines: 1,
|
|
2356
2765
|
style: {
|
|
2766
|
+
flexShrink: 1,
|
|
2357
2767
|
fontSize: 11,
|
|
2358
2768
|
fontFamily: "Inter, sans-serif"
|
|
2359
2769
|
},
|
|
@@ -2363,19 +2773,32 @@ function UpcomingCard({
|
|
|
2363
2773
|
)
|
|
2364
2774
|
] })
|
|
2365
2775
|
}
|
|
2366
|
-
);
|
|
2776
|
+
) });
|
|
2367
2777
|
}
|
|
2368
|
-
function ExerciseCard(
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2778
|
+
function ExerciseCard({
|
|
2779
|
+
upcoming,
|
|
2780
|
+
expanded,
|
|
2781
|
+
defaultExpanded,
|
|
2782
|
+
onExpandedChange,
|
|
2783
|
+
...rest
|
|
2784
|
+
}) {
|
|
2785
|
+
const [internalExpanded, setInternalExpanded] = useState(defaultExpanded ?? false);
|
|
2786
|
+
const isControlled = expanded !== void 0;
|
|
2787
|
+
const isExpanded = isControlled ? expanded : internalExpanded;
|
|
2788
|
+
const onToggle = () => {
|
|
2789
|
+
const next = !isExpanded;
|
|
2790
|
+
onExpandedChange?.(next);
|
|
2791
|
+
if (!isControlled) setInternalExpanded(next);
|
|
2792
|
+
};
|
|
2793
|
+
if (upcoming) return /* @__PURE__ */ jsx(UpcomingCard, { ...rest, onToggle });
|
|
2794
|
+
return isExpanded ? /* @__PURE__ */ jsx(ExpandedCard, { ...rest, onToggle }) : /* @__PURE__ */ jsx(CollapsedCard, { ...rest, onToggle });
|
|
2377
2795
|
}
|
|
2378
|
-
|
|
2796
|
+
function resolveColor(token, mode = "dark") {
|
|
2797
|
+
return Platform.OS === "web" ? `var(--color-${token})` : getSemanticColors(mode)[token];
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
// src/components/custom/Workout/InputBar.tsx
|
|
2801
|
+
var BRAND_PRIMARY2 = getSemanticColors("dark")["brand-primary"];
|
|
2379
2802
|
var INPUT_CLASSNAME = "bg-surface-raised border-border-strong text-text-primary";
|
|
2380
2803
|
var inputStyle = {
|
|
2381
2804
|
fontSize: 14,
|
|
@@ -2504,7 +2927,7 @@ function InputBar({
|
|
|
2504
2927
|
onPress: onRecord,
|
|
2505
2928
|
disabled: !canRecord,
|
|
2506
2929
|
style: ({ pressed }) => ({
|
|
2507
|
-
backgroundColor:
|
|
2930
|
+
backgroundColor: BRAND_PRIMARY2,
|
|
2508
2931
|
borderRadius: 8,
|
|
2509
2932
|
paddingVertical: 10,
|
|
2510
2933
|
paddingHorizontal: 16,
|
|
@@ -2531,7 +2954,46 @@ function InputBar({
|
|
|
2531
2954
|
}
|
|
2532
2955
|
);
|
|
2533
2956
|
}
|
|
2534
|
-
|
|
2957
|
+
function formatDuration(ms) {
|
|
2958
|
+
const totalSeconds = Math.max(0, Math.ceil(ms / 1e3));
|
|
2959
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
2960
|
+
const seconds = totalSeconds % 60;
|
|
2961
|
+
return `${minutes}:${String(seconds).padStart(2, "0")}`;
|
|
2962
|
+
}
|
|
2963
|
+
function useTimer(options = {}) {
|
|
2964
|
+
const {
|
|
2965
|
+
mode = "up",
|
|
2966
|
+
durationMs,
|
|
2967
|
+
elapsedMs: controlledElapsedMs,
|
|
2968
|
+
running = false,
|
|
2969
|
+
autoTick = false,
|
|
2970
|
+
tickMs = 1e3
|
|
2971
|
+
} = options;
|
|
2972
|
+
const isControlled = controlledElapsedMs != null;
|
|
2973
|
+
const [internalElapsedMs, setInternalElapsedMs] = useState(0);
|
|
2974
|
+
useEffect(() => {
|
|
2975
|
+
if (isControlled || !autoTick || !running) return;
|
|
2976
|
+
const id = setInterval(() => {
|
|
2977
|
+
setInternalElapsedMs((prev) => prev + tickMs);
|
|
2978
|
+
}, tickMs);
|
|
2979
|
+
return () => clearInterval(id);
|
|
2980
|
+
}, [isControlled, autoTick, running, tickMs]);
|
|
2981
|
+
const elapsedMs = isControlled ? controlledElapsedMs : internalElapsedMs;
|
|
2982
|
+
const hasDuration = durationMs != null && durationMs > 0;
|
|
2983
|
+
const remainingMs = durationMs != null ? Math.max(0, durationMs - elapsedMs) : 0;
|
|
2984
|
+
let progress;
|
|
2985
|
+
if (hasDuration) {
|
|
2986
|
+
progress = Math.min(1, Math.max(0, elapsedMs / durationMs));
|
|
2987
|
+
} else {
|
|
2988
|
+
progress = mode === "down" ? 1 : 0;
|
|
2989
|
+
}
|
|
2990
|
+
const label = formatDuration(mode === "down" ? remainingMs : elapsedMs);
|
|
2991
|
+
const done = durationMs != null && elapsedMs >= durationMs;
|
|
2992
|
+
return { elapsedMs, remainingMs, progress, label, done };
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
// src/components/custom/Workout/RestTimer.tsx
|
|
2996
|
+
var BRAND_PRIMARY3 = getSemanticColors("dark")["brand-primary"];
|
|
2535
2997
|
function RestTimer({
|
|
2536
2998
|
totalSeconds,
|
|
2537
2999
|
elapsedMs,
|
|
@@ -2541,14 +3003,18 @@ function RestTimer({
|
|
|
2541
3003
|
visible,
|
|
2542
3004
|
displayOnly = false
|
|
2543
3005
|
}) {
|
|
2544
|
-
|
|
2545
|
-
|
|
3006
|
+
const {
|
|
3007
|
+
remainingMs,
|
|
3008
|
+
progress,
|
|
3009
|
+
label: timeDisplay
|
|
3010
|
+
} = useTimer({
|
|
3011
|
+
mode: "down",
|
|
3012
|
+
durationMs: totalSeconds * 1e3,
|
|
3013
|
+
elapsedMs
|
|
3014
|
+
});
|
|
2546
3015
|
const remainingSec = Math.ceil(remainingMs / 1e3);
|
|
2547
|
-
const
|
|
2548
|
-
|
|
2549
|
-
const timeDisplay = `${minutes}:${String(seconds).padStart(2, "0")}`;
|
|
2550
|
-
const totalMs = totalSeconds * 1e3;
|
|
2551
|
-
const progressPct = totalMs > 0 ? Math.min(100, elapsedMs / totalMs * 100) : 100;
|
|
3016
|
+
const progressPct = progress * 100;
|
|
3017
|
+
if (!visible) return null;
|
|
2552
3018
|
return /* @__PURE__ */ jsxs(
|
|
2553
3019
|
View,
|
|
2554
3020
|
{
|
|
@@ -2637,7 +3103,7 @@ function RestTimer({
|
|
|
2637
3103
|
{
|
|
2638
3104
|
style: {
|
|
2639
3105
|
height: "100%",
|
|
2640
|
-
backgroundColor:
|
|
3106
|
+
backgroundColor: BRAND_PRIMARY3,
|
|
2641
3107
|
borderRadius: 2,
|
|
2642
3108
|
width: `${progressPct}%`
|
|
2643
3109
|
},
|
|
@@ -2694,7 +3160,7 @@ function RestTimer({
|
|
|
2694
3160
|
fontSize: 11,
|
|
2695
3161
|
fontFamily: "Inter, sans-serif",
|
|
2696
3162
|
fontWeight: "600",
|
|
2697
|
-
color:
|
|
3163
|
+
color: BRAND_PRIMARY3
|
|
2698
3164
|
},
|
|
2699
3165
|
children: "Skip"
|
|
2700
3166
|
}
|
|
@@ -2708,7 +3174,7 @@ function RestTimer({
|
|
|
2708
3174
|
}
|
|
2709
3175
|
var DEFAULTS = {
|
|
2710
3176
|
label: "SS",
|
|
2711
|
-
color: "
|
|
3177
|
+
color: getSemanticColors("dark")["brand-primary"],
|
|
2712
3178
|
bgBase: "#101010"
|
|
2713
3179
|
};
|
|
2714
3180
|
function SupersetWrapper({
|
|
@@ -2761,7 +3227,7 @@ function SupersetWrapper({
|
|
|
2761
3227
|
}
|
|
2762
3228
|
|
|
2763
3229
|
// src/components/custom/Workout/ActiveWorkoutPage.tsx
|
|
2764
|
-
var
|
|
3230
|
+
var BRAND_PRIMARY4 = getSemanticColors("dark")["brand-primary"];
|
|
2765
3231
|
function countCompletedSets(exercise) {
|
|
2766
3232
|
if (exercise.setVelocities != null) return exercise.setVelocities.length;
|
|
2767
3233
|
if (exercise.status === "completed") return exercise.totalPlannedSets;
|
|
@@ -2787,23 +3253,22 @@ function deriveWorkoutProgress(exercises) {
|
|
|
2787
3253
|
function findActiveExercise(exercises) {
|
|
2788
3254
|
return exercises.find((exercise) => exercise.status === "active") ?? null;
|
|
2789
3255
|
}
|
|
2790
|
-
function
|
|
2791
|
-
|
|
2792
|
-
return focused ? "expanded" : "collapsed";
|
|
3256
|
+
function isUpcomingExercise(status) {
|
|
3257
|
+
return status === "upcoming";
|
|
2793
3258
|
}
|
|
2794
3259
|
function toActiveCardProps(exercise, focused, onToggle, supersetPosition = null, supersetColor) {
|
|
2795
|
-
const
|
|
3260
|
+
const upcoming = isUpcomingExercise(exercise.status);
|
|
2796
3261
|
return {
|
|
2797
3262
|
name: exercise.name,
|
|
2798
|
-
|
|
2799
|
-
|
|
3263
|
+
upcoming,
|
|
3264
|
+
expanded: focused,
|
|
3265
|
+
onExpandedChange: onToggle,
|
|
2800
3266
|
summary: exercise.summary,
|
|
2801
|
-
e1rm: exercise.e1rm,
|
|
2802
3267
|
isPR: exercise.isPR,
|
|
2803
3268
|
tempo: exercise.tempo,
|
|
2804
3269
|
setVelocities: exercise.setVelocities,
|
|
2805
3270
|
totalPlannedSets: exercise.totalPlannedSets,
|
|
2806
|
-
sets:
|
|
3271
|
+
sets: focused ? exercise.sets : void 0,
|
|
2807
3272
|
prescription: exercise.prescription,
|
|
2808
3273
|
previousBest: exercise.previousBest,
|
|
2809
3274
|
supersetPosition,
|
|
@@ -2876,7 +3341,7 @@ function WorkoutHeader({
|
|
|
2876
3341
|
fontSize: 15,
|
|
2877
3342
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
2878
3343
|
fontWeight: "700",
|
|
2879
|
-
color:
|
|
3344
|
+
color: BRAND_PRIMARY4,
|
|
2880
3345
|
fontVariant: ["tabular-nums"]
|
|
2881
3346
|
},
|
|
2882
3347
|
children: `${progress.completedExercises}/${progress.totalExercises}`
|
|
@@ -2910,7 +3375,7 @@ function WorkoutHeader({
|
|
|
2910
3375
|
style: {
|
|
2911
3376
|
height: "100%",
|
|
2912
3377
|
width: `${Math.round(progress.fraction * 100)}%`,
|
|
2913
|
-
backgroundColor:
|
|
3378
|
+
backgroundColor: BRAND_PRIMARY4,
|
|
2914
3379
|
borderRadius: 2
|
|
2915
3380
|
},
|
|
2916
3381
|
testID: "active-workout-page-progress-fill"
|
|
@@ -3492,17 +3957,18 @@ function CardContent({ children, className }) {
|
|
|
3492
3957
|
function CardFooter({ children, className }) {
|
|
3493
3958
|
return /* @__PURE__ */ jsx(View, { className: cn("px-6 py-4 flex-row items-center gap-2", className), children });
|
|
3494
3959
|
}
|
|
3960
|
+
var t5 = getSemanticColors("dark");
|
|
3495
3961
|
var solidVariantColors = {
|
|
3496
|
-
success: "
|
|
3497
|
-
warning: "
|
|
3498
|
-
error: "
|
|
3962
|
+
success: t5["status-success"],
|
|
3963
|
+
warning: t5["status-warning"],
|
|
3964
|
+
error: t5["status-error"],
|
|
3499
3965
|
neutral: "#6B7280"
|
|
3500
3966
|
};
|
|
3501
3967
|
var ringVariantStyles = {
|
|
3502
3968
|
"on-track": {
|
|
3503
|
-
backgroundColor: "rgba(
|
|
3969
|
+
backgroundColor: "rgba(46,213,115,0.15)",
|
|
3504
3970
|
borderWidth: 1,
|
|
3505
|
-
borderColor: "rgba(
|
|
3971
|
+
borderColor: "rgba(46,213,115,0.3)"
|
|
3506
3972
|
},
|
|
3507
3973
|
deviation: {
|
|
3508
3974
|
backgroundColor: "rgba(245,158,11,0.15)",
|
|
@@ -3517,11 +3983,11 @@ var ringVariantStyles = {
|
|
|
3517
3983
|
}
|
|
3518
3984
|
};
|
|
3519
3985
|
var glowStyles = {
|
|
3520
|
-
success: { boxShadow: "0 0 4px rgba(
|
|
3986
|
+
success: { boxShadow: "0 0 4px rgba(46,213,115,0.4)" },
|
|
3521
3987
|
warning: { boxShadow: "0 0 4px rgba(245,158,11,0.4)" },
|
|
3522
3988
|
error: { boxShadow: "0 0 4px rgba(239,68,68,0.4)" },
|
|
3523
3989
|
neutral: { boxShadow: "0 0 4px rgba(107,114,128,0.4)" },
|
|
3524
|
-
"on-track": { boxShadow: "0 0 4px rgba(
|
|
3990
|
+
"on-track": { boxShadow: "0 0 4px rgba(46,213,115,0.4)" },
|
|
3525
3991
|
deviation: { boxShadow: "0 0 4px rgba(245,158,11,0.4)" },
|
|
3526
3992
|
future: { boxShadow: "0 0 4px rgba(107,114,128,0.4)" }
|
|
3527
3993
|
};
|
|
@@ -3535,8 +4001,8 @@ var iconColors = {
|
|
|
3535
4001
|
warning: "#6B4000",
|
|
3536
4002
|
error: "#5C1A1A",
|
|
3537
4003
|
neutral: "#D1D5DB",
|
|
3538
|
-
"on-track": "
|
|
3539
|
-
deviation: "
|
|
4004
|
+
"on-track": t5["status-success"],
|
|
4005
|
+
deviation: t5["status-warning"],
|
|
3540
4006
|
future: "#6B7280"
|
|
3541
4007
|
};
|
|
3542
4008
|
var sizeDimensions = {
|
|
@@ -3617,20 +4083,24 @@ function StatusDot({
|
|
|
3617
4083
|
}
|
|
3618
4084
|
return /* @__PURE__ */ jsx(View, { className, ...props, children: dot });
|
|
3619
4085
|
}
|
|
4086
|
+
var MESO_ACCENT_GRADIENT_DARK = primitiveRamps.orange[500];
|
|
4087
|
+
var MESO_ACCENT_GRADIENT_LIGHT = primitiveRamps.orange[300];
|
|
4088
|
+
var WORKOUT_PILL_DELOAD = primitiveRamps.magenta[600];
|
|
3620
4089
|
|
|
3621
4090
|
// src/components/custom/Workout/MesoStatusCard.tsx
|
|
3622
|
-
var
|
|
3623
|
-
var
|
|
3624
|
-
var
|
|
3625
|
-
var
|
|
3626
|
-
var
|
|
3627
|
-
var
|
|
3628
|
-
var
|
|
4091
|
+
var t6 = getSemanticColors("dark");
|
|
4092
|
+
var BRAND_PRIMARY5 = t6["brand-primary"];
|
|
4093
|
+
var BRAND_PRIMARY_DARK = MESO_ACCENT_GRADIENT_DARK;
|
|
4094
|
+
var BRAND_PRIMARY_LIGHT = MESO_ACCENT_GRADIENT_LIGHT;
|
|
4095
|
+
var SUCCESS = t6["status-success"];
|
|
4096
|
+
var WARNING = t6["status-warning"];
|
|
4097
|
+
var ERROR = t6["status-error"];
|
|
4098
|
+
var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY5, BRAND_PRIMARY_LIGHT];
|
|
3629
4099
|
var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
|
|
3630
|
-
var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(
|
|
4100
|
+
var GAUGE_GRADIENT = "linear-gradient(90deg, rgba(46,213,115,0.25) 0%, rgba(249,180,21,0.25) 50%, rgba(209,67,67,0.25) 100%)";
|
|
3631
4101
|
var STATUS_VARIANTS = {
|
|
3632
|
-
success: { bg: "rgba(
|
|
3633
|
-
warning: { bg: "rgba(
|
|
4102
|
+
success: { bg: "rgba(46,213,115,0.15)", border: "rgba(46,213,115,0.3)", text: SUCCESS },
|
|
4103
|
+
warning: { bg: "rgba(249,180,21,0.15)", border: "rgba(249,180,21,0.3)", text: WARNING },
|
|
3634
4104
|
error: { bg: "rgba(209,67,67,0.15)", border: "rgba(209,67,67,0.25)", text: ERROR }
|
|
3635
4105
|
};
|
|
3636
4106
|
function clamp01(value) {
|
|
@@ -3696,7 +4166,7 @@ function StatusPill({ badge }) {
|
|
|
3696
4166
|
}
|
|
3697
4167
|
);
|
|
3698
4168
|
}
|
|
3699
|
-
function
|
|
4169
|
+
function MetricCell2({ metric }) {
|
|
3700
4170
|
return /* @__PURE__ */ jsxs(View, { style: { width: "48%" }, testID: "meso-status-card-metric", children: [
|
|
3701
4171
|
/* @__PURE__ */ jsx(
|
|
3702
4172
|
Text,
|
|
@@ -3914,7 +4384,7 @@ function MesoStatusCard({
|
|
|
3914
4384
|
className: "flex-row flex-wrap",
|
|
3915
4385
|
style: { gap: 8 },
|
|
3916
4386
|
testID: "meso-status-card-metrics",
|
|
3917
|
-
children: metrics.map((metric, index) => /* @__PURE__ */ jsx(
|
|
4387
|
+
children: metrics.map((metric, index) => /* @__PURE__ */ jsx(MetricCell2, { metric }, `${metric.label}-${index}`))
|
|
3918
4388
|
}
|
|
3919
4389
|
),
|
|
3920
4390
|
gauges.length > 0 && /* @__PURE__ */ jsx(View, { style: { gap: 12 }, testID: "meso-status-card-gauges", children: gauges.map((gauge, index) => /* @__PURE__ */ jsx(Gauge, { gauge }, `${gauge.label}-${index}`)) }),
|
|
@@ -3922,9 +4392,9 @@ function MesoStatusCard({
|
|
|
3922
4392
|
View,
|
|
3923
4393
|
{
|
|
3924
4394
|
style: {
|
|
3925
|
-
backgroundColor: "rgba(
|
|
4395
|
+
backgroundColor: "rgba(249,180,21,0.06)",
|
|
3926
4396
|
borderWidth: 1,
|
|
3927
|
-
borderColor: "rgba(
|
|
4397
|
+
borderColor: "rgba(249,180,21,0.15)",
|
|
3928
4398
|
borderRadius: 8,
|
|
3929
4399
|
paddingVertical: 10,
|
|
3930
4400
|
paddingHorizontal: 12
|
|
@@ -3950,9 +4420,9 @@ function MesoStatusCard({
|
|
|
3950
4420
|
className: "flex-row items-center",
|
|
3951
4421
|
style: {
|
|
3952
4422
|
gap: 8,
|
|
3953
|
-
backgroundColor: "rgba(
|
|
4423
|
+
backgroundColor: "rgba(46,213,115,0.06)",
|
|
3954
4424
|
borderWidth: 1,
|
|
3955
|
-
borderColor: "rgba(
|
|
4425
|
+
borderColor: "rgba(46,213,115,0.2)",
|
|
3956
4426
|
borderRadius: 8,
|
|
3957
4427
|
paddingVertical: 10,
|
|
3958
4428
|
paddingHorizontal: 12
|
|
@@ -3981,21 +4451,22 @@ function MesoStatusCard({
|
|
|
3981
4451
|
}
|
|
3982
4452
|
);
|
|
3983
4453
|
}
|
|
3984
|
-
var
|
|
4454
|
+
var sem = getSemanticColors("dark");
|
|
4455
|
+
var BRAND_PRIMARY6 = sem["brand-primary"];
|
|
3985
4456
|
var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
|
|
3986
|
-
var STATUS_SUCCESS = "
|
|
3987
|
-
var STATUS_ERROR2 = "
|
|
3988
|
-
var STATUS_WARNING = "
|
|
4457
|
+
var STATUS_SUCCESS = sem["status-success"];
|
|
4458
|
+
var STATUS_ERROR2 = sem["status-error"];
|
|
4459
|
+
var STATUS_WARNING = sem["status-warning"];
|
|
3989
4460
|
var GRID_LINE = "rgba(255,255,255,0.06)";
|
|
3990
|
-
var SUCCESS_PILL_BG = "rgba(
|
|
3991
|
-
var SUCCESS_PILL_BORDER = "rgba(
|
|
4461
|
+
var SUCCESS_PILL_BG = "rgba(46,213,115,0.10)";
|
|
4462
|
+
var SUCCESS_PILL_BORDER = "rgba(46,213,115,0.20)";
|
|
3992
4463
|
var ERROR_PILL_BG = "rgba(209,67,67,0.10)";
|
|
3993
4464
|
var ERROR_PILL_BORDER = "rgba(209,67,67,0.20)";
|
|
3994
4465
|
var PLOT_LEFT = 26;
|
|
3995
4466
|
var TOOLTIP_WIDTH = 124;
|
|
3996
4467
|
function timeOf(dateStr) {
|
|
3997
|
-
const
|
|
3998
|
-
return Number.isNaN(
|
|
4468
|
+
const t12 = Date.parse(dateStr);
|
|
4469
|
+
return Number.isNaN(t12) ? 0 : t12;
|
|
3999
4470
|
}
|
|
4000
4471
|
function formatValue(value) {
|
|
4001
4472
|
return `${Math.round(value)}`;
|
|
@@ -4272,7 +4743,7 @@ function StrengthTrendChart({
|
|
|
4272
4743
|
ChartLine,
|
|
4273
4744
|
{
|
|
4274
4745
|
coords: geometry.actual,
|
|
4275
|
-
color:
|
|
4746
|
+
color: BRAND_PRIMARY6,
|
|
4276
4747
|
strokeWidth: 2.5,
|
|
4277
4748
|
testID: "strength-trend-chart-actual-segment"
|
|
4278
4749
|
}
|
|
@@ -4325,7 +4796,7 @@ function StrengthTrendChart({
|
|
|
4325
4796
|
width: 8,
|
|
4326
4797
|
height: 8,
|
|
4327
4798
|
borderRadius: 1,
|
|
4328
|
-
backgroundColor:
|
|
4799
|
+
backgroundColor: BRAND_PRIMARY6
|
|
4329
4800
|
}
|
|
4330
4801
|
},
|
|
4331
4802
|
`point-${c.index}`
|
|
@@ -4455,7 +4926,7 @@ function StrengthTrendChart({
|
|
|
4455
4926
|
testID: "strength-trend-chart-legend",
|
|
4456
4927
|
children: [
|
|
4457
4928
|
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
4458
|
-
/* @__PURE__ */ jsx(View, { style: { width: 14, height: 2.5, borderRadius: 1.5, backgroundColor:
|
|
4929
|
+
/* @__PURE__ */ jsx(View, { style: { width: 14, height: 2.5, borderRadius: 1.5, backgroundColor: BRAND_PRIMARY6 } }),
|
|
4459
4930
|
/* @__PURE__ */ jsx(Text, { className: "text-text-secondary", style: { fontSize: 10, fontFamily: "Inter, sans-serif" }, children: "Actual" })
|
|
4460
4931
|
] }),
|
|
4461
4932
|
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
@@ -4484,13 +4955,14 @@ function StrengthTrendChart({
|
|
|
4484
4955
|
}
|
|
4485
4956
|
);
|
|
4486
4957
|
}
|
|
4487
|
-
var
|
|
4488
|
-
var
|
|
4489
|
-
var
|
|
4958
|
+
var t7 = getSemanticColors("dark");
|
|
4959
|
+
var STATUS_SUCCESS2 = t7["status-success"];
|
|
4960
|
+
var STATUS_WARNING2 = t7["status-warning"];
|
|
4961
|
+
var STATUS_INFO = t7["status-info"];
|
|
4490
4962
|
var DOT_BORDER = "#F3F4F6";
|
|
4491
|
-
var BAND_FILL = "rgba(
|
|
4492
|
-
var BAND_EDGE = "rgba(
|
|
4493
|
-
var PROJECTION_FILL = "rgba(
|
|
4963
|
+
var BAND_FILL = "rgba(46,213,115,0.1)";
|
|
4964
|
+
var BAND_EDGE = "rgba(46,213,115,0.45)";
|
|
4965
|
+
var PROJECTION_FILL = "rgba(46,213,115,0.05)";
|
|
4494
4966
|
var PADDING_LEFT = 28;
|
|
4495
4967
|
var PADDING_RIGHT = 10;
|
|
4496
4968
|
var PADDING_TOP = 8;
|
|
@@ -4529,13 +5001,13 @@ function interpEdge(pixels, x, key) {
|
|
|
4529
5001
|
const a = pixels[i];
|
|
4530
5002
|
const b = pixels[i + 1];
|
|
4531
5003
|
if (x >= a.x && x <= b.x) {
|
|
4532
|
-
const
|
|
4533
|
-
return a[key] +
|
|
5004
|
+
const t12 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
|
|
5005
|
+
return a[key] + t12 * (b[key] - a[key]);
|
|
4534
5006
|
}
|
|
4535
5007
|
}
|
|
4536
5008
|
return pixels[pixels.length - 1][key];
|
|
4537
5009
|
}
|
|
4538
|
-
function
|
|
5010
|
+
function buildColumns2(pixels, step) {
|
|
4539
5011
|
if (pixels.length < 2) return [];
|
|
4540
5012
|
const start = pixels[0].x;
|
|
4541
5013
|
const end = pixels[pixels.length - 1].x;
|
|
@@ -4647,7 +5119,7 @@ function CapacityBandChart({
|
|
|
4647
5119
|
}
|
|
4648
5120
|
const { toX, toY } = scale;
|
|
4649
5121
|
const bandPixels = toPixels(band, toX, toY);
|
|
4650
|
-
const columns =
|
|
5122
|
+
const columns = buildColumns2(bandPixels, COLUMN_STEP);
|
|
4651
5123
|
const topEdge = buildEdges(bandPixels, "yHigh");
|
|
4652
5124
|
const bottomEdge = buildEdges(bandPixels, "yLow");
|
|
4653
5125
|
const lastBandPoint = band[band.length - 1];
|
|
@@ -4722,8 +5194,8 @@ function CapacityBandChart({
|
|
|
4722
5194
|
testID: "capacity-band-chart-reveal",
|
|
4723
5195
|
children: /* @__PURE__ */ jsxs(View, { style: { width, height, position: "relative" }, children: [
|
|
4724
5196
|
projection && /* @__PURE__ */ jsxs(View, { testID: "capacity-band-chart-projection", children: [
|
|
4725
|
-
renderColumns(
|
|
4726
|
-
renderColumns(
|
|
5197
|
+
renderColumns(buildColumns2(trainingPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
|
|
5198
|
+
renderColumns(buildColumns2(restPixels, COLUMN_STEP), PROJECTION_FILL, "capacity-band-chart-projection-fill"),
|
|
4727
5199
|
renderEdges(buildEdges(trainingPixels, "yHigh"), STATUS_SUCCESS2, true, "capacity-band-chart-projection-training"),
|
|
4728
5200
|
renderEdges(buildEdges(trainingPixels, "yLow"), STATUS_SUCCESS2, true, "capacity-band-chart-projection-training"),
|
|
4729
5201
|
renderEdges(buildEdges(restPixels, "yHigh"), STATUS_INFO, true, "capacity-band-chart-projection-rest"),
|
|
@@ -4862,7 +5334,7 @@ function CapacityBandChart({
|
|
|
4862
5334
|
}
|
|
4863
5335
|
|
|
4864
5336
|
// src/components/custom/Workout/ExerciseDetailPage.tsx
|
|
4865
|
-
var
|
|
5337
|
+
var BRAND_PRIMARY7 = getSemanticColors("dark")["brand-primary"];
|
|
4866
5338
|
var CHART_WIDTH = 326;
|
|
4867
5339
|
var CHART_HEIGHT = 150;
|
|
4868
5340
|
var EXERCISE_DETAIL_TABS = [
|
|
@@ -4884,10 +5356,9 @@ function deriveExerciseStats(entries) {
|
|
|
4884
5356
|
function toExerciseCardProps(entry, expanded, onToggle) {
|
|
4885
5357
|
return {
|
|
4886
5358
|
name: entry.title,
|
|
4887
|
-
|
|
4888
|
-
onToggle,
|
|
5359
|
+
expanded,
|
|
5360
|
+
onExpandedChange: onToggle,
|
|
4889
5361
|
summary: entry.summary,
|
|
4890
|
-
e1rm: entry.e1rm,
|
|
4891
5362
|
isPR: entry.isPR,
|
|
4892
5363
|
tempo: entry.tempo,
|
|
4893
5364
|
sets: expanded ? entry.sets : void 0
|
|
@@ -4926,7 +5397,7 @@ function TabBar({ active, onSelect }) {
|
|
|
4926
5397
|
alignItems: "center",
|
|
4927
5398
|
paddingVertical: 10,
|
|
4928
5399
|
borderBottomWidth: 2,
|
|
4929
|
-
borderBottomColor: isActive ?
|
|
5400
|
+
borderBottomColor: isActive ? BRAND_PRIMARY7 : "transparent"
|
|
4930
5401
|
},
|
|
4931
5402
|
testID: `exercise-detail-page-tab-${key}`,
|
|
4932
5403
|
children: /* @__PURE__ */ jsx(
|
|
@@ -5248,7 +5719,7 @@ function ExerciseDetailPage({
|
|
|
5248
5719
|
fontSize: 15,
|
|
5249
5720
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
5250
5721
|
fontWeight: "700",
|
|
5251
|
-
color:
|
|
5722
|
+
color: BRAND_PRIMARY7
|
|
5252
5723
|
},
|
|
5253
5724
|
children: `${exercise.currentE1rm} ${exercise.unit}`
|
|
5254
5725
|
}
|
|
@@ -5314,9 +5785,9 @@ function ExerciseDetailPage({
|
|
|
5314
5785
|
}
|
|
5315
5786
|
);
|
|
5316
5787
|
}
|
|
5317
|
-
var
|
|
5788
|
+
var BRAND_PRIMARY8 = getSemanticColors("dark")["brand-primary"];
|
|
5318
5789
|
var segmentBgColors = {
|
|
5319
|
-
completed: "rgba(
|
|
5790
|
+
completed: "rgba(46,213,115,0.3)",
|
|
5320
5791
|
current: "rgba(255,121,0,0.5)",
|
|
5321
5792
|
upcoming: "rgba(255,255,255,0.06)"
|
|
5322
5793
|
};
|
|
@@ -5366,7 +5837,7 @@ function MesoSegment({ meso, isActive, onPress }) {
|
|
|
5366
5837
|
},
|
|
5367
5838
|
isActive ? {
|
|
5368
5839
|
borderWidth: 2,
|
|
5369
|
-
borderColor:
|
|
5840
|
+
borderColor: BRAND_PRIMARY8,
|
|
5370
5841
|
transform: [{ scale: 1.02 }, { scale: pressScale }]
|
|
5371
5842
|
} : void 0
|
|
5372
5843
|
],
|
|
@@ -5380,7 +5851,7 @@ function MesoSegment({ meso, isActive, onPress }) {
|
|
|
5380
5851
|
top: 0,
|
|
5381
5852
|
bottom: 0,
|
|
5382
5853
|
width: `${progress * 100}%`,
|
|
5383
|
-
backgroundColor:
|
|
5854
|
+
backgroundColor: BRAND_PRIMARY8
|
|
5384
5855
|
},
|
|
5385
5856
|
testID: `meso-segment-fill-${meso.id}`
|
|
5386
5857
|
}
|
|
@@ -5431,9 +5902,11 @@ var colorStyles = {
|
|
|
5431
5902
|
default: "bg-text-tertiary",
|
|
5432
5903
|
primary: "bg-brand-primary",
|
|
5433
5904
|
success: "bg-status-success",
|
|
5905
|
+
live: "bg-status-live",
|
|
5434
5906
|
error: "bg-status-error",
|
|
5435
5907
|
warning: "bg-status-warning",
|
|
5436
|
-
info: "bg-status-info"
|
|
5908
|
+
info: "bg-status-info",
|
|
5909
|
+
"error-vivid": "bg-status-error-vivid"
|
|
5437
5910
|
};
|
|
5438
5911
|
function Indicator({
|
|
5439
5912
|
size = "sm",
|
|
@@ -5441,14 +5914,40 @@ function Indicator({
|
|
|
5441
5914
|
customColor,
|
|
5442
5915
|
glow = false,
|
|
5443
5916
|
ring = false,
|
|
5917
|
+
pulse = false,
|
|
5444
5918
|
className,
|
|
5445
5919
|
style,
|
|
5446
5920
|
...props
|
|
5447
5921
|
}) {
|
|
5922
|
+
const pulseMode = pulse === true ? "opacity" : pulse || false;
|
|
5923
|
+
const colorClass = !customColor ? colorStyles[color] : void 0;
|
|
5924
|
+
const colorStyle = customColor ? { backgroundColor: customColor } : void 0;
|
|
5925
|
+
if (pulseMode === "ping") {
|
|
5926
|
+
return /* @__PURE__ */ jsxs(View, { className: cn("relative", sizeStyles[size], className), style, ...props, children: [
|
|
5927
|
+
/* @__PURE__ */ jsx(
|
|
5928
|
+
View,
|
|
5929
|
+
{
|
|
5930
|
+
className: cn("absolute inset-0 rounded-full animate-ping", colorClass),
|
|
5931
|
+
style: colorStyle
|
|
5932
|
+
}
|
|
5933
|
+
),
|
|
5934
|
+
/* @__PURE__ */ jsx(
|
|
5935
|
+
View,
|
|
5936
|
+
{
|
|
5937
|
+
className: cn(
|
|
5938
|
+
"relative rounded-full",
|
|
5939
|
+
sizeStyles[size],
|
|
5940
|
+
colorClass,
|
|
5941
|
+
ring && "border-2 border-background-base"
|
|
5942
|
+
),
|
|
5943
|
+
style: colorStyle
|
|
5944
|
+
}
|
|
5945
|
+
)
|
|
5946
|
+
] });
|
|
5947
|
+
}
|
|
5448
5948
|
const dynamicStyle = {
|
|
5449
5949
|
...typeof style === "object" ? style : {},
|
|
5450
|
-
...
|
|
5451
|
-
...glow && !customColor ? {} : {},
|
|
5950
|
+
...colorStyle ?? {},
|
|
5452
5951
|
...glow && customColor ? { boxShadow: `0 0 6px ${customColor}` } : {}
|
|
5453
5952
|
};
|
|
5454
5953
|
return /* @__PURE__ */ jsx(
|
|
@@ -5457,12 +5956,14 @@ function Indicator({
|
|
|
5457
5956
|
className: cn(
|
|
5458
5957
|
"rounded-full shrink-0",
|
|
5459
5958
|
sizeStyles[size],
|
|
5460
|
-
|
|
5959
|
+
colorClass,
|
|
5960
|
+
pulseMode === "opacity" && "animate-pulse",
|
|
5461
5961
|
ring && "border-2 border-background-base",
|
|
5462
|
-
glow && !customColor && color === "success" && "shadow-[0_0_6px_rgba(
|
|
5962
|
+
glow && !customColor && (color === "success" || color === "live") && "shadow-[0_0_6px_rgba(46,213,115,0.6)]",
|
|
5463
5963
|
glow && !customColor && color === "error" && "shadow-[0_0_6px_rgba(239,68,68,0.6)]",
|
|
5464
5964
|
glow && !customColor && color === "warning" && "shadow-[0_0_6px_rgba(245,158,11,0.6)]",
|
|
5465
5965
|
glow && !customColor && color === "primary" && "shadow-[0_0_6px_rgba(255,121,0,0.6)]",
|
|
5966
|
+
glow && !customColor && color === "error-vivid" && "shadow-[0_0_6px_rgba(255,71,87,0.6)]",
|
|
5466
5967
|
className
|
|
5467
5968
|
),
|
|
5468
5969
|
style: Object.keys(dynamicStyle).length > 0 ? dynamicStyle : style,
|
|
@@ -5540,31 +6041,32 @@ function Badge({
|
|
|
5540
6041
|
}
|
|
5541
6042
|
);
|
|
5542
6043
|
}
|
|
6044
|
+
var t8 = getSemanticColors("dark");
|
|
5543
6045
|
var statusBgColors = {
|
|
5544
|
-
completed: "rgba(
|
|
6046
|
+
completed: "rgba(46,213,115,0.15)",
|
|
5545
6047
|
current: "rgba(255,121,0,0.15)",
|
|
5546
6048
|
next: "transparent",
|
|
5547
6049
|
upcoming: "#1C1C1C",
|
|
5548
6050
|
missed: "rgba(209,67,67,0.1)",
|
|
5549
|
-
deload: "rgba(
|
|
6051
|
+
deload: "rgba(186,41,150,0.15)"
|
|
5550
6052
|
};
|
|
5551
6053
|
var statusBorderStyles = {
|
|
5552
|
-
completed: { borderWidth: 1, borderColor: "rgba(
|
|
6054
|
+
completed: { borderWidth: 1, borderColor: "rgba(46,213,115,0.3)" },
|
|
5553
6055
|
current: { borderWidth: 1, borderColor: "rgba(255,121,0,0.3)" },
|
|
5554
6056
|
next: { borderWidth: 1, borderColor: "rgba(255,121,0,0.4)" },
|
|
5555
6057
|
upcoming: { borderWidth: 1, borderColor: "#1F1F1F" },
|
|
5556
6058
|
missed: { borderWidth: 1, borderColor: "rgba(209,67,67,0.25)" },
|
|
5557
|
-
deload: { borderWidth: 1, borderColor: "rgba(
|
|
6059
|
+
deload: { borderWidth: 1, borderColor: "rgba(186,41,150,0.3)" }
|
|
5558
6060
|
};
|
|
5559
6061
|
var textColors = {
|
|
5560
|
-
completed: "
|
|
5561
|
-
current: "
|
|
5562
|
-
next: "
|
|
6062
|
+
completed: t8["status-success"],
|
|
6063
|
+
current: t8["brand-primary"],
|
|
6064
|
+
next: t8["brand-primary"],
|
|
5563
6065
|
upcoming: "#6B7280",
|
|
5564
6066
|
missed: "rgba(209,67,67,0.7)",
|
|
5565
|
-
deload:
|
|
6067
|
+
deload: WORKOUT_PILL_DELOAD
|
|
5566
6068
|
};
|
|
5567
|
-
function
|
|
6069
|
+
function usePulse2(enabled) {
|
|
5568
6070
|
const [opacity] = useState(() => new Animated.Value(1));
|
|
5569
6071
|
useEffect(() => {
|
|
5570
6072
|
if (!enabled) {
|
|
@@ -5602,7 +6104,7 @@ function WorkoutPill({
|
|
|
5602
6104
|
...props
|
|
5603
6105
|
}) {
|
|
5604
6106
|
const shouldPulse = pulse ?? status === "current";
|
|
5605
|
-
const pulseOpacity =
|
|
6107
|
+
const pulseOpacity = usePulse2(shouldPulse);
|
|
5606
6108
|
const isCompleted = status === "completed";
|
|
5607
6109
|
const isMissed = status === "missed";
|
|
5608
6110
|
const pill = /* @__PURE__ */ jsx(
|
|
@@ -5692,23 +6194,24 @@ function WorkoutPill({
|
|
|
5692
6194
|
}
|
|
5693
6195
|
return pill;
|
|
5694
6196
|
}
|
|
6197
|
+
var t9 = getSemanticColors("dark");
|
|
5695
6198
|
var TRACK_BG = "#333333";
|
|
5696
6199
|
var LABEL_COLOR = "#6B7280";
|
|
5697
6200
|
var TARGET_LINE_COLOR = "rgba(33, 150, 243, 0.5)";
|
|
5698
6201
|
var AT_TARGET_GLOW = "0 0 5px 1px rgba(33, 150, 243, 0.35), 0 0 10px 3px rgba(33, 150, 243, 0.15)";
|
|
5699
6202
|
var ZONE = {
|
|
5700
|
-
building: "
|
|
5701
|
-
//
|
|
5702
|
-
approaching: "
|
|
5703
|
-
//
|
|
5704
|
-
target: "
|
|
5705
|
-
//
|
|
5706
|
-
over1: "
|
|
5707
|
-
//
|
|
5708
|
-
over2:
|
|
5709
|
-
//
|
|
5710
|
-
over3:
|
|
5711
|
-
//
|
|
6203
|
+
building: t9["status-success"],
|
|
6204
|
+
// below target ramp-up
|
|
6205
|
+
approaching: t9["status-warning"],
|
|
6206
|
+
// nearing target
|
|
6207
|
+
target: t9["brand-primary"],
|
|
6208
|
+
// exactly at target
|
|
6209
|
+
over1: t9["status-error"],
|
|
6210
|
+
// mild over-target
|
|
6211
|
+
over2: WORKOUT_TOKENS.intensity.over2,
|
|
6212
|
+
// moderate over-target
|
|
6213
|
+
over3: WORKOUT_TOKENS.intensity.over3
|
|
6214
|
+
// severe over-target
|
|
5712
6215
|
};
|
|
5713
6216
|
var BULGE_SIZE = { 1: 8, 2: 10, 3: 11 };
|
|
5714
6217
|
function zoneForPct(pct) {
|
|
@@ -5866,7 +6369,7 @@ function IntensityBar({
|
|
|
5866
6369
|
}
|
|
5867
6370
|
|
|
5868
6371
|
// src/components/custom/Workout/WeekRow.tsx
|
|
5869
|
-
var
|
|
6372
|
+
var BRAND_PRIMARY9 = getSemanticColors("dark")["brand-primary"];
|
|
5870
6373
|
function WeekRow({
|
|
5871
6374
|
weekNumber,
|
|
5872
6375
|
totalWeeks,
|
|
@@ -5886,12 +6389,12 @@ function WeekRow({
|
|
|
5886
6389
|
gap: 12
|
|
5887
6390
|
};
|
|
5888
6391
|
if (isDeload) {
|
|
5889
|
-
rowStyle.backgroundColor = "rgba(
|
|
6392
|
+
rowStyle.backgroundColor = "rgba(186,41,150,0.06)";
|
|
5890
6393
|
}
|
|
5891
6394
|
if (isCurrent) {
|
|
5892
6395
|
rowStyle.backgroundColor = "rgba(255,121,0,0.04)";
|
|
5893
6396
|
rowStyle.borderLeftWidth = 2;
|
|
5894
|
-
rowStyle.borderLeftColor =
|
|
6397
|
+
rowStyle.borderLeftColor = BRAND_PRIMARY9;
|
|
5895
6398
|
}
|
|
5896
6399
|
return /* @__PURE__ */ jsxs(
|
|
5897
6400
|
View,
|
|
@@ -5915,7 +6418,7 @@ function WeekRow({
|
|
|
5915
6418
|
width: 6,
|
|
5916
6419
|
height: 6,
|
|
5917
6420
|
borderRadius: 3,
|
|
5918
|
-
backgroundColor:
|
|
6421
|
+
backgroundColor: BRAND_PRIMARY9
|
|
5919
6422
|
},
|
|
5920
6423
|
accessibilityElementsHidden: true,
|
|
5921
6424
|
testID: "week-row-current-dot"
|
|
@@ -5929,7 +6432,7 @@ function WeekRow({
|
|
|
5929
6432
|
fontSize: 13,
|
|
5930
6433
|
fontWeight: "700",
|
|
5931
6434
|
fontFamily: "Inter, sans-serif",
|
|
5932
|
-
color: isCurrent ?
|
|
6435
|
+
color: isCurrent ? BRAND_PRIMARY9 : void 0
|
|
5933
6436
|
},
|
|
5934
6437
|
accessibilityElementsHidden: true,
|
|
5935
6438
|
children: `W${weekNumber}`
|
|
@@ -5970,11 +6473,11 @@ function WeekRow({
|
|
|
5970
6473
|
}
|
|
5971
6474
|
|
|
5972
6475
|
// src/components/custom/Workout/MesoCard.tsx
|
|
5973
|
-
var
|
|
5974
|
-
var BRAND_PRIMARY_DARK2 =
|
|
5975
|
-
var BRAND_PRIMARY_LIGHT2 =
|
|
6476
|
+
var BRAND_PRIMARY10 = getSemanticColors("dark")["brand-primary"];
|
|
6477
|
+
var BRAND_PRIMARY_DARK2 = MESO_ACCENT_GRADIENT_DARK;
|
|
6478
|
+
var BRAND_PRIMARY_LIGHT2 = MESO_ACCENT_GRADIENT_LIGHT;
|
|
5976
6479
|
var BORDER_DEFAULT = "#1F1F1F";
|
|
5977
|
-
var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2,
|
|
6480
|
+
var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2, BRAND_PRIMARY10, BRAND_PRIMARY_LIGHT2];
|
|
5978
6481
|
function heatmapColor(percentage) {
|
|
5979
6482
|
const clamped = Math.max(0, Math.min(100, percentage));
|
|
5980
6483
|
const opacity = 0.12 + clamped / 100 * 0.78;
|
|
@@ -6009,7 +6512,7 @@ function MesoCard({
|
|
|
6009
6512
|
}, [highlighted, highlight]);
|
|
6010
6513
|
const borderColor = highlight.interpolate({
|
|
6011
6514
|
inputRange: [0, 1],
|
|
6012
|
-
outputRange: [BORDER_DEFAULT,
|
|
6515
|
+
outputRange: [BORDER_DEFAULT, BRAND_PRIMARY10]
|
|
6013
6516
|
});
|
|
6014
6517
|
const header = /* @__PURE__ */ jsxs(View, { style: { paddingHorizontal: 14, paddingTop: 12, paddingBottom: 10 }, testID: "meso-card-body", children: [
|
|
6015
6518
|
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center", style: { gap: 8 }, testID: "meso-card-header", children: [
|
|
@@ -6069,7 +6572,7 @@ function MesoCard({
|
|
|
6069
6572
|
{
|
|
6070
6573
|
variant: "outline",
|
|
6071
6574
|
elevation: 2,
|
|
6072
|
-
borderColor: highlighted ?
|
|
6575
|
+
borderColor: highlighted ? BRAND_PRIMARY10 : BORDER_DEFAULT,
|
|
6073
6576
|
className,
|
|
6074
6577
|
style: [
|
|
6075
6578
|
{ borderColor },
|
|
@@ -6126,12 +6629,13 @@ function MesoCard({
|
|
|
6126
6629
|
}
|
|
6127
6630
|
) });
|
|
6128
6631
|
}
|
|
6632
|
+
var t10 = getSemanticColors("dark");
|
|
6129
6633
|
var dotColorMap = {
|
|
6130
6634
|
untrained: "#2C2C2C",
|
|
6131
|
-
behind: "
|
|
6132
|
-
ontrack: "
|
|
6133
|
-
target: "
|
|
6134
|
-
over: "
|
|
6635
|
+
behind: t10["brand-secondary"],
|
|
6636
|
+
ontrack: t10["status-success"],
|
|
6637
|
+
target: t10["brand-primary"],
|
|
6638
|
+
over: t10["status-error"]
|
|
6135
6639
|
};
|
|
6136
6640
|
function MuscleGroupChip({
|
|
6137
6641
|
name,
|
|
@@ -6205,9 +6709,10 @@ function MuscleGroupChip({
|
|
|
6205
6709
|
}
|
|
6206
6710
|
|
|
6207
6711
|
// src/components/custom/Workout/WorkoutCard.tsx
|
|
6712
|
+
var t11 = getSemanticColors("dark");
|
|
6208
6713
|
var COLORS = {
|
|
6209
|
-
statusSuccess: "
|
|
6210
|
-
brandPrimary: "
|
|
6714
|
+
statusSuccess: t11["status-success"],
|
|
6715
|
+
brandPrimary: t11["brand-primary"],
|
|
6211
6716
|
borderDefault: "#1F1F1F",
|
|
6212
6717
|
brandPrimarySubtle: "rgba(255,121,0,0.06)"
|
|
6213
6718
|
};
|
|
@@ -6351,7 +6856,7 @@ function WorkoutCard({
|
|
|
6351
6856
|
}
|
|
6352
6857
|
|
|
6353
6858
|
// src/components/custom/Workout/ProgramPlanningPage.tsx
|
|
6354
|
-
var
|
|
6859
|
+
var BRAND_PRIMARY11 = getSemanticColors("dark")["brand-primary"];
|
|
6355
6860
|
var WORKOUT_PILL_STATUS = {
|
|
6356
6861
|
completed: "completed",
|
|
6357
6862
|
today: "current",
|
|
@@ -6419,7 +6924,7 @@ function Breadcrumbs({ crumbs, onNavigate }) {
|
|
|
6419
6924
|
fontSize: 12,
|
|
6420
6925
|
fontFamily: "Inter, sans-serif",
|
|
6421
6926
|
fontWeight: isLast ? "700" : "500",
|
|
6422
|
-
color: isLast ? void 0 :
|
|
6927
|
+
color: isLast ? void 0 : BRAND_PRIMARY11
|
|
6423
6928
|
},
|
|
6424
6929
|
children: crumb.label
|
|
6425
6930
|
}
|
|
@@ -6491,8 +6996,8 @@ function WeekLevel({ week, onSelectWorkout }) {
|
|
|
6491
6996
|
function WorkoutLevel({ workout, expandedExercise, onToggleExercise }) {
|
|
6492
6997
|
const exercises = workout.exercises.map((exercise, index) => ({
|
|
6493
6998
|
...exercise,
|
|
6494
|
-
|
|
6495
|
-
|
|
6999
|
+
expanded: index === expandedExercise,
|
|
7000
|
+
onExpandedChange: () => onToggleExercise(index)
|
|
6496
7001
|
}));
|
|
6497
7002
|
return /* @__PURE__ */ jsx(View, { testID: "program-planning-page-workout-level", children: /* @__PURE__ */ jsx(
|
|
6498
7003
|
WorkoutCard,
|
|
@@ -6621,6 +7126,6 @@ function ProgramPlanningPage({
|
|
|
6621
7126
|
);
|
|
6622
7127
|
}
|
|
6623
7128
|
|
|
6624
|
-
export { ActiveWorkoutPage, EXERCISE_DETAIL_TABS, ExerciseDetailPage, ProgramPlanningPage, buildBreadcrumbs, countCompletedSets, deriveExerciseStats, deriveNavLevel, deriveWorkoutProgress, findActiveExercise, findMeso, findWeek, findWorkout, groupExercises,
|
|
7129
|
+
export { ActiveWorkoutPage, EXERCISE_DETAIL_TABS, ExerciseDetailPage, ProgramPlanningPage, buildBreadcrumbs, countCompletedSets, deriveExerciseStats, deriveNavLevel, deriveWorkoutProgress, findActiveExercise, findMeso, findWeek, findWorkout, groupExercises, isUpcomingExercise, summarizeVbt, toActiveCardProps, toExerciseCardProps, toProgressBarMesos };
|
|
6625
7130
|
//# sourceMappingURL=pages.mjs.map
|
|
6626
7131
|
//# sourceMappingURL=pages.mjs.map
|