@titan-design/react-ui 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -47
- package/dist/bodymap.js +768 -701
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +770 -703
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +1319 -216
- package/dist/index.d.ts +1319 -216
- package/dist/index.js +5996 -4498
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5773 -4357
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-CvsFqNtx.d.mts → pages-CpW3OB3g.d.mts} +21 -3
- package/dist/{pages-B1hqnGIC.d.ts → pages-_3Ajpiqu.d.ts} +21 -3
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +1435 -1428
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +1443 -1436
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +195 -134
- package/dist/theme/index.d.ts +195 -134
- package/dist/theme/index.js +215 -300
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +202 -296
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +62 -5
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +62 -5
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/dist/theme/tokens.d.mts +73 -5
- package/dist/theme/tokens.d.ts +73 -5
- package/dist/theme/tokens.js +55 -7
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme/tokens.mjs +55 -8
- package/dist/theme/tokens.mjs.map +1 -1
- package/docs/audits/2026-09-08-critique-addenda.md +51 -0
- package/docs/audits/2026-09-08-library-critique.md +212 -0
- package/docs/library-roadmap.md +99 -0
- package/package.json +1 -1
- package/src/arch/arch-graph.freshness.test.ts +52 -0
- package/src/arch/arch-graph.json +5021 -1617
- package/src/components/custom/ActiveWork/CoChangeChip.stories.tsx +44 -0
- package/src/components/custom/ActiveWork/CoChangeChip.test.tsx +29 -0
- package/src/components/custom/ActiveWork/CoChangeChip.tsx +48 -0
- package/src/components/custom/ActiveWork/Eyebrow.stories.tsx +25 -0
- package/src/components/custom/ActiveWork/Eyebrow.test.tsx +16 -0
- package/src/components/custom/ActiveWork/Eyebrow.tsx +26 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.stories.tsx +50 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.test.tsx +66 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.tsx +202 -0
- package/src/components/custom/ActiveWork/FileActivityRow.stories.tsx +70 -0
- package/src/components/custom/ActiveWork/FileActivityRow.test.tsx +67 -0
- package/src/components/custom/ActiveWork/FileActivityRow.tsx +130 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.stories.tsx +84 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.test.tsx +99 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.tsx +138 -0
- package/src/components/custom/ActiveWork/FilePathLabel.stories.tsx +39 -0
- package/src/components/custom/ActiveWork/FilePathLabel.test.tsx +53 -0
- package/src/components/custom/ActiveWork/FilePathLabel.tsx +63 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.stories.tsx +50 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.test.tsx +62 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.tsx +181 -0
- package/src/components/custom/ActiveWork/InitiativeCard.stories.tsx +73 -0
- package/src/components/custom/ActiveWork/InitiativeCard.test.tsx +68 -0
- package/src/components/custom/ActiveWork/InitiativeCard.tsx +136 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.stories.tsx +59 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.test.tsx +40 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.tsx +73 -0
- package/src/components/custom/ActiveWork/InitiativeReader.stories.tsx +145 -0
- package/src/components/custom/ActiveWork/OpenLoops.stories.tsx +58 -0
- package/src/components/custom/ActiveWork/OpenLoops.test.tsx +61 -0
- package/src/components/custom/ActiveWork/OpenLoops.tsx +107 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.stories.tsx +101 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.test.tsx +81 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.tsx +83 -0
- package/src/components/custom/ActiveWork/README.md +305 -0
- package/src/components/custom/ActiveWork/SessionDetail.stories.tsx +71 -0
- package/src/components/custom/ActiveWork/SessionDetail.test.tsx +84 -0
- package/src/components/custom/ActiveWork/SessionDetail.tsx +180 -0
- package/src/components/custom/ActiveWork/SessionList.stories.tsx +69 -0
- package/src/components/custom/ActiveWork/SessionList.test.tsx +78 -0
- package/src/components/custom/ActiveWork/SessionList.tsx +103 -0
- package/src/components/custom/ActiveWork/SessionListItem.stories.tsx +64 -0
- package/src/components/custom/ActiveWork/SessionListItem.test.tsx +62 -0
- package/src/components/custom/ActiveWork/SessionListItem.tsx +152 -0
- package/src/components/custom/ActiveWork/SessionReader.stories.tsx +113 -0
- package/src/components/custom/ActiveWork/SeverityLabel.stories.tsx +51 -0
- package/src/components/custom/ActiveWork/SeverityLabel.test.tsx +68 -0
- package/src/components/custom/ActiveWork/SeverityLabel.tsx +97 -0
- package/src/components/custom/ActiveWork/TaskRow.stories.tsx +63 -0
- package/src/components/custom/ActiveWork/TaskRow.test.tsx +112 -0
- package/src/components/custom/ActiveWork/TaskRow.tsx +176 -0
- package/src/components/custom/ActiveWork/TaskTable.stories.tsx +123 -0
- package/src/components/custom/ActiveWork/TaskTable.test.tsx +233 -0
- package/src/components/custom/ActiveWork/TaskTable.tsx +321 -0
- package/src/components/custom/ActiveWork/active-work-depth.test.tsx +102 -0
- package/src/components/custom/ActiveWork/file-history-fixture.ts +91 -0
- package/src/components/custom/ActiveWork/format-time.test.ts +23 -0
- package/src/components/custom/ActiveWork/format-time.ts +32 -0
- package/src/components/custom/ActiveWork/index.ts +19 -0
- package/src/components/custom/ActiveWork/initiative-fixture.ts +104 -0
- package/src/components/custom/ActiveWork/session-fixture.ts +267 -0
- package/src/components/custom/ActiveWork/session-linkers.ts +56 -0
- package/src/components/custom/ActiveWork/task-list-fixture.ts +97 -0
- package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +4 -3
- package/src/components/custom/DateTime/DateTime.stories.tsx +2 -1
- package/src/components/custom/DateTime/DateTime.test.tsx +3 -1
- package/src/components/custom/EmptyState/EmptyState.stories.tsx +22 -9
- package/src/components/custom/EmptyState/EmptyState.test.tsx +7 -13
- package/src/components/custom/EmptyState/EmptyState.tsx +4 -18
- package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +4 -3
- package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
- package/src/components/custom/Fatigue/GhostSpark.stories.tsx +4 -3
- package/src/components/custom/Fatigue/LiveFatigueCard.stories.tsx +2 -2
- package/src/components/custom/Fatigue/LiveFatigueCard.tsx +8 -4
- package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +116 -6
- package/src/components/custom/Fatigue/LiveFatiguePanel.test.tsx +134 -0
- package/src/components/custom/Fatigue/LiveFatiguePanel.tsx +54 -83
- package/src/components/custom/Fatigue/README.md +40 -3
- package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
- package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +2 -1
- package/src/components/custom/Fatigue/VelocityHero.stories.tsx +4 -3
- package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
- package/src/components/custom/Fatigue/fatigue-mock.test.ts +0 -5
- package/src/components/custom/Fatigue/fatigue-mock.ts +2 -10
- package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -0
- package/src/components/custom/Fatigue/index.ts +17 -5
- package/src/components/custom/Fatigue/panel-layout.test.ts +149 -0
- package/src/components/custom/Fatigue/panel-layout.ts +185 -0
- package/src/components/custom/Gauge/Gauge.stories.tsx +2 -2
- package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.tsx +4 -1
- package/src/components/custom/Metric/Metric.stories.tsx +10 -1
- package/src/components/custom/Metric/Metric.test.tsx +1 -3
- package/src/components/custom/Metric/Metric.tsx +5 -20
- package/src/components/custom/Prose/MarkdownProse.stories.tsx +88 -0
- package/src/components/custom/Prose/MarkdownProse.test.tsx +87 -0
- package/src/components/custom/Prose/MarkdownProse.tsx +201 -0
- package/src/components/custom/Prose/README.md +58 -0
- package/src/components/custom/Prose/index.ts +1 -0
- package/src/components/custom/Scatter/Scatter.stories.tsx +46 -8
- package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
- package/src/components/custom/Scatter/Scatter.tsx +116 -14
- package/src/components/custom/Sidebar/Sidebar.stories.tsx +40 -7
- package/src/components/custom/Sidebar/Sidebar.test.tsx +5 -1
- package/src/components/custom/Sidebar/Sidebar.tsx +16 -33
- package/src/components/custom/Table/Table.stories.tsx +98 -15
- package/src/components/custom/Table/Table.test.tsx +273 -86
- package/src/components/custom/Table/Table.tsx +159 -67
- package/src/components/custom/Table/column-fit.test.ts +75 -0
- package/src/components/custom/Table/column-fit.ts +116 -0
- package/src/components/custom/Table/index.ts +9 -0
- package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +8 -6
- package/src/components/custom/Treemap/Treemap.stories.tsx +2 -2
- package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
- package/src/components/custom/Treemap/Treemap.tsx +7 -2
- package/src/components/custom/Typography/Typography.stories.tsx +28 -1
- package/src/components/custom/Typography/Typography.test.tsx +34 -0
- package/src/components/custom/Typography/Typography.tsx +6 -0
- package/src/components/custom/Typography/index.ts +1 -8
- package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +9 -1
- package/src/components/custom/Workout/BaseBadge.stories.tsx +19 -7
- package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
- package/src/components/custom/Workout/BaseBadge.tsx +3 -0
- package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
- package/src/components/custom/Workout/BodyMap.tsx +3 -1
- package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +16 -4
- package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +45 -9
- package/src/components/custom/Workout/CapacityBandChart.stories.tsx +10 -8
- package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
- package/src/components/custom/Workout/CapacityBandChart.tsx +139 -108
- package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
- package/src/components/custom/Workout/DeviationBar.test.tsx +5 -2
- package/src/components/custom/Workout/DeviationBar.tsx +21 -16
- package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +182 -0
- package/src/components/custom/Workout/DualVelocityStrip.test.tsx +3 -2
- package/src/components/custom/Workout/ExerciseCard.stories.tsx +8 -7
- package/src/components/custom/Workout/ExerciseCard.test.tsx +13 -3
- package/src/components/custom/Workout/ExerciseCard.tsx +42 -51
- package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +7 -7
- package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
- package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
- package/src/components/custom/Workout/ExerciseHeading.tsx +8 -5
- package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +6 -4
- package/src/components/custom/Workout/ExerciseIndicator.test.tsx +27 -11
- package/src/components/custom/Workout/ExerciseIndicator.tsx +14 -15
- package/src/components/custom/Workout/FatigueMeter.stories.tsx +5 -5
- package/src/components/custom/Workout/InputBar.stories.tsx +4 -5
- package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
- package/src/components/custom/Workout/IntensityBar.test.tsx +5 -1
- package/src/components/custom/Workout/IntensityBar.tsx +4 -2
- package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +5 -4
- package/src/components/custom/Workout/MesoCard.stories.tsx +4 -1
- package/src/components/custom/Workout/MesoCard.test.tsx +7 -18
- package/src/components/custom/Workout/MesoCard.tsx +12 -9
- package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
- package/src/components/custom/Workout/MesoProgressBar.test.tsx +18 -11
- package/src/components/custom/Workout/MesoProgressBar.tsx +15 -13
- package/src/components/custom/Workout/MesoStatusCard.stories.tsx +2 -1
- package/src/components/custom/Workout/MesoStatusCard.test.tsx +14 -44
- package/src/components/custom/Workout/MesoStatusCard.tsx +9 -23
- package/src/components/custom/Workout/MetricTiles.stories.tsx +3 -2
- package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +2 -8
- package/src/components/custom/Workout/MuscleGroupChip.test.tsx +23 -31
- package/src/components/custom/Workout/MuscleGroupChip.tsx +28 -67
- package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
- package/src/components/custom/Workout/PlaceholderStrip.test.tsx +17 -10
- package/src/components/custom/Workout/PlaceholderStrip.tsx +9 -8
- package/src/components/custom/Workout/PrBadge.stories.tsx +2 -1
- package/src/components/custom/Workout/PrBadge.test.tsx +3 -9
- package/src/components/custom/Workout/PrBadge.tsx +13 -17
- package/src/components/custom/Workout/PrHistoryModal.stories.tsx +4 -1
- package/src/components/custom/Workout/PrHistoryModal.test.tsx +13 -36
- package/src/components/custom/Workout/PrHistoryModal.tsx +8 -4
- package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +6 -1
- package/src/components/custom/Workout/README.md +11 -6
- package/src/components/custom/Workout/ReadinessCheck.stories.tsx +3 -2
- package/src/components/custom/Workout/ReadinessCheck.test.tsx +12 -18
- package/src/components/custom/Workout/ReadinessCheck.tsx +19 -3
- package/src/components/custom/Workout/RestTimer.stories.tsx +3 -2
- package/src/components/custom/Workout/ScheduleTiles.stories.tsx +3 -2
- package/src/components/custom/Workout/ScheduleTiles.test.tsx +3 -4
- package/src/components/custom/Workout/ScheduleTiles.tsx +4 -7
- package/src/components/custom/Workout/SegmentedBar.stories.tsx +5 -5
- package/src/components/custom/Workout/SegmentedBar.tsx +6 -2
- package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +5 -5
- package/src/components/custom/Workout/SessionHeader.stories.tsx +6 -6
- package/src/components/custom/Workout/SessionHeader.tsx +12 -12
- package/src/components/custom/Workout/SessionRail.stories.tsx +12 -11
- package/src/components/custom/Workout/SessionRail.tsx +7 -9
- package/src/components/custom/Workout/SetBar.stories.tsx +10 -6
- package/src/components/custom/Workout/SetBar.test.tsx +49 -4
- package/src/components/custom/Workout/SetBar.tsx +38 -12
- package/src/components/custom/Workout/SetRow.stories.tsx +3 -2
- package/src/components/custom/Workout/SetRow.test.tsx +16 -2
- package/src/components/custom/Workout/SetRow.tsx +61 -23
- package/src/components/custom/Workout/SetStrip.stories.tsx +60 -5
- package/src/components/custom/Workout/SetStrip.test.tsx +25 -0
- package/src/components/custom/Workout/SetStrip.tsx +24 -4
- package/src/components/custom/Workout/SetTableHeader.stories.tsx +6 -6
- package/src/components/custom/Workout/SetTableHeader.tsx +9 -12
- package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +7 -7
- package/src/components/custom/Workout/SetsRepsLoad.tsx +3 -5
- package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
- package/src/components/custom/Workout/Sparkline.test.tsx +37 -19
- package/src/components/custom/Workout/Sparkline.tsx +14 -18
- package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
- package/src/components/custom/Workout/StatusDot.test.tsx +44 -5
- package/src/components/custom/Workout/StatusDot.tsx +93 -63
- package/src/components/custom/Workout/StatusPill.stories.tsx +1 -1
- package/src/components/custom/Workout/StatusPill.test.tsx +6 -15
- package/src/components/custom/Workout/StatusPill.tsx +27 -38
- package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +9 -3
- package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
- package/src/components/custom/Workout/StrengthTrendChart.tsx +31 -30
- package/src/components/custom/Workout/SupersetWrapper.stories.tsx +27 -64
- package/src/components/custom/Workout/SupersetWrapper.test.tsx +16 -14
- package/src/components/custom/Workout/SupersetWrapper.tsx +17 -21
- package/src/components/custom/Workout/TempoDisplay.stories.tsx +22 -7
- package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
- package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +9 -1
- package/src/components/custom/Workout/VelocityStrip.compact.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +7 -4
- package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
- package/src/components/custom/Workout/VelocityStrip.tsx +3 -0
- package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +6 -7
- package/src/components/custom/Workout/VolumeLandmarkBar.tsx +15 -6
- package/src/components/custom/Workout/WeekRow.stories.tsx +4 -1
- package/src/components/custom/Workout/WeekRow.test.tsx +18 -15
- package/src/components/custom/Workout/WeekRow.tsx +23 -16
- package/src/components/custom/Workout/WeightBadge.stories.tsx +2 -1
- package/src/components/custom/Workout/WeightBadge.test.tsx +50 -19
- package/src/components/custom/Workout/WeightBadge.tsx +28 -27
- package/src/components/custom/Workout/WorkoutCard.stories.tsx +6 -1
- package/src/components/custom/Workout/WorkoutCard.test.tsx +18 -0
- package/src/components/custom/Workout/WorkoutCard.tsx +35 -57
- package/src/components/custom/Workout/WorkoutPill.stories.tsx +5 -2
- package/src/components/custom/Workout/WorkoutPill.test.tsx +39 -7
- package/src/components/custom/Workout/WorkoutPill.tsx +88 -57
- package/src/components/custom/Workout/ZoneTrack.stories.tsx +7 -6
- package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
- package/src/components/custom/Workout/index.ts +5 -0
- package/src/components/custom/Workout/metricText.stories.tsx +6 -5
- package/src/components/custom/Workout/metricText.tsx +4 -0
- package/src/components/custom/Workout/setHeadingKit.tsx +207 -26
- package/src/components/custom/charts/README.md +61 -0
- package/src/components/custom/charts/SetBarChart.test.tsx +30 -1
- package/src/components/custom/charts/SetBarChart.tsx +42 -4
- package/src/components/custom/charts/SparkBars.stories.tsx +55 -0
- package/src/components/custom/charts/SparkBars.test.tsx +69 -0
- package/src/components/custom/charts/SparkBars.tsx +85 -0
- package/src/components/custom/charts/index.ts +3 -0
- package/src/components/custom/index.ts +3 -0
- package/src/components/custom/stepper/Stepper.stories.tsx +13 -10
- package/src/components/custom/stepper/Stepper.test.tsx +1 -7
- package/src/components/custom/stepper/Stepper.tsx +13 -28
- package/src/components/icons/icons.stories.tsx +1 -1
- package/src/components/icons/icons.tsx +51 -0
- package/src/components/shell/AppShell.stories.tsx +150 -0
- package/src/components/shell/AppShell.test.tsx +70 -0
- package/src/components/shell/AppShell.tsx +90 -0
- package/src/components/shell/BrandLockup.stories.tsx +66 -5
- package/src/components/shell/BrandLockup.test.tsx +34 -1
- package/src/components/shell/BrandLockup.tsx +27 -11
- package/src/components/shell/NavItem.stories.tsx +4 -4
- package/src/components/shell/NavItem.test.tsx +17 -0
- package/src/components/shell/NavItem.tsx +17 -5
- package/src/components/shell/README.md +89 -26
- package/src/components/shell/SideNav.stories.tsx +38 -7
- package/src/components/shell/SideNav.test.tsx +16 -8
- package/src/components/shell/SideNav.tsx +17 -17
- package/src/components/shell/TopBar.stories.tsx +44 -19
- package/src/components/shell/TopBar.test.tsx +34 -12
- package/src/components/shell/TopBar.tsx +61 -40
- package/src/components/shell/brands.tsx +66 -0
- package/src/components/shell/index.ts +9 -8
- package/src/components/shell/{DeviceIndicator.stories.tsx → workout/DeviceIndicator.stories.tsx} +2 -2
- package/src/components/shell/{DeviceIndicator.tsx → workout/DeviceIndicator.tsx} +2 -2
- package/src/components/shell/{DeviceMenu.stories.tsx → workout/DeviceMenu.stories.tsx} +2 -2
- package/src/components/shell/{DeviceMenu.tsx → workout/DeviceMenu.tsx} +3 -3
- package/src/components/shell/{DeviceRow.stories.tsx → workout/DeviceRow.stories.tsx} +2 -2
- package/src/components/shell/{DeviceRow.tsx → workout/DeviceRow.tsx} +3 -3
- package/src/components/shell/{SessionStatePill.stories.tsx → workout/SessionStatePill.stories.tsx} +2 -2
- package/src/components/shell/{SessionStatePill.tsx → workout/SessionStatePill.tsx} +5 -3
- package/src/components/shell/workout/WorkoutShell.stories.tsx +71 -0
- package/src/components/shell/{DashboardShell.test.tsx → workout/WorkoutShell.test.tsx} +19 -8
- package/src/components/shell/workout/WorkoutShell.tsx +77 -0
- package/src/components/shell/workout/WorkoutTopBar.stories.tsx +58 -0
- package/src/components/shell/workout/WorkoutTopBar.test.tsx +39 -0
- package/src/components/shell/workout/WorkoutTopBar.tsx +52 -0
- package/src/components/shell/workout/index.ts +9 -0
- package/src/components/shell/workout/workoutNavItems.tsx +16 -0
- package/src/components/ui/README.md +110 -0
- package/src/components/ui/alert/Alert.stories.tsx +1 -1
- package/src/components/ui/autocomplete/Autocomplete.stories.tsx +11 -13
- package/src/components/ui/autocomplete/Autocomplete.test.tsx +7 -25
- package/src/components/ui/autocomplete/Autocomplete.tsx +21 -28
- package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
- package/src/components/ui/avatar/Avatar.tsx +2 -10
- package/src/components/ui/badge/Badge.stories.tsx +83 -28
- package/src/components/ui/badge/Badge.test.tsx +19 -3
- package/src/components/ui/badge/Badge.tsx +48 -55
- package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
- package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +4 -16
- package/src/components/ui/button/Button.stories.tsx +46 -12
- package/src/components/ui/button/Button.tsx +32 -25
- package/src/components/ui/card/Card.stories.tsx +90 -94
- package/src/components/ui/card/Card.test.tsx +80 -6
- package/src/components/ui/card/Card.tsx +150 -203
- package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
- package/src/components/ui/checkbox/Checkbox.tsx +6 -26
- package/src/components/ui/chip/Chip.stories.tsx +37 -13
- package/src/components/ui/chip/Chip.test.tsx +10 -6
- package/src/components/ui/chip/Chip.tsx +76 -91
- package/src/components/ui/collapse/Collapse.stories.tsx +23 -23
- package/src/components/ui/collapse/Collapse.tsx +6 -11
- package/src/components/ui/data-row/DataRow.stories.tsx +9 -2
- package/src/components/ui/data-row/DataRow.test.tsx +5 -15
- package/src/components/ui/data-row/DataRow.tsx +18 -7
- package/src/components/ui/divider/Divider.stories.tsx +1 -1
- package/src/components/ui/divider/Divider.tsx +1 -5
- package/src/components/ui/drawer/Drawer.stories.tsx +5 -16
- package/src/components/ui/drawer/Drawer.tsx +13 -30
- package/src/components/ui/floating-overlay-depth.test.tsx +143 -0
- package/src/components/ui/form-field/FormField.stories.tsx +6 -20
- package/src/components/ui/form-field/FormField.test.tsx +1 -5
- package/src/components/ui/form-field/FormField.tsx +10 -46
- package/src/components/ui/help-tip/HelpTip.stories.tsx +8 -19
- package/src/components/ui/help-tip/HelpTip.test.tsx +1 -3
- package/src/components/ui/help-tip/HelpTip.tsx +21 -22
- package/src/components/ui/help-tip/index.ts +7 -1
- package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
- package/src/components/ui/icon-box/IconBox.test.tsx +1 -7
- package/src/components/ui/icon-box/IconBox.tsx +2 -12
- package/src/components/ui/indicator/Indicator.stories.tsx +1 -1
- package/src/components/ui/indicator/Indicator.tsx +20 -14
- package/src/components/ui/input/Input.stories.tsx +3 -11
- package/src/components/ui/input/Input.test.tsx +2 -10
- package/src/components/ui/input/Input.tsx +10 -25
- package/src/components/ui/input/index.ts +7 -1
- package/src/components/ui/link/Link.stories.tsx +19 -7
- package/src/components/ui/list-item/ListItem.stories.tsx +11 -2
- package/src/components/ui/list-item/ListItem.tsx +2 -9
- package/src/components/ui/menu/Menu.stories.tsx +21 -15
- package/src/components/ui/menu/Menu.test.tsx +2 -11
- package/src/components/ui/menu/Menu.tsx +12 -14
- package/src/components/ui/menu/index.ts +8 -1
- package/src/components/ui/modal/Modal.stories.tsx +2 -2
- package/src/components/ui/modal/Modal.tsx +29 -19
- package/src/components/ui/pill/Pill.stories.tsx +58 -23
- package/src/components/ui/pill/Pill.test.tsx +101 -3
- package/src/components/ui/pill/Pill.tsx +164 -49
- package/src/components/ui/pill/index.ts +1 -1
- package/src/components/ui/popover/Popover.stories.tsx +5 -7
- package/src/components/ui/popover/Popover.test.tsx +1 -6
- package/src/components/ui/popover/Popover.tsx +20 -15
- package/src/components/ui/popover/index.ts +7 -1
- package/src/components/ui/progress/Progress.stories.tsx +3 -12
- package/src/components/ui/progress/Progress.test.tsx +1 -5
- package/src/components/ui/radio/Radio.stories.tsx +42 -21
- package/src/components/ui/radio/Radio.test.tsx +6 -2
- package/src/components/ui/radio/Radio.tsx +23 -22
- package/src/components/ui/section/Section.stories.tsx +5 -14
- package/src/components/ui/section/Section.test.tsx +1 -6
- package/src/components/ui/section/Section.tsx +1 -3
- package/src/components/ui/section/index.ts +1 -5
- package/src/components/ui/select/Select.stories.tsx +3 -13
- package/src/components/ui/select/Select.test.tsx +2 -11
- package/src/components/ui/select/Select.tsx +14 -14
- package/src/components/ui/skeleton/Skeleton.stories.tsx +3 -11
- package/src/components/ui/skeleton/Skeleton.tsx +3 -14
- package/src/components/ui/skeleton/index.ts +1 -7
- package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
- package/src/components/ui/spinner/Spinner.tsx +1 -4
- package/src/components/ui/stack/Stack.stories.tsx +1 -1
- package/src/components/ui/stack/Stack.tsx +1 -1
- package/src/components/ui/surface/Surface.stories.tsx +17 -5
- package/src/components/ui/surface/Surface.test.tsx +88 -28
- package/src/components/ui/surface/Surface.tsx +37 -87
- package/src/components/ui/surface/SurfaceContext.ts +22 -62
- package/src/components/ui/surface/index.ts +8 -0
- package/src/components/ui/surface/resolveSurface.ts +98 -0
- package/src/components/ui/surface/surface.contract.test.ts +6 -1
- package/src/components/ui/switch/Switch.stories.tsx +1 -1
- package/src/components/ui/switch/Switch.tsx +7 -6
- package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
- package/src/components/ui/tabs/Tabs.tsx +7 -22
- package/src/components/ui/tabs/index.ts +1 -7
- package/src/components/ui/tile/Tile.stories.tsx +1 -1
- package/src/components/ui/tile/Tile.tsx +3 -0
- package/src/components/ui/toast/Toast.stories.tsx +1 -1
- package/src/components/ui/toast/Toast.test.tsx +2 -8
- package/src/components/ui/toast/Toast.tsx +43 -53
- package/src/components/ui/toast/index.ts +0 -1
- package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +92 -71
- package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +3 -18
- package/src/components/ui/toolbar-button/ToolbarButton.tsx +25 -43
- package/src/components/ui/tooltip/Tooltip.stories.tsx +12 -3
- package/src/components/ui/tooltip/Tooltip.test.tsx +21 -3
- package/src/components/ui/tooltip/Tooltip.tsx +55 -36
- package/src/components/ui/tooltip/index.ts +1 -1
- package/src/components/ui/trigger/TriggerSurface.test.tsx +215 -0
- package/src/components/ui/trigger/TriggerSurface.tsx +81 -0
- package/src/components/ui/trigger/index.ts +2 -0
- package/src/stories/PresetShowcase.stories.tsx +100 -47
- package/src/test/no-device-internals.test.ts +3 -3
- package/src/theme/ChoosingTokens.stories.tsx +48 -0
- package/src/theme/ColorPalettes.stories.tsx +62 -45
- package/src/theme/ColorPrimitives.stories.tsx +35 -35
- package/src/theme/Depth.stories.tsx +132 -65
- package/src/theme/DepthCalibration.stories.tsx +23 -21
- package/src/theme/ThemeProvider.test.tsx +4 -4
- package/src/theme/barrel.ts +7 -6
- package/src/theme/color-stories.coverage.test.ts +1 -1
- package/src/theme/color-utils.ts +41 -29
- package/src/theme/config.completeness.test.ts +1 -1
- package/src/theme/config.ts +28 -0
- package/src/theme/elevation.test.ts +82 -56
- package/src/theme/elevation.ts +77 -561
- package/src/theme/global.css +30 -2
- package/src/theme/grey-ramp.test.ts +24 -8
- package/src/theme/lift.test.ts +39 -0
- package/src/theme/lift.ts +102 -0
- package/src/theme/materials.test.ts +5 -2
- package/src/theme/materials.ts +38 -4
- package/src/theme/native-theming-guard.test.ts +5 -5
- package/src/theme/presets/apply.ts +4 -0
- package/src/theme/presets/audiobook.ts +5 -2
- package/src/theme/presets/default.ts +4 -0
- package/src/theme/presets/index.ts +14 -1
- package/src/theme/presets/types.ts +1 -1
- package/src/theme/semantic-contrast.test.ts +13 -4
- package/src/theme/status-distinctness.test.ts +66 -0
- package/src/theme/surface-planes.test.ts +37 -0
- package/src/theme/surface-planes.ts +68 -0
- package/src/theme/token-export-guard.test.ts +1 -3
- package/src/theme/tokens/primitives.test.ts +15 -7
- package/src/theme/tokens/primitives.ts +65 -33
- package/src/theme/tokens/semantic.ts +71 -37
- package/src/theme/wash-ladder.test.ts +58 -0
- package/src/theme/workout-tokens.ts +1 -7
- package/src/types/jest-axe.d.ts +2 -6
- package/src/types/raw-md.d.ts +5 -0
- package/src/utils/colors.ts +4 -4
- package/src/utils/form.ts +1 -3
- package/src/utils/index.ts +2 -7
- package/src/utils/number-format.ts +17 -0
- package/src/utils/workout-format.ts +15 -6
- package/src/web-jsx/jsx-runtime.ts +1 -5
- package/tailwind.config.js +5 -0
- package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +0 -151
- package/src/components/custom/Workout/RowInventory.stories.tsx +0 -408
- package/src/components/custom/Workout/S3FullRail.stories.tsx +0 -46
- package/src/components/custom/Workout/S3SessionPace.stories.tsx +0 -95
- package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +0 -61
- package/src/components/custom/Workout/S3SetTypes.stories.tsx +0 -176
- package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +0 -240
- package/src/components/shell/DashboardShell.stories.tsx +0 -65
- package/src/components/shell/DashboardShell.tsx +0 -75
- package/src/components/shell/SessionRailSpecimen.stories.tsx +0 -753
- package/src/theme/elevation.stories.tsx +0 -346
- package/src/utils/useTheme.ts +0 -72
- /package/src/components/shell/{DeviceIndicator.test.tsx → workout/DeviceIndicator.test.tsx} +0 -0
- /package/src/components/shell/{DeviceMenu.test.tsx → workout/DeviceMenu.test.tsx} +0 -0
- /package/src/components/shell/{DeviceRow.test.tsx → workout/DeviceRow.test.tsx} +0 -0
- /package/src/components/shell/{SessionStatePill.test.tsx → workout/SessionStatePill.test.tsx} +0 -0
package/dist/pages.js
CHANGED
|
@@ -11,6 +11,7 @@ var tailwindMerge = require('tailwind-merge');
|
|
|
11
11
|
// src/theme/tokens/primitives.ts
|
|
12
12
|
var primitiveColors = {
|
|
13
13
|
white: "#FFFFFF"};
|
|
14
|
+
var alertRedVivid = "#FF4757";
|
|
14
15
|
var greyRamp = {
|
|
15
16
|
50: "#F9F6F3",
|
|
16
17
|
// L*97.0 W6
|
|
@@ -161,11 +162,7 @@ var WORKOUT_TOKENS = {
|
|
|
161
162
|
intensity: {
|
|
162
163
|
// matches status-error
|
|
163
164
|
over2: primitiveRamps.red[700],
|
|
164
|
-
over3: primitiveRamps.red[800]}
|
|
165
|
-
// Placeholder strip
|
|
166
|
-
placeholder: {
|
|
167
|
-
fill: "#3A3A3A"
|
|
168
|
-
}};
|
|
165
|
+
over3: primitiveRamps.red[800]}};
|
|
169
166
|
|
|
170
167
|
// src/theme/tokens/semantic.ts
|
|
171
168
|
var semanticColorsLight = {
|
|
@@ -174,12 +171,16 @@ var semanticColorsLight = {
|
|
|
174
171
|
"brand-primary-light": primitiveRamps.orange[300],
|
|
175
172
|
"brand-primary-dark": primitiveRamps.orange[500],
|
|
176
173
|
"brand-primary-subtle": "rgba(255, 121, 0, 0.08)",
|
|
174
|
+
"brand-primary-muted": "rgba(255, 121, 0, 0.30)",
|
|
175
|
+
"brand-primary-strong": "rgba(255, 121, 0, 0.50)",
|
|
177
176
|
"brand-primary-hover": primitiveRamps.orange[500],
|
|
178
177
|
"brand-primary-active": primitiveRamps.orange[600],
|
|
179
178
|
"brand-secondary": primitiveRamps.cyan[600],
|
|
180
179
|
"brand-secondary-light": primitiveRamps.cyan[500],
|
|
181
180
|
"brand-secondary-dark": primitiveRamps.cyan[700],
|
|
182
181
|
"brand-secondary-subtle": "rgba(48, 123, 155, 0.08)",
|
|
182
|
+
"brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
|
|
183
|
+
"brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
|
|
183
184
|
"brand-secondary-hover": primitiveRamps.cyan[700],
|
|
184
185
|
"brand-secondary-active": primitiveRamps.cyan[800],
|
|
185
186
|
// Text on brand backgrounds (on-*)
|
|
@@ -190,6 +191,8 @@ var semanticColorsLight = {
|
|
|
190
191
|
"status-success-light": primitiveRamps.green[200],
|
|
191
192
|
"status-success-dark": primitiveRamps.green[600],
|
|
192
193
|
"status-success-subtle": primitiveRamps.green[50],
|
|
194
|
+
"status-success-muted": "rgba(46, 213, 115, 0.30)",
|
|
195
|
+
"status-success-strong": "rgba(46, 213, 115, 0.50)",
|
|
193
196
|
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
194
197
|
"status-live": primitiveRamps.green[300],
|
|
195
198
|
"status-live-muted": primitiveRamps.green[500],
|
|
@@ -197,19 +200,27 @@ var semanticColorsLight = {
|
|
|
197
200
|
"status-error-light": primitiveRamps.red[500],
|
|
198
201
|
"status-error-dark": primitiveRamps.red[700],
|
|
199
202
|
"status-error-subtle": primitiveRamps.red[50],
|
|
200
|
-
"status-error-
|
|
201
|
-
|
|
203
|
+
"status-error-muted": "rgba(209, 67, 67, 0.30)",
|
|
204
|
+
"status-error-strong": "rgba(209, 67, 67, 0.50)",
|
|
205
|
+
"status-error-vivid": alertRedVivid,
|
|
206
|
+
// NOT red[600], that is status-error
|
|
202
207
|
"status-error-vivid-light": primitiveRamps.red[500],
|
|
203
208
|
"status-error-vivid-dark": primitiveRamps.red[700],
|
|
204
209
|
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
210
|
+
"status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
|
|
211
|
+
"status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
|
|
205
212
|
"status-warning": primitiveRamps.amber[300],
|
|
206
213
|
"status-warning-light": primitiveRamps.amber[200],
|
|
207
214
|
"status-warning-dark": primitiveRamps.amber[500],
|
|
208
215
|
"status-warning-subtle": primitiveRamps.amber[50],
|
|
216
|
+
"status-warning-muted": "rgba(249, 180, 21, 0.30)",
|
|
217
|
+
"status-warning-strong": "rgba(249, 180, 21, 0.50)",
|
|
209
218
|
"status-info": primitiveRamps.blue[500],
|
|
210
219
|
"status-info-light": primitiveRamps.blue[300],
|
|
211
220
|
"status-info-dark": primitiveRamps.blue[600],
|
|
212
221
|
"status-info-subtle": primitiveRamps.blue[50],
|
|
222
|
+
"status-info-muted": "rgba(33, 150, 243, 0.30)",
|
|
223
|
+
"status-info-strong": "rgba(33, 150, 243, 0.50)",
|
|
213
224
|
// Text on status backgrounds (on-status-*)
|
|
214
225
|
"on-status-success": primitiveColors.white,
|
|
215
226
|
"on-status-error": primitiveColors.white,
|
|
@@ -304,7 +315,7 @@ var semanticColorsLight = {
|
|
|
304
315
|
"interactive-disabled": "rgba(55, 65, 81, 0.12)",
|
|
305
316
|
"interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
|
|
306
317
|
// Divider
|
|
307
|
-
|
|
318
|
+
divider: "#E8E9EB",
|
|
308
319
|
// Avatar default
|
|
309
320
|
"avatar-background": greyRamp[600],
|
|
310
321
|
"avatar-text": primitiveColors.white
|
|
@@ -315,12 +326,16 @@ var semanticColorsDark = {
|
|
|
315
326
|
"brand-primary-light": primitiveRamps.orange[300],
|
|
316
327
|
"brand-primary-dark": primitiveRamps.orange[500],
|
|
317
328
|
"brand-primary-subtle": "rgba(255, 121, 0, 0.12)",
|
|
329
|
+
"brand-primary-muted": "rgba(255, 121, 0, 0.30)",
|
|
330
|
+
"brand-primary-strong": "rgba(255, 121, 0, 0.50)",
|
|
318
331
|
"brand-primary-hover": primitiveRamps.orange[300],
|
|
319
332
|
"brand-primary-active": primitiveRamps.orange[200],
|
|
320
333
|
"brand-secondary": primitiveRamps.cyan[600],
|
|
321
334
|
"brand-secondary-light": primitiveRamps.cyan[500],
|
|
322
335
|
"brand-secondary-dark": primitiveRamps.cyan[700],
|
|
323
336
|
"brand-secondary-subtle": "rgba(48, 123, 155, 0.12)",
|
|
337
|
+
"brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
|
|
338
|
+
"brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
|
|
324
339
|
"brand-secondary-hover": primitiveRamps.cyan[500],
|
|
325
340
|
"brand-secondary-active": primitiveRamps.cyan[400],
|
|
326
341
|
// Text on brand backgrounds
|
|
@@ -331,6 +346,8 @@ var semanticColorsDark = {
|
|
|
331
346
|
"status-success-light": primitiveRamps.green[200],
|
|
332
347
|
"status-success-dark": primitiveRamps.green[600],
|
|
333
348
|
"status-success-subtle": "rgba(46, 213, 115, 0.12)",
|
|
349
|
+
"status-success-muted": "rgba(46, 213, 115, 0.30)",
|
|
350
|
+
"status-success-strong": "rgba(46, 213, 115, 0.50)",
|
|
334
351
|
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
335
352
|
"status-live": primitiveRamps.green[300],
|
|
336
353
|
"status-live-muted": primitiveRamps.green[500],
|
|
@@ -338,18 +355,26 @@ var semanticColorsDark = {
|
|
|
338
355
|
"status-error-light": primitiveRamps.red[500],
|
|
339
356
|
"status-error-dark": primitiveRamps.red[700],
|
|
340
357
|
"status-error-subtle": "rgba(209, 67, 67, 0.12)",
|
|
341
|
-
"status-error-
|
|
358
|
+
"status-error-muted": "rgba(209, 67, 67, 0.30)",
|
|
359
|
+
"status-error-strong": "rgba(209, 67, 67, 0.50)",
|
|
360
|
+
"status-error-vivid": alertRedVivid,
|
|
342
361
|
"status-error-vivid-light": primitiveRamps.red[500],
|
|
343
362
|
"status-error-vivid-dark": primitiveRamps.red[700],
|
|
344
363
|
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
364
|
+
"status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
|
|
365
|
+
"status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
|
|
345
366
|
"status-warning": primitiveRamps.amber[300],
|
|
346
367
|
"status-warning-light": primitiveRamps.amber[200],
|
|
347
368
|
"status-warning-dark": primitiveRamps.amber[500],
|
|
348
369
|
"status-warning-subtle": "rgba(249, 180, 21, 0.12)",
|
|
370
|
+
"status-warning-muted": "rgba(249, 180, 21, 0.30)",
|
|
371
|
+
"status-warning-strong": "rgba(249, 180, 21, 0.50)",
|
|
349
372
|
"status-info": primitiveRamps.blue[500],
|
|
350
373
|
"status-info-light": primitiveRamps.blue[300],
|
|
351
374
|
"status-info-dark": primitiveRamps.blue[600],
|
|
352
375
|
"status-info-subtle": "rgba(33, 150, 243, 0.12)",
|
|
376
|
+
"status-info-muted": "rgba(33, 150, 243, 0.30)",
|
|
377
|
+
"status-info-strong": "rgba(33, 150, 243, 0.50)",
|
|
353
378
|
// Text on status backgrounds
|
|
354
379
|
"on-status-success": primitiveColors.white,
|
|
355
380
|
"on-status-error": primitiveColors.white,
|
|
@@ -489,7 +514,7 @@ var semanticColorsDark = {
|
|
|
489
514
|
"interactive-disabled": "rgba(255, 255, 255, 0.12)",
|
|
490
515
|
"interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
|
|
491
516
|
// Divider
|
|
492
|
-
|
|
517
|
+
divider: "rgba(255, 255, 255, 0.09)",
|
|
493
518
|
// Avatar default
|
|
494
519
|
"avatar-background": greyRamp[700],
|
|
495
520
|
"avatar-text": primitiveColors.white
|
|
@@ -515,79 +540,6 @@ function hexToRgb(hex) {
|
|
|
515
540
|
}
|
|
516
541
|
return { r, g, b };
|
|
517
542
|
}
|
|
518
|
-
function rgbToHsv(r, g, b) {
|
|
519
|
-
const rNorm = r / 255;
|
|
520
|
-
const gNorm = g / 255;
|
|
521
|
-
const bNorm = b / 255;
|
|
522
|
-
const max = Math.max(rNorm, gNorm, bNorm);
|
|
523
|
-
const min = Math.min(rNorm, gNorm, bNorm);
|
|
524
|
-
const delta = max - min;
|
|
525
|
-
const v = max;
|
|
526
|
-
const s = max === 0 ? 0 : delta / max;
|
|
527
|
-
let h = 0;
|
|
528
|
-
if (delta !== 0) {
|
|
529
|
-
if (max === rNorm) {
|
|
530
|
-
h = 60 * ((gNorm - bNorm) / delta % 6);
|
|
531
|
-
} else if (max === gNorm) {
|
|
532
|
-
h = 60 * ((bNorm - rNorm) / delta + 2);
|
|
533
|
-
} else {
|
|
534
|
-
h = 60 * ((rNorm - gNorm) / delta + 4);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (h < 0) h += 360;
|
|
538
|
-
return { h, s, v };
|
|
539
|
-
}
|
|
540
|
-
function hsvToRgb(h, s, v) {
|
|
541
|
-
const c2 = v * s;
|
|
542
|
-
const x = c2 * (1 - Math.abs(h / 60 % 2 - 1));
|
|
543
|
-
const m = v - c2;
|
|
544
|
-
let rPrime, gPrime, bPrime;
|
|
545
|
-
if (h >= 0 && h < 60) {
|
|
546
|
-
rPrime = c2;
|
|
547
|
-
gPrime = x;
|
|
548
|
-
bPrime = 0;
|
|
549
|
-
} else if (h >= 60 && h < 120) {
|
|
550
|
-
rPrime = x;
|
|
551
|
-
gPrime = c2;
|
|
552
|
-
bPrime = 0;
|
|
553
|
-
} else if (h >= 120 && h < 180) {
|
|
554
|
-
rPrime = 0;
|
|
555
|
-
gPrime = c2;
|
|
556
|
-
bPrime = x;
|
|
557
|
-
} else if (h >= 180 && h < 240) {
|
|
558
|
-
rPrime = 0;
|
|
559
|
-
gPrime = x;
|
|
560
|
-
bPrime = c2;
|
|
561
|
-
} else if (h >= 240 && h < 300) {
|
|
562
|
-
rPrime = x;
|
|
563
|
-
gPrime = 0;
|
|
564
|
-
bPrime = c2;
|
|
565
|
-
} else {
|
|
566
|
-
rPrime = c2;
|
|
567
|
-
gPrime = 0;
|
|
568
|
-
bPrime = x;
|
|
569
|
-
}
|
|
570
|
-
return {
|
|
571
|
-
r: Math.round((rPrime + m) * 255),
|
|
572
|
-
g: Math.round((gPrime + m) * 255),
|
|
573
|
-
b: Math.round((bPrime + m) * 255)
|
|
574
|
-
};
|
|
575
|
-
}
|
|
576
|
-
function rgbToHex(r, g, b) {
|
|
577
|
-
const toHex = (n) => {
|
|
578
|
-
const clamped = Math.max(0, Math.min(255, Math.round(n)));
|
|
579
|
-
return clamped.toString(16).padStart(2, "0");
|
|
580
|
-
};
|
|
581
|
-
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
582
|
-
}
|
|
583
|
-
function lighten(hex, amount = 0.1) {
|
|
584
|
-
const rgb = hexToRgb(hex);
|
|
585
|
-
if (!rgb) return hex;
|
|
586
|
-
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
587
|
-
const newV = Math.min(1, hsv.v + amount);
|
|
588
|
-
const newRgb = hsvToRgb(hsv.h, hsv.s, newV);
|
|
589
|
-
return rgbToHex(newRgb.r, newRgb.g, newRgb.b);
|
|
590
|
-
}
|
|
591
543
|
|
|
592
544
|
// src/utils/colors.ts
|
|
593
545
|
function alpha(color, opacity) {
|
|
@@ -634,6 +586,17 @@ function formatVelocity(velocity) {
|
|
|
634
586
|
function roundTempo(tempo) {
|
|
635
587
|
return tempo.map((v) => Math.round(v * 10) / 10);
|
|
636
588
|
}
|
|
589
|
+
function formatRepsRange(repsLow, repsHigh) {
|
|
590
|
+
if (repsLow != null && repsHigh != null) {
|
|
591
|
+
return repsLow === repsHigh ? `${repsLow}` : `${repsLow}\u2013${repsHigh}`;
|
|
592
|
+
}
|
|
593
|
+
if (repsLow != null) return `${repsLow}`;
|
|
594
|
+
if (repsHigh != null) return `${repsHigh}`;
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// src/theme/materials.ts
|
|
599
|
+
var c = getSemanticColors("dark");
|
|
637
600
|
function parseHex(hex) {
|
|
638
601
|
const h = hex.replace("#", "");
|
|
639
602
|
const full = h.length === 3 ? h.split("").map((ch) => ch + ch).join("") : h;
|
|
@@ -657,12 +620,20 @@ function grainForTone(baseColor) {
|
|
|
657
620
|
const op = grainOpacityForTone(baseColor).toFixed(3);
|
|
658
621
|
return `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='${op}'/%3E%3C/svg%3E")`;
|
|
659
622
|
}
|
|
623
|
+
function insetWell(tone = c["surface-input"]) {
|
|
624
|
+
return {
|
|
625
|
+
backgroundColor: tone,
|
|
626
|
+
boxShadow: "inset 0 2px 6px rgba(0,0,0,0.55), inset 0 -1px 0 rgba(255,255,255,0.12)"
|
|
627
|
+
};
|
|
628
|
+
}
|
|
660
629
|
function barPaper(color, flip = false) {
|
|
661
630
|
return {
|
|
662
631
|
backgroundImage: grainForTone(color),
|
|
663
632
|
boxShadow: flip ? "0 -6px 16px rgba(0,0,0,0.45)" : "inset 0 1.5px 0 rgba(255,255,255,0.22), 0 6px 16px rgba(0,0,0,0.45)"
|
|
664
633
|
};
|
|
665
634
|
}
|
|
635
|
+
|
|
636
|
+
// src/theme/surface-planes.ts
|
|
666
637
|
var SURFACE_LEVEL_TOKEN = {
|
|
667
638
|
frame: "background-frame",
|
|
668
639
|
background: "background-base",
|
|
@@ -671,6 +642,30 @@ var SURFACE_LEVEL_TOKEN = {
|
|
|
671
642
|
raised: "surface-raised",
|
|
672
643
|
overlay: "surface-overlay"
|
|
673
644
|
};
|
|
645
|
+
var PLANE_ORDER = [
|
|
646
|
+
"frame",
|
|
647
|
+
"background",
|
|
648
|
+
"base",
|
|
649
|
+
"elevated",
|
|
650
|
+
"raised",
|
|
651
|
+
"overlay"
|
|
652
|
+
];
|
|
653
|
+
function surfaceBackground(level, mode) {
|
|
654
|
+
return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]];
|
|
655
|
+
}
|
|
656
|
+
function stepPlane(from, delta) {
|
|
657
|
+
const index = PLANE_ORDER.indexOf(from);
|
|
658
|
+
const clamped = Math.min(PLANE_ORDER.length - 1, Math.max(0, index + delta));
|
|
659
|
+
return PLANE_ORDER[clamped];
|
|
660
|
+
}
|
|
661
|
+
function pressedLevel(parent) {
|
|
662
|
+
return stepPlane(parent, -1);
|
|
663
|
+
}
|
|
664
|
+
function raisedLevel(parent, steps) {
|
|
665
|
+
return stepPlane(parent, Math.max(0, steps));
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/components/ui/surface/SurfaceContext.ts
|
|
674
669
|
var ON_SURFACE_TOKEN = {
|
|
675
670
|
primary: "text-primary",
|
|
676
671
|
secondary: "text-secondary",
|
|
@@ -687,9 +682,6 @@ function useSurfaceMode() {
|
|
|
687
682
|
function useOnSurfaceColor(role = "primary") {
|
|
688
683
|
return getSemanticColors(useSurfaceMode())[ON_SURFACE_TOKEN[role]];
|
|
689
684
|
}
|
|
690
|
-
function surfaceBackground(level, mode) {
|
|
691
|
-
return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]];
|
|
692
|
-
}
|
|
693
685
|
var ANIMATION_EASING = reactNative.Easing.bezier(0.22, 1, 0.36, 1);
|
|
694
686
|
var PEAK_OVERSHOOT = 1.12;
|
|
695
687
|
function getReducedMotionPreference() {
|
|
@@ -763,14 +755,14 @@ var jsx = wrapJsx(jsxRuntime.jsx);
|
|
|
763
755
|
var jsxs = wrapJsx(jsxRuntime.jsxs);
|
|
764
756
|
|
|
765
757
|
// src/components/custom/charts/SetBarChart.tsx
|
|
766
|
-
function mixHex(a, b,
|
|
758
|
+
function mixHex(a, b, t7) {
|
|
767
759
|
const parse = (h) => {
|
|
768
760
|
const s = h.replace("#", "");
|
|
769
761
|
return [parseInt(s.slice(0, 2), 16), parseInt(s.slice(2, 4), 16), parseInt(s.slice(4, 6), 16)];
|
|
770
762
|
};
|
|
771
763
|
const [ar, ag, ab] = parse(a);
|
|
772
764
|
const [br, bg, bb] = parse(b);
|
|
773
|
-
const ch = (x, y) => Math.round(x + (y - x) *
|
|
765
|
+
const ch = (x, y) => Math.round(x + (y - x) * t7).toString(16).padStart(2, "0");
|
|
774
766
|
return `#${ch(ar, br)}${ch(ag, bg)}${ch(ab, bb)}`;
|
|
775
767
|
}
|
|
776
768
|
var VARIABLE_FILL = primitiveRamps.cyan[900];
|
|
@@ -783,6 +775,13 @@ function scaleDenominator(scale, maxValue) {
|
|
|
783
775
|
function valueLabelFontSize(height) {
|
|
784
776
|
return Math.round(Math.max(8, Math.min(12, height * 0.11)));
|
|
785
777
|
}
|
|
778
|
+
var LABEL_GLYPH_WIDTH_RATIO = 0.62;
|
|
779
|
+
function estimateValueLabelWidth(text, fontSize) {
|
|
780
|
+
return text.length * fontSize * LABEL_GLYPH_WIDTH_RATIO;
|
|
781
|
+
}
|
|
782
|
+
function shouldFlipEdgeLabel(roomPx, labelWidthPx) {
|
|
783
|
+
return labelWidthPx / 2 > roomPx;
|
|
784
|
+
}
|
|
786
785
|
var SET_BAR_DEFAULT_HEIGHT = 220;
|
|
787
786
|
var LABEL_ROW_HEIGHT = 16;
|
|
788
787
|
var LABEL_GAP = 3;
|
|
@@ -826,6 +825,7 @@ function SetBarChart({
|
|
|
826
825
|
flat = false,
|
|
827
826
|
showValueLabels: showValueLabelsProp = false,
|
|
828
827
|
formatValue: formatValue2 = String,
|
|
828
|
+
flipEdgeLabel = false,
|
|
829
829
|
todoVariant = "solid",
|
|
830
830
|
minColumns,
|
|
831
831
|
renderReference,
|
|
@@ -941,6 +941,12 @@ function SetBarChart({
|
|
|
941
941
|
}) : isLive ? liveGrowth.interpolate({ inputRange: [0, 1], outputRange: [0, barHeight(value)] }) : barHeight(value);
|
|
942
942
|
const ownLabel = showValueLabels && !renderBarOverlay && showBarLabel(repIndex);
|
|
943
943
|
const labelBottom = (expandProgress ? valueBarHeight(best) : barHeight(best)) + LABEL_GAP;
|
|
944
|
+
const isLastCell = i === cells.length - 1;
|
|
945
|
+
const labelText = formatValue2(value);
|
|
946
|
+
const flipLabel = flipEdgeLabel && isLastCell && shouldFlipEdgeLabel(
|
|
947
|
+
barWidth / 2,
|
|
948
|
+
estimateValueLabelWidth(labelText, valueLabelFontSize(height))
|
|
949
|
+
);
|
|
944
950
|
return /* @__PURE__ */ jsxs(reactNative.View, { accessibilityElementsHidden: renderBarOverlay == null, style: column, children: [
|
|
945
951
|
ownLabel && // All labels pin to one aligned row JUST ABOVE THE PEAK BAR (not the container top),
|
|
946
952
|
// in the muted on-surface-secondary tone — so the row hugs the bars, no floating void.
|
|
@@ -950,9 +956,8 @@ function SetBarChart({
|
|
|
950
956
|
style: {
|
|
951
957
|
position: "absolute",
|
|
952
958
|
bottom: labelBottom,
|
|
953
|
-
left: 0,
|
|
954
|
-
|
|
955
|
-
alignItems: "center",
|
|
959
|
+
...flipLabel ? { right: 0 } : { left: 0, right: 0 },
|
|
960
|
+
alignItems: flipLabel ? "flex-end" : "center",
|
|
956
961
|
...expandProgress ? { opacity: expandProgress } : null
|
|
957
962
|
},
|
|
958
963
|
pointerEvents: "none",
|
|
@@ -962,7 +967,7 @@ function SetBarChart({
|
|
|
962
967
|
className: "text-text-secondary",
|
|
963
968
|
style: [{ fontSize: valueLabelFontSize(height), fontWeight: "700" }, flipStyle],
|
|
964
969
|
testID: `${testIDPrefix}-label-${repIndex}`,
|
|
965
|
-
children:
|
|
970
|
+
children: labelText
|
|
966
971
|
}
|
|
967
972
|
)
|
|
968
973
|
}
|
|
@@ -1457,6 +1462,7 @@ function VelocityStrip({
|
|
|
1457
1462
|
label,
|
|
1458
1463
|
showValueLabels: true,
|
|
1459
1464
|
formatValue: formatVelocity,
|
|
1465
|
+
flipEdgeLabel: columnSlots != null,
|
|
1460
1466
|
renderReference: (g) => velocityReferenceOverlay(g, lossBandsOn),
|
|
1461
1467
|
hideBaseline: true,
|
|
1462
1468
|
testID: "velocity-strip-hero",
|
|
@@ -1661,8 +1667,12 @@ function VelocityStrip({
|
|
|
1661
1667
|
function cn(...inputs) {
|
|
1662
1668
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
1663
1669
|
}
|
|
1670
|
+
function resolveColor(token, mode = "dark") {
|
|
1671
|
+
return reactNative.Platform.OS === "web" ? `var(--color-${token})` : getSemanticColors(mode)[token];
|
|
1672
|
+
}
|
|
1664
1673
|
|
|
1665
1674
|
// src/components/custom/Workout/PlaceholderStrip.tsx
|
|
1675
|
+
var RAIL_TOKEN = "border-prominent";
|
|
1666
1676
|
function SingleStrip({
|
|
1667
1677
|
width,
|
|
1668
1678
|
className,
|
|
@@ -1675,7 +1685,7 @@ function SingleStrip({
|
|
|
1675
1685
|
style: [
|
|
1676
1686
|
{
|
|
1677
1687
|
height: 3,
|
|
1678
|
-
backgroundColor:
|
|
1688
|
+
backgroundColor: resolveColor(RAIL_TOKEN),
|
|
1679
1689
|
borderRadius: 2,
|
|
1680
1690
|
opacity: 0.5
|
|
1681
1691
|
},
|
|
@@ -1712,7 +1722,7 @@ function SegmentedStrip({
|
|
|
1712
1722
|
style: {
|
|
1713
1723
|
flex: 1,
|
|
1714
1724
|
height: 3,
|
|
1715
|
-
backgroundColor:
|
|
1725
|
+
backgroundColor: resolveColor(RAIL_TOKEN),
|
|
1716
1726
|
borderRadius: 1,
|
|
1717
1727
|
minWidth: 4
|
|
1718
1728
|
},
|
|
@@ -1724,11 +1734,7 @@ function SegmentedStrip({
|
|
|
1724
1734
|
}
|
|
1725
1735
|
);
|
|
1726
1736
|
}
|
|
1727
|
-
function PlaceholderStrip({
|
|
1728
|
-
mode = "single",
|
|
1729
|
-
segments,
|
|
1730
|
-
...props
|
|
1731
|
-
}) {
|
|
1737
|
+
function PlaceholderStrip({ mode = "single", segments, ...props }) {
|
|
1732
1738
|
if (mode === "segmented") {
|
|
1733
1739
|
return /* @__PURE__ */ jsx(SegmentedStrip, { segments, ...props });
|
|
1734
1740
|
}
|
|
@@ -1887,9 +1893,98 @@ function BaseBadge({
|
|
|
1887
1893
|
}
|
|
1888
1894
|
return badge;
|
|
1889
1895
|
}
|
|
1896
|
+
var variantStyles = {
|
|
1897
|
+
h1: "font-heading text-5xl font-bold leading-tight",
|
|
1898
|
+
h2: "font-heading text-4xl font-bold leading-tight",
|
|
1899
|
+
h3: "font-heading text-3xl font-bold leading-tight",
|
|
1900
|
+
h4: "font-heading text-2xl font-bold leading-tight",
|
|
1901
|
+
h5: "font-heading text-xl font-semibold leading-tight",
|
|
1902
|
+
h6: "font-heading text-lg font-semibold leading-tight",
|
|
1903
|
+
body1: "font-body text-base font-normal leading-normal",
|
|
1904
|
+
body2: "font-body text-sm font-normal leading-normal",
|
|
1905
|
+
subtitle1: "font-body text-base font-medium leading-relaxed",
|
|
1906
|
+
subtitle2: "font-body text-sm font-medium leading-normal",
|
|
1907
|
+
caption: "font-body text-xs font-normal leading-loose",
|
|
1908
|
+
overline: "font-body text-xs font-semibold uppercase tracking-widest leading-relaxed",
|
|
1909
|
+
button: "font-sans text-sm font-semibold leading-relaxed",
|
|
1910
|
+
// Monospace technical readouts (clocks, ids, metrics) and their all-caps label form.
|
|
1911
|
+
mono: "font-mono text-xs font-normal leading-normal",
|
|
1912
|
+
monoLabel: "font-mono text-xs font-bold uppercase tracking-wide leading-normal",
|
|
1913
|
+
// The sans (Inter) label pair: 10px for dense table/column headers, 12px bold for
|
|
1914
|
+
// badge and row labels. `overline` is the 12px font-body form of the same idea.
|
|
1915
|
+
microLabel: "font-sans text-2xs font-semibold uppercase tracking-widest leading-normal",
|
|
1916
|
+
boldLabel: "font-sans text-xs font-bold leading-normal"
|
|
1917
|
+
};
|
|
1918
|
+
var colorStyles = {
|
|
1919
|
+
primary: "text-text-primary",
|
|
1920
|
+
secondary: "text-text-secondary",
|
|
1921
|
+
tertiary: "text-text-tertiary",
|
|
1922
|
+
disabled: "text-text-disabled",
|
|
1923
|
+
inverse: "text-text-inverse",
|
|
1924
|
+
success: "text-status-success",
|
|
1925
|
+
error: "text-status-error",
|
|
1926
|
+
warning: "text-status-warning",
|
|
1927
|
+
info: "text-status-info",
|
|
1928
|
+
inherit: ""
|
|
1929
|
+
// No color class, inherit from parent
|
|
1930
|
+
};
|
|
1931
|
+
var alignStyles = {
|
|
1932
|
+
left: "text-left",
|
|
1933
|
+
center: "text-center",
|
|
1934
|
+
right: "text-right",
|
|
1935
|
+
justify: "text-justify"
|
|
1936
|
+
};
|
|
1937
|
+
var headingVariants = ["h1", "h2", "h3", "h4", "h5", "h6"];
|
|
1938
|
+
var marginBottomStyles = {
|
|
1939
|
+
none: "",
|
|
1940
|
+
sm: "mb-1",
|
|
1941
|
+
md: "mb-2",
|
|
1942
|
+
lg: "mb-4"
|
|
1943
|
+
};
|
|
1944
|
+
function Typography({
|
|
1945
|
+
variant = "body1",
|
|
1946
|
+
color = "primary",
|
|
1947
|
+
align,
|
|
1948
|
+
truncate = false,
|
|
1949
|
+
noWrap = false,
|
|
1950
|
+
// deprecated, kept for backward compatibility
|
|
1951
|
+
marginBottom,
|
|
1952
|
+
gutterBottom = false,
|
|
1953
|
+
// deprecated, kept for backward compatibility
|
|
1954
|
+
maxLines,
|
|
1955
|
+
className,
|
|
1956
|
+
children,
|
|
1957
|
+
...props
|
|
1958
|
+
}) {
|
|
1959
|
+
const isHeading = headingVariants.includes(variant);
|
|
1960
|
+
const shouldTruncate = truncate || noWrap;
|
|
1961
|
+
const mb = marginBottom || (gutterBottom ? "md" : "none");
|
|
1962
|
+
let numLines;
|
|
1963
|
+
if (maxLines) {
|
|
1964
|
+
numLines = maxLines;
|
|
1965
|
+
} else if (shouldTruncate) {
|
|
1966
|
+
numLines = 1;
|
|
1967
|
+
}
|
|
1968
|
+
return /* @__PURE__ */ jsx(
|
|
1969
|
+
reactNative.Text,
|
|
1970
|
+
{
|
|
1971
|
+
accessibilityRole: isHeading ? "header" : "text",
|
|
1972
|
+
numberOfLines: numLines,
|
|
1973
|
+
className: cn(
|
|
1974
|
+
variantStyles[variant],
|
|
1975
|
+
color !== "inherit" && colorStyles[color],
|
|
1976
|
+
align && alignStyles[align],
|
|
1977
|
+
shouldTruncate && "truncate",
|
|
1978
|
+
marginBottomStyles[mb],
|
|
1979
|
+
className
|
|
1980
|
+
),
|
|
1981
|
+
...props,
|
|
1982
|
+
children
|
|
1983
|
+
}
|
|
1984
|
+
);
|
|
1985
|
+
}
|
|
1890
1986
|
|
|
1891
1987
|
// src/components/custom/Workout/PrBadge.tsx
|
|
1892
|
-
var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
|
|
1893
1988
|
var typeLabels = {
|
|
1894
1989
|
e1rm: "PR e1RM",
|
|
1895
1990
|
weight: "PR Weight",
|
|
@@ -1906,6 +2001,7 @@ function PrBadge({
|
|
|
1906
2001
|
...props
|
|
1907
2002
|
}) {
|
|
1908
2003
|
const resolvedLabel = labelProp ?? typeLabels[type];
|
|
2004
|
+
const brandPrimary = resolveColor("brand-primary");
|
|
1909
2005
|
const [scale] = react.useState(() => new reactNative.Animated.Value(animate ? 0.8 : 1));
|
|
1910
2006
|
const [opacity] = react.useState(() => new reactNative.Animated.Value(animate ? 0 : 1));
|
|
1911
2007
|
react.useEffect(() => {
|
|
@@ -1933,7 +2029,7 @@ function PrBadge({
|
|
|
1933
2029
|
accessibilityLabel: `Personal record: ${resolvedLabel}`,
|
|
1934
2030
|
testID: "pr-badge-star",
|
|
1935
2031
|
...props,
|
|
1936
|
-
children: /* @__PURE__ */ jsx(StarIcon, { size: 14, color:
|
|
2032
|
+
children: /* @__PURE__ */ jsx(StarIcon, { size: 14, color: brandPrimary, fill: brandPrimary, strokeWidth: 2 })
|
|
1937
2033
|
}
|
|
1938
2034
|
) : /* @__PURE__ */ jsx(
|
|
1939
2035
|
BaseBadge,
|
|
@@ -1943,14 +2039,11 @@ function PrBadge({
|
|
|
1943
2039
|
accessibilityLabel: `Personal record: ${resolvedLabel}`,
|
|
1944
2040
|
...props,
|
|
1945
2041
|
children: /* @__PURE__ */ jsxs(
|
|
1946
|
-
|
|
2042
|
+
Typography,
|
|
1947
2043
|
{
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
fontWeight: "700",
|
|
1952
|
-
fontFamily: "Inter, sans-serif"
|
|
1953
|
-
},
|
|
2044
|
+
variant: "boldLabel",
|
|
2045
|
+
color: "inherit",
|
|
2046
|
+
className: "leading-[normal] text-brand-primary",
|
|
1954
2047
|
children: [
|
|
1955
2048
|
"\u2605",
|
|
1956
2049
|
" ",
|
|
@@ -1961,28 +2054,15 @@ function PrBadge({
|
|
|
1961
2054
|
}
|
|
1962
2055
|
);
|
|
1963
2056
|
if (animate) {
|
|
1964
|
-
return /* @__PURE__ */ jsx(
|
|
1965
|
-
reactNative.Animated.View,
|
|
1966
|
-
{
|
|
1967
|
-
style: { transform: [{ scale }], opacity },
|
|
1968
|
-
testID: "pr-badge-animated",
|
|
1969
|
-
children: badge
|
|
1970
|
-
}
|
|
1971
|
-
);
|
|
2057
|
+
return /* @__PURE__ */ jsx(reactNative.Animated.View, { style: { transform: [{ scale }], opacity }, testID: "pr-badge-animated", children: badge });
|
|
1972
2058
|
}
|
|
1973
2059
|
return badge;
|
|
1974
2060
|
}
|
|
1975
|
-
var
|
|
1976
|
-
var
|
|
1977
|
-
var TEXT_MUTED = DARK["text-secondary"];
|
|
2061
|
+
var TEXT_ACTIVE = "text-primary";
|
|
2062
|
+
var TEXT_MUTED = "text-secondary";
|
|
1978
2063
|
var COL = { set: 36, reps: 44, load: 56, rpe: 36 };
|
|
1979
|
-
var
|
|
1980
|
-
var
|
|
1981
|
-
fontSize: 10,
|
|
1982
|
-
fontWeight: "700",
|
|
1983
|
-
fontFamily: "Inter, sans-serif",
|
|
1984
|
-
color: WORKOUT_TOKENS.scale.orange,
|
|
1985
|
-
backgroundColor: "rgba(255,165,2,0.12)",
|
|
2064
|
+
var CELL_CLASS = "font-semibold leading-[normal]";
|
|
2065
|
+
var typeBadgeStyle = {
|
|
1986
2066
|
paddingVertical: 1,
|
|
1987
2067
|
paddingHorizontal: 5,
|
|
1988
2068
|
borderRadius: 3,
|
|
@@ -2043,7 +2123,8 @@ function RowStrip({ set }) {
|
|
|
2043
2123
|
}
|
|
2044
2124
|
function SetRow(set) {
|
|
2045
2125
|
const live = set.state === "live";
|
|
2046
|
-
const valueColor = live ? TEXT_ACTIVE : TEXT_MUTED;
|
|
2126
|
+
const valueColor = resolveColor(live ? TEXT_ACTIVE : TEXT_MUTED);
|
|
2127
|
+
const mutedColor = resolveColor(TEXT_MUTED);
|
|
2047
2128
|
const rpe = set.state === "todo" ? null : set.rpe;
|
|
2048
2129
|
return /* @__PURE__ */ jsxs(
|
|
2049
2130
|
reactNative.View,
|
|
@@ -2053,10 +2134,60 @@ function SetRow(set) {
|
|
|
2053
2134
|
testID: "set-row",
|
|
2054
2135
|
children: [
|
|
2055
2136
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { justifyContent: "space-between" }, children: [
|
|
2056
|
-
/* @__PURE__ */ jsx(Cell, { width: COL.set, testID: "set-row-set-number", children: set.setType ? /* @__PURE__ */ jsx(
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2137
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.set, testID: "set-row-set-number", children: set.setType ? /* @__PURE__ */ jsx(
|
|
2138
|
+
Typography,
|
|
2139
|
+
{
|
|
2140
|
+
variant: "boldLabel",
|
|
2141
|
+
color: "inherit",
|
|
2142
|
+
className: "text-2xs leading-[normal]",
|
|
2143
|
+
style: {
|
|
2144
|
+
...typeBadgeStyle,
|
|
2145
|
+
color: resolveColor("brand-primary"),
|
|
2146
|
+
backgroundColor: resolveColor("brand-primary-subtle")
|
|
2147
|
+
},
|
|
2148
|
+
testID: "set-row-type-badge",
|
|
2149
|
+
children: set.setType
|
|
2150
|
+
}
|
|
2151
|
+
) : /* @__PURE__ */ jsx(
|
|
2152
|
+
Typography,
|
|
2153
|
+
{
|
|
2154
|
+
variant: "boldLabel",
|
|
2155
|
+
color: "inherit",
|
|
2156
|
+
className: live ? "font-bold leading-[normal]" : CELL_CLASS,
|
|
2157
|
+
style: { color: valueColor },
|
|
2158
|
+
children: set.setNumber
|
|
2159
|
+
}
|
|
2160
|
+
) }),
|
|
2161
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.reps, testID: "set-row-reps", children: /* @__PURE__ */ jsx(
|
|
2162
|
+
Typography,
|
|
2163
|
+
{
|
|
2164
|
+
variant: "boldLabel",
|
|
2165
|
+
color: "inherit",
|
|
2166
|
+
className: CELL_CLASS,
|
|
2167
|
+
style: { color: valueColor },
|
|
2168
|
+
children: displayReps(set)
|
|
2169
|
+
}
|
|
2170
|
+
) }),
|
|
2171
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.load, testID: "set-row-weight", children: /* @__PURE__ */ jsx(
|
|
2172
|
+
Typography,
|
|
2173
|
+
{
|
|
2174
|
+
variant: "boldLabel",
|
|
2175
|
+
color: "inherit",
|
|
2176
|
+
className: CELL_CLASS,
|
|
2177
|
+
style: { color: valueColor },
|
|
2178
|
+
children: roundWeight(displayWeight(set))
|
|
2179
|
+
}
|
|
2180
|
+
) }),
|
|
2181
|
+
/* @__PURE__ */ jsx(Cell, { width: COL.rpe, testID: "set-row-rpe", children: /* @__PURE__ */ jsx(
|
|
2182
|
+
Typography,
|
|
2183
|
+
{
|
|
2184
|
+
variant: "boldLabel",
|
|
2185
|
+
color: "inherit",
|
|
2186
|
+
className: CELL_CLASS,
|
|
2187
|
+
style: { color: mutedColor },
|
|
2188
|
+
children: rpe != null ? roundRpe(rpe) : "\u2014"
|
|
2189
|
+
}
|
|
2190
|
+
) })
|
|
2060
2191
|
] }),
|
|
2061
2192
|
/* @__PURE__ */ jsx(reactNative.View, { style: { marginTop: live ? 6 : 4 }, testID: "set-row-strip", children: /* @__PURE__ */ jsx(RowStrip, { set }) })
|
|
2062
2193
|
]
|
|
@@ -2064,6 +2195,7 @@ function SetRow(set) {
|
|
|
2064
2195
|
);
|
|
2065
2196
|
}
|
|
2066
2197
|
var PREV_COLUMN = { label: "PREV", width: void 0 };
|
|
2198
|
+
var COLUMN_LABEL = "leading-[normal]";
|
|
2067
2199
|
function buildColumns(unit, showPrevious) {
|
|
2068
2200
|
return [
|
|
2069
2201
|
{ label: "SET", width: 36 },
|
|
@@ -2102,20 +2234,7 @@ function SetTableHeader({
|
|
|
2102
2234
|
gap: 8
|
|
2103
2235
|
},
|
|
2104
2236
|
...isFlex ? { className: "flex-1" } : {},
|
|
2105
|
-
children: /* @__PURE__ */ jsx(
|
|
2106
|
-
reactNative.Text,
|
|
2107
|
-
{
|
|
2108
|
-
className: "text-text-tertiary",
|
|
2109
|
-
style: {
|
|
2110
|
-
fontSize: 10,
|
|
2111
|
-
fontWeight: "600",
|
|
2112
|
-
fontFamily: "Inter, sans-serif",
|
|
2113
|
-
textTransform: "uppercase",
|
|
2114
|
-
letterSpacing: 0.8
|
|
2115
|
-
},
|
|
2116
|
-
children: label
|
|
2117
|
-
}
|
|
2118
|
-
)
|
|
2237
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "microLabel", color: "tertiary", className: COLUMN_LABEL, children: label })
|
|
2119
2238
|
},
|
|
2120
2239
|
label
|
|
2121
2240
|
);
|
|
@@ -2141,7 +2260,6 @@ function MetricCell({ children, color, fontSize = 11 }) {
|
|
|
2141
2260
|
}
|
|
2142
2261
|
|
|
2143
2262
|
// src/components/custom/Workout/SetsRepsLoad.tsx
|
|
2144
|
-
var t2 = getSemanticColors("dark");
|
|
2145
2263
|
var TIMES = "\xD7";
|
|
2146
2264
|
var AT = "@";
|
|
2147
2265
|
function SetsRepsLoad({
|
|
@@ -2153,8 +2271,8 @@ function SetsRepsLoad({
|
|
|
2153
2271
|
className,
|
|
2154
2272
|
...props
|
|
2155
2273
|
}) {
|
|
2156
|
-
const value =
|
|
2157
|
-
const sep =
|
|
2274
|
+
const value = useOnSurfaceColor("primary");
|
|
2275
|
+
const sep = useOnSurfaceColor("tertiary");
|
|
2158
2276
|
return /* @__PURE__ */ jsxs(
|
|
2159
2277
|
reactNative.View,
|
|
2160
2278
|
{
|
|
@@ -2174,19 +2292,19 @@ function SetsRepsLoad({
|
|
|
2174
2292
|
}
|
|
2175
2293
|
);
|
|
2176
2294
|
}
|
|
2177
|
-
var
|
|
2295
|
+
var t2 = getSemanticColors("dark");
|
|
2178
2296
|
var INTER = "Inter, sans-serif";
|
|
2179
2297
|
var TEXT_TERTIARY = "#6B7280";
|
|
2180
|
-
var STATUS_ERROR =
|
|
2181
|
-
var STATUS_SUCCESS =
|
|
2182
|
-
var STATUS_WARNING =
|
|
2298
|
+
var STATUS_ERROR = t2["status-error"];
|
|
2299
|
+
var STATUS_SUCCESS = t2["status-success"];
|
|
2300
|
+
var STATUS_WARNING = t2["status-warning"];
|
|
2183
2301
|
var ON_TARGET_MS = 100;
|
|
2184
2302
|
function getTempoFillPct(elapsedMs, targetMs) {
|
|
2185
2303
|
if (!targetMs) return 100;
|
|
2186
2304
|
return Math.min(100, elapsedMs / targetMs * 100);
|
|
2187
2305
|
}
|
|
2188
2306
|
function activeNumberTone(elapsedMs, targetMs) {
|
|
2189
|
-
if (targetMs == null) return
|
|
2307
|
+
if (targetMs == null) return t2["text-primary"];
|
|
2190
2308
|
const remainingMs = targetMs - elapsedMs;
|
|
2191
2309
|
if (remainingMs > ON_TARGET_MS) return STATUS_WARNING;
|
|
2192
2310
|
if (remainingMs >= -ON_TARGET_MS) return STATUS_SUCCESS;
|
|
@@ -2338,7 +2456,7 @@ function TempoDisplay({
|
|
|
2338
2456
|
style: {
|
|
2339
2457
|
flexDirection: "row",
|
|
2340
2458
|
alignItems: "center",
|
|
2341
|
-
backgroundColor:
|
|
2459
|
+
backgroundColor: t2["surface-raised"],
|
|
2342
2460
|
paddingHorizontal: chromePadX,
|
|
2343
2461
|
paddingVertical: chromePadY,
|
|
2344
2462
|
borderRadius: chromeRadius
|
|
@@ -2353,7 +2471,7 @@ function TempoDisplay({
|
|
|
2353
2471
|
fontSize: labelFont,
|
|
2354
2472
|
fontWeight: "500",
|
|
2355
2473
|
// Live-muted green while a rep is running, tertiary at rest.
|
|
2356
|
-
color: live ?
|
|
2474
|
+
color: live ? t2["status-live-muted"] : TEXT_TERTIARY,
|
|
2357
2475
|
letterSpacing: 0.5,
|
|
2358
2476
|
textTransform: "uppercase",
|
|
2359
2477
|
marginRight: Math.round(fontSize * 0.5)
|
|
@@ -2411,7 +2529,7 @@ function TempoDisplay({
|
|
|
2411
2529
|
reactNative.View,
|
|
2412
2530
|
{
|
|
2413
2531
|
style: {
|
|
2414
|
-
backgroundColor:
|
|
2532
|
+
backgroundColor: t2["surface-overlay"],
|
|
2415
2533
|
borderRadius: 6,
|
|
2416
2534
|
paddingVertical: 8,
|
|
2417
2535
|
paddingHorizontal: 12,
|
|
@@ -2464,17 +2582,17 @@ function TempoDisplay({
|
|
|
2464
2582
|
}
|
|
2465
2583
|
);
|
|
2466
2584
|
}
|
|
2467
|
-
var t4 = getSemanticColors("dark");
|
|
2468
2585
|
var INDICATOR_CONFIG = {
|
|
2469
|
-
imbalance: { Icon: ScaleIcon,
|
|
2470
|
-
overshoot: { Icon: AlertTriangleIcon,
|
|
2471
|
-
"velocity-loss": { Icon: TrendingDownIcon,
|
|
2472
|
-
"missed-reps": { Icon: CircleSlashIcon,
|
|
2473
|
-
pr: { Icon: AwardIcon,
|
|
2474
|
-
info: { Icon: InfoIcon,
|
|
2586
|
+
imbalance: { Icon: ScaleIcon, token: "status-error", label: "Left/right imbalance" },
|
|
2587
|
+
overshoot: { Icon: AlertTriangleIcon, token: "status-error", label: "Load overshoot" },
|
|
2588
|
+
"velocity-loss": { Icon: TrendingDownIcon, token: "status-warning", label: "Velocity loss" },
|
|
2589
|
+
"missed-reps": { Icon: CircleSlashIcon, token: "status-warning", label: "Missed reps" },
|
|
2590
|
+
pr: { Icon: AwardIcon, token: "status-success", label: "Personal record" },
|
|
2591
|
+
info: { Icon: InfoIcon, token: "status-info", label: "More info" }
|
|
2475
2592
|
};
|
|
2476
2593
|
function ExerciseIndicator({ kind, onPress, className, ...props }) {
|
|
2477
|
-
const { Icon,
|
|
2594
|
+
const { Icon, token, label } = INDICATOR_CONFIG[kind];
|
|
2595
|
+
const color = resolveColor(token);
|
|
2478
2596
|
const chip = /* @__PURE__ */ jsx(
|
|
2479
2597
|
reactNative.View,
|
|
2480
2598
|
{
|
|
@@ -2529,10 +2647,10 @@ function ExerciseHeading({
|
|
|
2529
2647
|
testID: "exercise-card-header",
|
|
2530
2648
|
children: [
|
|
2531
2649
|
/* @__PURE__ */ jsx(
|
|
2532
|
-
|
|
2650
|
+
Typography,
|
|
2533
2651
|
{
|
|
2534
|
-
|
|
2535
|
-
|
|
2652
|
+
variant: "boldLabel",
|
|
2653
|
+
className: "font-heading text-sm leading-[normal]",
|
|
2536
2654
|
testID: "exercise-card-name",
|
|
2537
2655
|
children: name
|
|
2538
2656
|
}
|
|
@@ -2661,12 +2779,12 @@ function SegmentedBar({
|
|
|
2661
2779
|
|
|
2662
2780
|
// src/components/custom/Workout/SetBar.tsx
|
|
2663
2781
|
var SET_STRIP_ZONES = {
|
|
2664
|
-
slow:
|
|
2665
|
-
moderate:
|
|
2666
|
-
fast:
|
|
2667
|
-
fastest:
|
|
2782
|
+
slow: WORKOUT_TOKENS.scale.red,
|
|
2783
|
+
moderate: WORKOUT_TOKENS.scale.orange,
|
|
2784
|
+
fast: WORKOUT_TOKENS.scale.yellow,
|
|
2785
|
+
fastest: WORKOUT_TOKENS.scale.green
|
|
2668
2786
|
};
|
|
2669
|
-
var TODO_COLOR =
|
|
2787
|
+
var TODO_COLOR = resolveColor("border-prominent");
|
|
2670
2788
|
var SET_STRIP_VARIABLE_COLOR = primitiveRamps.cyan[900];
|
|
2671
2789
|
var NOTCH_GAP = 2;
|
|
2672
2790
|
var CLUSTER_GAP = 3;
|
|
@@ -2780,6 +2898,10 @@ function describeSets(sets) {
|
|
|
2780
2898
|
const upcoming = sets.filter((s) => setCategory(s) === "upcoming").length;
|
|
2781
2899
|
return `Set progress: ${done} done, ${active} in progress, ${upcoming} upcoming`;
|
|
2782
2900
|
}
|
|
2901
|
+
function repsRangeLabel(set) {
|
|
2902
|
+
if (set.status !== "todo" && set.status !== "active") return null;
|
|
2903
|
+
return formatRepsRange(set.repsLow, set.repsHigh);
|
|
2904
|
+
}
|
|
2783
2905
|
function SetStrip({ sets, height = 8, className, ...props }) {
|
|
2784
2906
|
return /* @__PURE__ */ jsx(
|
|
2785
2907
|
reactNative.View,
|
|
@@ -2790,7 +2912,22 @@ function SetStrip({ sets, height = 8, className, ...props }) {
|
|
|
2790
2912
|
accessibilityLabel: describeSets(sets),
|
|
2791
2913
|
testID: "set-strip",
|
|
2792
2914
|
...props,
|
|
2793
|
-
children: sets.map((set, i) =>
|
|
2915
|
+
children: sets.map((set, i) => {
|
|
2916
|
+
const label = repsRangeLabel(set);
|
|
2917
|
+
if (label == null) return /* @__PURE__ */ jsx(SetBar, { set, height }, i);
|
|
2918
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { style: { flex: 1, minWidth: 0, position: "relative" }, children: [
|
|
2919
|
+
/* @__PURE__ */ jsx(
|
|
2920
|
+
reactNative.Text,
|
|
2921
|
+
{
|
|
2922
|
+
className: "text-text-secondary text-2xs font-semibold text-center",
|
|
2923
|
+
style: { position: "absolute", bottom: height + 3, left: 0, right: 0 },
|
|
2924
|
+
testID: "set-strip-reps-label",
|
|
2925
|
+
children: label
|
|
2926
|
+
}
|
|
2927
|
+
),
|
|
2928
|
+
/* @__PURE__ */ jsx(SetBar, { set, height })
|
|
2929
|
+
] }, i);
|
|
2930
|
+
})
|
|
2794
2931
|
}
|
|
2795
2932
|
);
|
|
2796
2933
|
}
|
|
@@ -2902,28 +3039,24 @@ function CollapsedCard({
|
|
|
2902
3039
|
children: [
|
|
2903
3040
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", testID: "exercise-card-header", children: [
|
|
2904
3041
|
/* @__PURE__ */ jsx(
|
|
2905
|
-
|
|
3042
|
+
Typography,
|
|
2906
3043
|
{
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
fontFamily: '"Space Grotesk", sans-serif',
|
|
2911
|
-
fontWeight: "700"
|
|
2912
|
-
},
|
|
3044
|
+
variant: "h6",
|
|
3045
|
+
color: "primary",
|
|
3046
|
+
className: "text-sm font-bold leading-[normal]",
|
|
2913
3047
|
testID: "exercise-card-name",
|
|
2914
3048
|
children: name
|
|
2915
3049
|
}
|
|
2916
3050
|
),
|
|
2917
3051
|
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1" }),
|
|
2918
|
-
summary && /*
|
|
2919
|
-
|
|
3052
|
+
summary && /* The demo's "body" face is Inter, which is the library's `font-sans`
|
|
3053
|
+
(the mapping B1 established for PrBadge), not Typography's `font-body`. */
|
|
3054
|
+
/* @__PURE__ */ jsx(
|
|
3055
|
+
Typography,
|
|
2920
3056
|
{
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
fontFamily: "Inter, sans-serif",
|
|
2925
|
-
marginRight: 8
|
|
2926
|
-
},
|
|
3057
|
+
variant: "caption",
|
|
3058
|
+
color: "secondary",
|
|
3059
|
+
className: "font-sans mr-2 leading-[normal]",
|
|
2927
3060
|
testID: "exercise-card-summary",
|
|
2928
3061
|
children: formatSummary(summary)
|
|
2929
3062
|
}
|
|
@@ -2957,8 +3090,6 @@ function CollapsedCard({
|
|
|
2957
3090
|
}
|
|
2958
3091
|
);
|
|
2959
3092
|
}
|
|
2960
|
-
var DARK2 = getSemanticColors("dark");
|
|
2961
|
-
var BODY_DIVIDER = DARK2["hairline-subtle"];
|
|
2962
3093
|
function deriveHeaderSetStates(sets) {
|
|
2963
3094
|
return sets.map((set) => {
|
|
2964
3095
|
switch (set.state) {
|
|
@@ -3019,7 +3150,11 @@ function ExpandedCard({
|
|
|
3019
3150
|
/* @__PURE__ */ jsxs(
|
|
3020
3151
|
reactNative.View,
|
|
3021
3152
|
{
|
|
3022
|
-
style: {
|
|
3153
|
+
style: {
|
|
3154
|
+
borderTopWidth: 1,
|
|
3155
|
+
borderTopColor: resolveColor("hairline-subtle"),
|
|
3156
|
+
paddingBottom: 6
|
|
3157
|
+
},
|
|
3023
3158
|
testID: "exercise-card-body",
|
|
3024
3159
|
children: [
|
|
3025
3160
|
/* @__PURE__ */ jsx(SetTableHeader, { unit, showPrevious: false, testID: "exercise-card-column-headers" }),
|
|
@@ -3054,45 +3189,36 @@ function UpcomingCard({
|
|
|
3054
3189
|
testID: "exercise-card",
|
|
3055
3190
|
children: /* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", children: [
|
|
3056
3191
|
/* @__PURE__ */ jsx(
|
|
3057
|
-
|
|
3192
|
+
Typography,
|
|
3058
3193
|
{
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
fontSize: 14,
|
|
3063
|
-
fontFamily: '"Space Grotesk", sans-serif',
|
|
3064
|
-
fontWeight: "700"
|
|
3065
|
-
},
|
|
3194
|
+
variant: "h6",
|
|
3195
|
+
color: "primary",
|
|
3196
|
+
className: "shrink-0 text-sm font-bold leading-[normal]",
|
|
3066
3197
|
testID: "exercise-card-name",
|
|
3067
3198
|
children: name
|
|
3068
3199
|
}
|
|
3069
3200
|
),
|
|
3070
3201
|
prescription && /* @__PURE__ */ jsx(
|
|
3071
|
-
|
|
3202
|
+
Typography,
|
|
3072
3203
|
{
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
fontSize: 12,
|
|
3078
|
-
fontFamily: "Inter, sans-serif",
|
|
3079
|
-
marginLeft: 8
|
|
3080
|
-
},
|
|
3204
|
+
variant: "caption",
|
|
3205
|
+
color: "secondary",
|
|
3206
|
+
maxLines: 1,
|
|
3207
|
+
className: "font-sans shrink ml-2 leading-[normal]",
|
|
3081
3208
|
testID: "exercise-card-prescription",
|
|
3082
3209
|
children: prescription
|
|
3083
3210
|
}
|
|
3084
3211
|
),
|
|
3085
3212
|
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1", style: { minWidth: 8 } }),
|
|
3086
|
-
previousBest && /*
|
|
3087
|
-
|
|
3213
|
+
previousBest && /* 11px is off the type scale; `2xs` (10px) is the step below, as B2's
|
|
3214
|
+
WorkoutCard date took for the same size. */
|
|
3215
|
+
/* @__PURE__ */ jsx(
|
|
3216
|
+
Typography,
|
|
3088
3217
|
{
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
fontSize: 11,
|
|
3094
|
-
fontFamily: "Inter, sans-serif"
|
|
3095
|
-
},
|
|
3218
|
+
variant: "caption",
|
|
3219
|
+
color: "tertiary",
|
|
3220
|
+
maxLines: 1,
|
|
3221
|
+
className: "font-sans shrink text-2xs leading-[normal]",
|
|
3096
3222
|
testID: "exercise-card-previous-best",
|
|
3097
3223
|
children: previousBest
|
|
3098
3224
|
}
|
|
@@ -3119,12 +3245,7 @@ function ExerciseCard({
|
|
|
3119
3245
|
if (upcoming) return /* @__PURE__ */ jsx(UpcomingCard, { ...rest, onToggle });
|
|
3120
3246
|
return isExpanded ? /* @__PURE__ */ jsx(ExpandedCard, { ...rest, onToggle }) : /* @__PURE__ */ jsx(CollapsedCard, { ...rest, onToggle });
|
|
3121
3247
|
}
|
|
3122
|
-
|
|
3123
|
-
return reactNative.Platform.OS === "web" ? `var(--color-${token})` : getSemanticColors(mode)[token];
|
|
3124
|
-
}
|
|
3125
|
-
|
|
3126
|
-
// src/components/custom/Workout/InputBar.tsx
|
|
3127
|
-
var BRAND_PRIMARY2 = getSemanticColors("dark")["brand-primary"];
|
|
3248
|
+
var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
|
|
3128
3249
|
var INPUT_CLASSNAME = "bg-surface-raised border-hairline-strong text-text-primary";
|
|
3129
3250
|
var inputStyle = {
|
|
3130
3251
|
fontSize: 14,
|
|
@@ -3253,7 +3374,7 @@ function InputBar({
|
|
|
3253
3374
|
onPress: onRecord,
|
|
3254
3375
|
disabled: !canRecord,
|
|
3255
3376
|
style: ({ pressed }) => ({
|
|
3256
|
-
backgroundColor:
|
|
3377
|
+
backgroundColor: BRAND_PRIMARY,
|
|
3257
3378
|
borderRadius: 8,
|
|
3258
3379
|
paddingVertical: 10,
|
|
3259
3380
|
paddingHorizontal: 16,
|
|
@@ -3487,7 +3608,7 @@ function CircularTimer({
|
|
|
3487
3608
|
}
|
|
3488
3609
|
|
|
3489
3610
|
// src/components/custom/Workout/RestTimer.tsx
|
|
3490
|
-
var
|
|
3611
|
+
var BRAND_PRIMARY2 = getSemanticColors("dark")["brand-primary"];
|
|
3491
3612
|
var RING_DEFAULT_SIZE = 180;
|
|
3492
3613
|
function RestActions({ onAddTime, onSkip }) {
|
|
3493
3614
|
return /* @__PURE__ */ jsxs(reactNative.View, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
@@ -3534,7 +3655,7 @@ function RestActions({ onAddTime, onSkip }) {
|
|
|
3534
3655
|
fontSize: 11,
|
|
3535
3656
|
fontFamily: "Inter, sans-serif",
|
|
3536
3657
|
fontWeight: "600",
|
|
3537
|
-
color:
|
|
3658
|
+
color: BRAND_PRIMARY2
|
|
3538
3659
|
},
|
|
3539
3660
|
children: "Skip"
|
|
3540
3661
|
}
|
|
@@ -3709,7 +3830,7 @@ function RestTimer({
|
|
|
3709
3830
|
{
|
|
3710
3831
|
style: {
|
|
3711
3832
|
height: "100%",
|
|
3712
|
-
backgroundColor:
|
|
3833
|
+
backgroundColor: BRAND_PRIMARY2,
|
|
3713
3834
|
borderRadius: 2,
|
|
3714
3835
|
width: `${progressPct}%`
|
|
3715
3836
|
},
|
|
@@ -3723,23 +3844,16 @@ function RestTimer({
|
|
|
3723
3844
|
}
|
|
3724
3845
|
);
|
|
3725
3846
|
}
|
|
3726
|
-
var
|
|
3727
|
-
|
|
3728
|
-
color
|
|
3729
|
-
bgBase: getSemanticColors("dark")["background-base"]
|
|
3730
|
-
};
|
|
3731
|
-
function SupersetWrapper({
|
|
3732
|
-
label = DEFAULTS.label,
|
|
3733
|
-
color = DEFAULTS.color,
|
|
3734
|
-
children
|
|
3735
|
-
}) {
|
|
3847
|
+
var DEFAULT_LABEL = "SS";
|
|
3848
|
+
function SupersetWrapper({ label = DEFAULT_LABEL, color, children }) {
|
|
3849
|
+
const rail = color ?? resolveColor("brand-primary");
|
|
3736
3850
|
return /* @__PURE__ */ jsxs(
|
|
3737
3851
|
reactNative.View,
|
|
3738
3852
|
{
|
|
3739
3853
|
style: {
|
|
3740
3854
|
position: "relative",
|
|
3741
3855
|
borderLeftWidth: 3,
|
|
3742
|
-
borderLeftColor:
|
|
3856
|
+
borderLeftColor: rail,
|
|
3743
3857
|
paddingLeft: 8,
|
|
3744
3858
|
marginHorizontal: 12,
|
|
3745
3859
|
marginBottom: 8,
|
|
@@ -3750,21 +3864,18 @@ function SupersetWrapper({
|
|
|
3750
3864
|
testID: "superset-wrapper",
|
|
3751
3865
|
children: [
|
|
3752
3866
|
/* @__PURE__ */ jsx(
|
|
3753
|
-
|
|
3867
|
+
Typography,
|
|
3754
3868
|
{
|
|
3869
|
+
variant: "microLabel",
|
|
3870
|
+
color: "inverse",
|
|
3755
3871
|
style: {
|
|
3756
3872
|
position: "absolute",
|
|
3757
3873
|
top: -1,
|
|
3758
3874
|
left: -3,
|
|
3759
|
-
|
|
3760
|
-
fontFamily: "Inter, sans-serif",
|
|
3761
|
-
fontWeight: "700",
|
|
3762
|
-
backgroundColor: color,
|
|
3763
|
-
color: DEFAULTS.bgBase,
|
|
3875
|
+
backgroundColor: rail,
|
|
3764
3876
|
paddingVertical: 2,
|
|
3765
3877
|
paddingHorizontal: 6,
|
|
3766
3878
|
borderBottomRightRadius: 4,
|
|
3767
|
-
letterSpacing: 0.5,
|
|
3768
3879
|
zIndex: 2
|
|
3769
3880
|
},
|
|
3770
3881
|
testID: "superset-label",
|
|
@@ -3778,7 +3889,7 @@ function SupersetWrapper({
|
|
|
3778
3889
|
}
|
|
3779
3890
|
|
|
3780
3891
|
// src/components/custom/Workout/ActiveWorkoutPage.tsx
|
|
3781
|
-
var
|
|
3892
|
+
var BRAND_PRIMARY3 = getSemanticColors("dark")["brand-primary"];
|
|
3782
3893
|
function countCompletedSets(exercise) {
|
|
3783
3894
|
if (exercise.setVelocities != null) return exercise.setVelocities.length;
|
|
3784
3895
|
if (exercise.status === "completed") return exercise.totalPlannedSets;
|
|
@@ -3892,7 +4003,7 @@ function WorkoutHeader({
|
|
|
3892
4003
|
fontSize: 15,
|
|
3893
4004
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
3894
4005
|
fontWeight: "700",
|
|
3895
|
-
color:
|
|
4006
|
+
color: BRAND_PRIMARY3,
|
|
3896
4007
|
fontVariant: ["tabular-nums"]
|
|
3897
4008
|
},
|
|
3898
4009
|
children: `${progress.completedExercises}/${progress.totalExercises}`
|
|
@@ -3926,7 +4037,7 @@ function WorkoutHeader({
|
|
|
3926
4037
|
style: {
|
|
3927
4038
|
height: "100%",
|
|
3928
4039
|
width: `${Math.round(progress.fraction * 100)}%`,
|
|
3929
|
-
backgroundColor:
|
|
4040
|
+
backgroundColor: BRAND_PRIMARY3,
|
|
3930
4041
|
borderRadius: 2
|
|
3931
4042
|
},
|
|
3932
4043
|
testID: "active-workout-page-progress-fill"
|
|
@@ -4060,348 +4171,159 @@ function ActiveWorkoutPage({
|
|
|
4060
4171
|
}
|
|
4061
4172
|
);
|
|
4062
4173
|
}
|
|
4063
|
-
var
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
// Level 1: Subtle elevation (outline cards, subtle containers)
|
|
4089
|
-
[1]: {
|
|
4090
|
-
name: "subtle",
|
|
4091
|
-
// The whole ladder was re-spaced in TD-07.16. It used to run
|
|
4092
|
-
// 0.01/0.02/0.04/0.06/0.08, where the first step was ~2 RGB values — under
|
|
4093
|
-
// the perceptual floor, so level 1 existed in the type system and nowhere on
|
|
4094
|
-
// screen. With drop-shadow now gated off below FLOATING_ELEVATION_MIN, TONE
|
|
4095
|
-
// is the only thing separating 0-3, so every step has to actually land.
|
|
4096
|
-
// Even 0.025 spacing, verified in elevation.test.ts as ΔL* > 1 per step.
|
|
4097
|
-
colorAdjustment: 0.025,
|
|
4098
|
-
shadowIntensity: "subtle",
|
|
4099
|
-
shadowStyle: "raised",
|
|
4100
|
-
description: "Subtle elevation (outline cards, subtle containers)"
|
|
4101
|
-
},
|
|
4102
|
-
// Level 2: Standard elevation (default cards, buttons)
|
|
4103
|
-
[2]: {
|
|
4104
|
-
name: "standard",
|
|
4105
|
-
colorAdjustment: 0.05,
|
|
4106
|
-
shadowIntensity: "medium",
|
|
4107
|
-
shadowStyle: "raised",
|
|
4108
|
-
description: "Standard elevation (default cards, raised buttons)"
|
|
4109
|
-
},
|
|
4110
|
-
// Level 3: Prominent elevation (important cards, modals)
|
|
4111
|
-
[3]: {
|
|
4112
|
-
name: "prominent",
|
|
4113
|
-
colorAdjustment: 0.075,
|
|
4114
|
-
shadowIntensity: "strong",
|
|
4115
|
-
shadowStyle: "raised",
|
|
4116
|
-
description: "Prominent elevation (important cards, modals, dropdowns)"
|
|
4117
|
-
},
|
|
4118
|
-
// Level 4: High elevation (overlays, popovers)
|
|
4119
|
-
[4]: {
|
|
4120
|
-
name: "high",
|
|
4121
|
-
colorAdjustment: 0.1,
|
|
4122
|
-
shadowIntensity: "strong",
|
|
4123
|
-
shadowStyle: "raised",
|
|
4124
|
-
description: "High elevation (overlays, popovers, tooltips)"
|
|
4125
|
-
},
|
|
4126
|
-
// Level 5: Floating (toasts, floating action buttons)
|
|
4127
|
-
[5]: {
|
|
4128
|
-
name: "floating",
|
|
4129
|
-
colorAdjustment: 0.13,
|
|
4130
|
-
shadowIntensity: "strong",
|
|
4131
|
-
shadowStyle: "raised",
|
|
4132
|
-
description: "Floating elevation (toasts, floating action buttons, highest z-index)"
|
|
4133
|
-
}
|
|
4174
|
+
var FLOATING_LIFT_MIN = 4;
|
|
4175
|
+
var LIFT_RIM_ALPHA = { dark: 0.12, light: 0.9 };
|
|
4176
|
+
var AMBIENT = {
|
|
4177
|
+
1: [
|
|
4178
|
+
{ y: 1, blur: 2, alpha: 0.35 },
|
|
4179
|
+
{ y: 2, blur: 6, alpha: 0.3 }
|
|
4180
|
+
],
|
|
4181
|
+
2: [
|
|
4182
|
+
{ y: 1, blur: 2, alpha: 0.35 },
|
|
4183
|
+
{ y: 4, blur: 12, alpha: 0.32 }
|
|
4184
|
+
],
|
|
4185
|
+
3: [
|
|
4186
|
+
{ y: 2, blur: 4, alpha: 0.35 },
|
|
4187
|
+
{ y: 8, blur: 22, alpha: 0.35 }
|
|
4188
|
+
],
|
|
4189
|
+
4: [
|
|
4190
|
+
{ y: 1, blur: 2, alpha: 0.35 },
|
|
4191
|
+
{ y: 10, blur: 24, alpha: 0.3 },
|
|
4192
|
+
{ y: 24, blur: 48, alpha: 0.2 }
|
|
4193
|
+
],
|
|
4194
|
+
5: [
|
|
4195
|
+
{ y: 2, blur: 4, alpha: 0.4 },
|
|
4196
|
+
{ y: 16, blur: 32, alpha: 0.35 },
|
|
4197
|
+
{ y: 32, blur: 64, alpha: 0.25 }
|
|
4198
|
+
]
|
|
4134
4199
|
};
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
const isLight = hsv.v > 0.6;
|
|
4142
|
-
const isSaturated = hsv.s > 0.3;
|
|
4143
|
-
const absLevel = Math.abs(level);
|
|
4144
|
-
const opacityBoost = Math.max(0, (absLevel - 1) * 0.05);
|
|
4145
|
-
if (isSaturated) {
|
|
4146
|
-
const rimLightValue = 0.95;
|
|
4147
|
-
const rimLightRgb = hsvToRgb(hsv.h, hsv.s * 0.3, rimLightValue);
|
|
4148
|
-
const baseOpacity = isLight ? 0.9 : 0.5;
|
|
4149
|
-
const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
|
|
4150
|
-
return `rgba(${rimLightRgb.r}, ${rimLightRgb.g}, ${rimLightRgb.b}, ${finalOpacity.toFixed(2)})`;
|
|
4151
|
-
} else {
|
|
4152
|
-
const baseOpacity = isLight ? 0.9 : 0.12;
|
|
4153
|
-
const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
|
|
4154
|
-
return `rgba(255, 255, 255, ${finalOpacity.toFixed(2)})`;
|
|
4155
|
-
}
|
|
4200
|
+
var AMBIENT_ALPHA_SCALE = { dark: 1, light: 0.4 };
|
|
4201
|
+
function ambientLayers(step, mode) {
|
|
4202
|
+
const scale = AMBIENT_ALPHA_SCALE[mode];
|
|
4203
|
+
return AMBIENT[step].map(
|
|
4204
|
+
({ y, blur, alpha: alpha2 }) => `0 ${y}px ${blur}px rgba(0,0,0,${(alpha2 * scale).toFixed(2)})`
|
|
4205
|
+
);
|
|
4156
4206
|
}
|
|
4157
|
-
function
|
|
4158
|
-
const
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.3)`,
|
|
4174
|
-
darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.4)`
|
|
4175
|
-
};
|
|
4176
|
-
} else {
|
|
4177
|
-
return {
|
|
4178
|
-
dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.5)`,
|
|
4179
|
-
darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.6)`
|
|
4180
|
-
};
|
|
4181
|
-
}
|
|
4182
|
-
} else {
|
|
4183
|
-
if (isLight) {
|
|
4184
|
-
return {
|
|
4185
|
-
dark: "rgba(0, 0, 0, 0.2)",
|
|
4186
|
-
darker: "rgba(0, 0, 0, 0.3)"
|
|
4187
|
-
};
|
|
4188
|
-
} else {
|
|
4189
|
-
return {
|
|
4190
|
-
dark: "rgba(0, 0, 0, 0.5)",
|
|
4191
|
-
darker: "rgba(0, 0, 0, 0.6)"
|
|
4192
|
-
};
|
|
4207
|
+
function liftShadow(step, mode = "dark", opts = {}) {
|
|
4208
|
+
const rim = opts.rim ?? LIFT_RIM_ALPHA[mode];
|
|
4209
|
+
const layers = ambientLayers(step, mode);
|
|
4210
|
+
if (rim > 0) layers.unshift(`inset 0 1px 0 rgba(255,255,255,${rim.toFixed(2)})`);
|
|
4211
|
+
return layers.join(", ");
|
|
4212
|
+
}
|
|
4213
|
+
function liftStyle(step, mode = "dark", opts = {}) {
|
|
4214
|
+
const deepest = AMBIENT[step][AMBIENT[step].length - 1];
|
|
4215
|
+
return reactNative.Platform.select({
|
|
4216
|
+
web: { boxShadow: liftShadow(step, mode, opts) },
|
|
4217
|
+
default: {
|
|
4218
|
+
shadowColor: "#000",
|
|
4219
|
+
shadowOffset: { width: 0, height: Math.round(deepest.y / 2) },
|
|
4220
|
+
shadowOpacity: deepest.alpha * AMBIENT_ALPHA_SCALE[mode],
|
|
4221
|
+
shadowRadius: deepest.blur / 2,
|
|
4222
|
+
elevation: step
|
|
4193
4223
|
}
|
|
4194
|
-
}
|
|
4195
|
-
}
|
|
4196
|
-
function getRimLightConfig() {
|
|
4197
|
-
return {
|
|
4198
|
-
offset: 1,
|
|
4199
|
-
// Fixed 1px for crisp rim
|
|
4200
|
-
blur: 1
|
|
4201
|
-
// Tight blur for crisp edge
|
|
4202
|
-
};
|
|
4203
|
-
}
|
|
4204
|
-
var elevationSurfaceCache = /* @__PURE__ */ new Map();
|
|
4205
|
-
var MAX_CACHE_SIZE = 100;
|
|
4206
|
-
function getCacheKey(baseColor, level, theme) {
|
|
4207
|
-
return `${baseColor}-${level}-${theme}`;
|
|
4224
|
+
});
|
|
4208
4225
|
}
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
}
|
|
4217
|
-
return lighten(baseColor, config.colorAdjustment);
|
|
4226
|
+
var FLOATING_ELEVATION_MIN = FLOATING_LIFT_MIN;
|
|
4227
|
+
function getPressedRecessShadow(fillColor, _mode = "dark") {
|
|
4228
|
+
const { boxShadow } = insetWell(fillColor);
|
|
4229
|
+
return reactNative.Platform.select({
|
|
4230
|
+
web: { boxShadow },
|
|
4231
|
+
default: {}
|
|
4232
|
+
});
|
|
4218
4233
|
}
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
}
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
}
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
}
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
if (level === 0) {
|
|
4240
|
-
return {};
|
|
4241
|
-
}
|
|
4242
|
-
const elevatedSurfaceColor = calculateElevationSurface(baseColor, level);
|
|
4243
|
-
const rimLightColor = calculateRimLightColor(baseColor, level);
|
|
4244
|
-
const darkShadowColors = calculateDarkShadowColors(elevatedSurfaceColor);
|
|
4245
|
-
const intensityConfig = {
|
|
4246
|
-
subtle: { offset: 1, blur: 2 },
|
|
4247
|
-
medium: { offset: 2, blur: 4 },
|
|
4248
|
-
strong: { offset: 2, blur: 5 }
|
|
4249
|
-
};
|
|
4250
|
-
const { offset, blur } = intensityConfig[config.shadowIntensity];
|
|
4251
|
-
const rimConfig = getRimLightConfig();
|
|
4252
|
-
if (config.shadowStyle === "pressed") {
|
|
4253
|
-
if (isHovered) {
|
|
4254
|
-
const hoverOffset = Math.max(1, Math.round(offset / 2));
|
|
4255
|
-
const hoverBlur = Math.max(1, Math.round(blur / 2));
|
|
4256
|
-
return reactNative.Platform.select({
|
|
4257
|
-
web: {
|
|
4258
|
-
boxShadow: `inset ${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
4259
|
-
},
|
|
4260
|
-
default: {
|
|
4261
|
-
shadowOpacity: 0,
|
|
4262
|
-
elevation: 0
|
|
4263
|
-
}
|
|
4264
|
-
});
|
|
4265
|
-
}
|
|
4266
|
-
return reactNative.Platform.select({
|
|
4267
|
-
web: {
|
|
4268
|
-
boxShadow: `inset ${offset}px ${offset}px ${blur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
4269
|
-
},
|
|
4270
|
-
default: {
|
|
4271
|
-
shadowOpacity: 0,
|
|
4272
|
-
elevation: 0
|
|
4273
|
-
}
|
|
4274
|
-
});
|
|
4275
|
-
} else {
|
|
4276
|
-
if (isHovered) {
|
|
4277
|
-
const hoverOffset = Math.max(1, Math.round(offset / 2));
|
|
4278
|
-
const hoverBlur = Math.max(1, Math.round(blur / 2));
|
|
4279
|
-
return reactNative.Platform.select({
|
|
4280
|
-
web: {
|
|
4281
|
-
boxShadow: `${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
4282
|
-
},
|
|
4283
|
-
default: {
|
|
4284
|
-
shadowColor: "#000",
|
|
4285
|
-
shadowOffset: { width: hoverOffset, height: hoverOffset },
|
|
4286
|
-
shadowOpacity: 0.2,
|
|
4287
|
-
shadowRadius: hoverBlur / 2,
|
|
4288
|
-
elevation: hoverOffset
|
|
4289
|
-
}
|
|
4290
|
-
});
|
|
4234
|
+
var glowConfig = {
|
|
4235
|
+
tight: { blur: 4, spread: 0, opacity: 0.4 },
|
|
4236
|
+
subtle: { blur: 12, spread: 0, opacity: 0.25 },
|
|
4237
|
+
medium: { blur: 20, spread: 2, opacity: 0.4 },
|
|
4238
|
+
strong: { blur: 30, spread: 4, opacity: 0.55 }
|
|
4239
|
+
};
|
|
4240
|
+
function getGlowShadow(color, intensity = "medium") {
|
|
4241
|
+
const config = glowConfig[intensity];
|
|
4242
|
+
const rgb = hexToRgb(color);
|
|
4243
|
+
if (!rgb) return {};
|
|
4244
|
+
return reactNative.Platform.select({
|
|
4245
|
+
web: {
|
|
4246
|
+
boxShadow: `0 0 ${config.blur}px ${config.spread}px rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${config.opacity})`
|
|
4247
|
+
},
|
|
4248
|
+
default: {
|
|
4249
|
+
shadowColor: color,
|
|
4250
|
+
shadowOffset: { width: 0, height: 0 },
|
|
4251
|
+
shadowOpacity: config.opacity,
|
|
4252
|
+
shadowRadius: config.blur / 2,
|
|
4253
|
+
elevation: 0
|
|
4291
4254
|
}
|
|
4292
|
-
|
|
4293
|
-
web: {
|
|
4294
|
-
boxShadow: `${offset}px ${offset}px ${blur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
4295
|
-
},
|
|
4296
|
-
default: {
|
|
4297
|
-
shadowColor: "#000",
|
|
4298
|
-
shadowOffset: { width: offset, height: offset },
|
|
4299
|
-
shadowOpacity: 0.3,
|
|
4300
|
-
shadowRadius: blur / 2,
|
|
4301
|
-
elevation: offset
|
|
4302
|
-
}
|
|
4303
|
-
});
|
|
4304
|
-
}
|
|
4305
|
-
}
|
|
4306
|
-
var FLOATING_ELEVATION_MIN = 4;
|
|
4307
|
-
function getElevationShadow(baseColor, level, theme, isHovered = false) {
|
|
4308
|
-
const cacheKey = getShadowCacheKey(baseColor, level, theme, isHovered);
|
|
4309
|
-
if (elevationShadowCache.has(cacheKey)) {
|
|
4310
|
-
return elevationShadowCache.get(cacheKey);
|
|
4311
|
-
}
|
|
4312
|
-
const result = level > 0 && level < FLOATING_ELEVATION_MIN ? {} : calculateElevationShadow(baseColor, level, theme, isHovered);
|
|
4313
|
-
if (elevationShadowCache.size >= MAX_SHADOW_CACHE_SIZE) {
|
|
4314
|
-
const firstKey = elevationShadowCache.keys().next().value;
|
|
4315
|
-
elevationShadowCache.delete(firstKey);
|
|
4316
|
-
}
|
|
4317
|
-
elevationShadowCache.set(cacheKey, result);
|
|
4318
|
-
return result;
|
|
4319
|
-
}
|
|
4320
|
-
function getBaseSurfaceColor(theme) {
|
|
4321
|
-
return theme === "light" ? semanticColorsLight["surface-raised"] : semanticColorsDark["surface-elevated"];
|
|
4255
|
+
});
|
|
4322
4256
|
}
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
allowed: [-2, -1, 0],
|
|
4336
|
-
default: -1
|
|
4337
|
-
},
|
|
4338
|
-
overlay: {
|
|
4339
|
-
allowed: [4, 5],
|
|
4340
|
-
default: 4
|
|
4257
|
+
function recessDepth(inherited, planesDown, mode) {
|
|
4258
|
+
let plane = inherited.level;
|
|
4259
|
+
for (let i = 0; i < planesDown; i++) plane = pressedLevel(plane);
|
|
4260
|
+
const backgroundColor = surfaceBackground(plane, mode);
|
|
4261
|
+
return { plane, backgroundColor, depthStyle: getPressedRecessShadow(backgroundColor, mode) };
|
|
4262
|
+
}
|
|
4263
|
+
function resolveSurfaceDepth(inherited, props) {
|
|
4264
|
+
const mode = props.theme ?? inherited.mode;
|
|
4265
|
+
const elevation = props.elevation ?? 0;
|
|
4266
|
+
if (props.pressed || elevation < 0) {
|
|
4267
|
+
const down = props.pressed ? 1 : -elevation;
|
|
4268
|
+
return { mode, step: 0, lifted: false, ...recessDepth(inherited, down, mode) };
|
|
4341
4269
|
}
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
const
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
}
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4270
|
+
const step = props.level != null ? 0 : props.raise ?? elevation;
|
|
4271
|
+
const floating = step >= FLOATING_ELEVATION_MIN;
|
|
4272
|
+
const plane = props.level ?? (floating ? "overlay" : raisedLevel(inherited.level, step));
|
|
4273
|
+
const lifted = props.lift ?? step > 0;
|
|
4274
|
+
const liftStep = Math.max(1, Math.min(5, step));
|
|
4275
|
+
const depthStyle = lifted ? liftStyle(liftStep, mode, props.liftOptions) : {};
|
|
4276
|
+
return { mode, plane, backgroundColor: surfaceBackground(plane, mode), depthStyle, step, lifted };
|
|
4277
|
+
}
|
|
4278
|
+
function useResolvedSurface(props) {
|
|
4279
|
+
const inherited = useSurface();
|
|
4280
|
+
const { level, raise, elevation, pressed, lift, liftOptions, theme } = props;
|
|
4281
|
+
return react.useMemo(
|
|
4282
|
+
() => resolveSurfaceDepth(inherited, {
|
|
4283
|
+
level,
|
|
4284
|
+
raise,
|
|
4285
|
+
elevation,
|
|
4286
|
+
pressed,
|
|
4287
|
+
lift,
|
|
4288
|
+
liftOptions,
|
|
4289
|
+
theme
|
|
4290
|
+
}),
|
|
4291
|
+
[inherited, level, raise, elevation, pressed, lift, liftOptions, theme]
|
|
4353
4292
|
);
|
|
4354
4293
|
}
|
|
4355
|
-
function getTheme() {
|
|
4356
|
-
if (typeof document === "undefined") return "dark";
|
|
4357
|
-
return document.documentElement.classList.contains("light") ? "light" : "dark";
|
|
4358
|
-
}
|
|
4359
|
-
var listeners = [];
|
|
4360
|
-
function subscribe(listener) {
|
|
4361
|
-
listeners = [...listeners, listener];
|
|
4362
|
-
if (typeof document !== "undefined" && listeners.length === 1) {
|
|
4363
|
-
const observer = new MutationObserver((mutations) => {
|
|
4364
|
-
for (const mutation of mutations) {
|
|
4365
|
-
if (mutation.type === "attributes" && mutation.attributeName === "class") {
|
|
4366
|
-
listeners.forEach((l) => l());
|
|
4367
|
-
}
|
|
4368
|
-
}
|
|
4369
|
-
});
|
|
4370
|
-
observer.observe(document.documentElement, {
|
|
4371
|
-
attributes: true,
|
|
4372
|
-
attributeFilter: ["class"]
|
|
4373
|
-
});
|
|
4374
|
-
subscribe._observer = observer;
|
|
4375
|
-
}
|
|
4376
|
-
return () => {
|
|
4377
|
-
listeners = listeners.filter((l) => l !== listener);
|
|
4378
|
-
if (listeners.length === 0 && subscribe._observer) {
|
|
4379
|
-
subscribe._observer.disconnect();
|
|
4380
|
-
subscribe._observer = null;
|
|
4381
|
-
}
|
|
4382
|
-
};
|
|
4383
|
-
}
|
|
4384
|
-
function getSnapshot() {
|
|
4385
|
-
return getTheme();
|
|
4386
|
-
}
|
|
4387
|
-
function getServerSnapshot() {
|
|
4388
|
-
return "dark";
|
|
4389
|
-
}
|
|
4390
|
-
function useTheme() {
|
|
4391
|
-
return react.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
4392
|
-
}
|
|
4393
4294
|
|
|
4394
4295
|
// src/components/ui/card/Card.tsx
|
|
4395
|
-
var
|
|
4296
|
+
var EDGE_CLASS = {
|
|
4396
4297
|
elevated: "",
|
|
4397
|
-
|
|
4398
|
-
outline: "border-2 border-hairline-strong",
|
|
4399
|
-
// Thicker border with stronger contrast
|
|
4298
|
+
accent: "",
|
|
4400
4299
|
filled: "",
|
|
4401
|
-
|
|
4402
|
-
accent: "border border-hairline",
|
|
4300
|
+
outline: "border border-hairline-strong",
|
|
4403
4301
|
subtle: "border border-hairline-subtle"
|
|
4404
4302
|
};
|
|
4303
|
+
var LIFTED = {
|
|
4304
|
+
elevated: true,
|
|
4305
|
+
accent: true,
|
|
4306
|
+
filled: false,
|
|
4307
|
+
outline: false,
|
|
4308
|
+
subtle: false
|
|
4309
|
+
};
|
|
4310
|
+
var STAYS_ON_HOST = {
|
|
4311
|
+
elevated: false,
|
|
4312
|
+
accent: false,
|
|
4313
|
+
filled: false,
|
|
4314
|
+
outline: true,
|
|
4315
|
+
subtle: true
|
|
4316
|
+
};
|
|
4317
|
+
function useCardDepth(variant, elevation, hovered) {
|
|
4318
|
+
const raise = STAYS_ON_HOST[variant] ? void 0 : elevation;
|
|
4319
|
+
const resolved = useResolvedSurface({ raise, lift: LIFTED[variant] });
|
|
4320
|
+
const depthStyle = react.useMemo(() => {
|
|
4321
|
+
if (!hovered || !LIFTED[variant]) return resolved.depthStyle;
|
|
4322
|
+
const hoverStep = Math.min(3, resolved.step + 1);
|
|
4323
|
+
return liftStyle(hoverStep, resolved.mode);
|
|
4324
|
+
}, [hovered, variant, resolved]);
|
|
4325
|
+
return { ...resolved, depthStyle };
|
|
4326
|
+
}
|
|
4405
4327
|
function Card({
|
|
4406
4328
|
variant = "elevated",
|
|
4407
4329
|
elevation = 2,
|
|
@@ -4422,89 +4344,54 @@ function Card({
|
|
|
4422
4344
|
}) {
|
|
4423
4345
|
const isClickable = isInteractive || !!onPress;
|
|
4424
4346
|
const [isHovered, setIsHovered] = react.useState(false);
|
|
4425
|
-
const
|
|
4426
|
-
const elevationLevel = react.useMemo(() => {
|
|
4427
|
-
const validated = getValidatedElevation("card", elevation);
|
|
4428
|
-
if (variant === "outline" || variant === "accent" || variant === "subtle") {
|
|
4429
|
-
return 1;
|
|
4430
|
-
}
|
|
4431
|
-
return validated;
|
|
4432
|
-
}, [variant, elevation]);
|
|
4433
|
-
const baseColor = react.useMemo(() => getBaseSurfaceColor(theme), [theme]);
|
|
4434
|
-
const surfaceColor = react.useMemo(() => {
|
|
4435
|
-
if ((variant === "outline" || variant === "accent") && theme === "light") {
|
|
4436
|
-
return "#FAFAFA";
|
|
4437
|
-
}
|
|
4438
|
-
if (variant === "subtle") {
|
|
4439
|
-
return getElevationSurface(baseColor, 0, theme);
|
|
4440
|
-
}
|
|
4441
|
-
return getElevationSurface(baseColor, elevationLevel, theme);
|
|
4442
|
-
}, [baseColor, elevationLevel, theme, variant]);
|
|
4443
|
-
const shadowStyle = react.useMemo(() => {
|
|
4444
|
-
const shouldHover = isHovered && isClickable;
|
|
4445
|
-
return getElevationShadow(baseColor, elevationLevel, theme, shouldHover);
|
|
4446
|
-
}, [baseColor, elevationLevel, theme, isHovered, isClickable]);
|
|
4447
|
-
const cardContent = isLoading ? /* @__PURE__ */ jsxs(jsxRuntime.Fragment, { children: [
|
|
4448
|
-
skeletonHasHeader && /* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
4449
|
-
/* @__PURE__ */ jsx(reactNative.View, { className: "h-5 w-1/3 bg-interactive-disabled rounded" }),
|
|
4450
|
-
/* @__PURE__ */ jsx(reactNative.View, { className: "mt-2 h-4 w-2/3 bg-interactive-disabled rounded" })
|
|
4451
|
-
] }),
|
|
4452
|
-
/* @__PURE__ */ jsx(CardContent, { children: Array.from({ length: skeletonContentLines }).map((_, i) => /* @__PURE__ */ jsx(
|
|
4453
|
-
reactNative.View,
|
|
4454
|
-
{
|
|
4455
|
-
className: cn(
|
|
4456
|
-
"h-4 bg-interactive-disabled rounded",
|
|
4457
|
-
i < skeletonContentLines - 1 ? "mb-2 w-full" : "w-4/5"
|
|
4458
|
-
)
|
|
4459
|
-
},
|
|
4460
|
-
i
|
|
4461
|
-
)) }),
|
|
4462
|
-
skeletonHasFooter && /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(reactNative.View, { className: "h-9 w-24 bg-interactive-disabled rounded" }) })
|
|
4463
|
-
] }) : children;
|
|
4347
|
+
const depth = useCardDepth(variant, elevation, isHovered && isClickable);
|
|
4464
4348
|
const baseClassName = cn(
|
|
4465
4349
|
"rounded-lg overflow-hidden relative",
|
|
4466
|
-
|
|
4467
|
-
variant === "outline" ? borderColor ? "border-2" : variantStyles[variant] : variantStyles[variant],
|
|
4468
|
-
// Remove Tailwind shadow classes - we're using elevation shadows via style prop
|
|
4350
|
+
borderColor ? "border" : EDGE_CLASS[variant],
|
|
4469
4351
|
isClickable && "web:cursor-pointer web:transition-all web:duration-150",
|
|
4470
4352
|
isClickable && "web:hover:-translate-y-0.5 active:scale-[0.99]",
|
|
4471
4353
|
isLoading && "pointer-events-none animate-pulse",
|
|
4472
4354
|
className
|
|
4473
4355
|
);
|
|
4474
|
-
const accentStyle = react.useMemo(() => variant === "accent" ? {
|
|
4475
|
-
borderLeftWidth: accentWidth ?? 3,
|
|
4476
|
-
borderLeftColor: accentColor ?? "var(--color-brand-primary)"
|
|
4477
|
-
} : {}, [variant, accentWidth, accentColor]);
|
|
4478
4356
|
const mergedStyle = react.useMemo(() => {
|
|
4479
|
-
const
|
|
4480
|
-
backgroundColor: bgColor ||
|
|
4357
|
+
const own = {
|
|
4358
|
+
backgroundColor: bgColor || depth.backgroundColor,
|
|
4481
4359
|
borderRadius: 8,
|
|
4482
4360
|
overflow: "hidden",
|
|
4483
|
-
...
|
|
4484
|
-
...accentStyle
|
|
4361
|
+
...depth.depthStyle
|
|
4485
4362
|
};
|
|
4486
|
-
if (
|
|
4487
|
-
|
|
4363
|
+
if (variant === "accent") {
|
|
4364
|
+
own.borderLeftWidth = accentWidth ?? 3;
|
|
4365
|
+
own.borderLeftColor = accentColor ?? "var(--color-brand-primary)";
|
|
4488
4366
|
}
|
|
4489
|
-
if (
|
|
4490
|
-
return [
|
|
4491
|
-
}, [style,
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4367
|
+
if (borderColor) own.borderColor = borderColor;
|
|
4368
|
+
return style ? [own, style] : own;
|
|
4369
|
+
}, [style, depth, bgColor, borderColor, variant, accentWidth, accentColor]);
|
|
4370
|
+
const context = react.useMemo(
|
|
4371
|
+
() => ({ mode: depth.mode, level: depth.plane }),
|
|
4372
|
+
[depth.mode, depth.plane]
|
|
4373
|
+
);
|
|
4374
|
+
const content = isLoading ? /* @__PURE__ */ jsx(
|
|
4375
|
+
SkeletonBody,
|
|
4376
|
+
{
|
|
4377
|
+
hasHeader: skeletonHasHeader,
|
|
4378
|
+
hasFooter: skeletonHasFooter,
|
|
4379
|
+
contentLines: skeletonContentLines
|
|
4380
|
+
}
|
|
4381
|
+
) : children;
|
|
4382
|
+
return /* @__PURE__ */ jsx(SurfaceContext.Provider, { value: context, children: isClickable ? /* @__PURE__ */ jsx(
|
|
4383
|
+
reactNative.Pressable,
|
|
4384
|
+
{
|
|
4385
|
+
onPress,
|
|
4386
|
+
onHoverIn: () => setIsHovered(true),
|
|
4387
|
+
onHoverOut: () => setIsHovered(false),
|
|
4388
|
+
accessibilityRole: "button",
|
|
4389
|
+
className: baseClassName,
|
|
4390
|
+
style: mergedStyle,
|
|
4391
|
+
...props,
|
|
4392
|
+
children: content
|
|
4393
|
+
}
|
|
4394
|
+
) : /* @__PURE__ */ jsx(reactNative.View, { className: baseClassName, style: mergedStyle, ...props, children: content }) });
|
|
4508
4395
|
}
|
|
4509
4396
|
function CardHeader({ children, className }) {
|
|
4510
4397
|
return /* @__PURE__ */ jsx(reactNative.View, { className: cn("px-6 py-6", className), children });
|
|
@@ -4515,60 +4402,88 @@ function CardContent({ children, className }) {
|
|
|
4515
4402
|
function CardFooter({ children, className }) {
|
|
4516
4403
|
return /* @__PURE__ */ jsx(reactNative.View, { className: cn("px-6 py-4 flex-row items-center gap-2", className), children });
|
|
4517
4404
|
}
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4405
|
+
function SkeletonBody({ hasHeader, hasFooter, contentLines }) {
|
|
4406
|
+
return /* @__PURE__ */ jsxs(jsxRuntime.Fragment, { children: [
|
|
4407
|
+
hasHeader && /* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
4408
|
+
/* @__PURE__ */ jsx(reactNative.View, { className: "h-5 w-1/3 bg-interactive-disabled rounded" }),
|
|
4409
|
+
/* @__PURE__ */ jsx(reactNative.View, { className: "mt-2 h-4 w-2/3 bg-interactive-disabled rounded" })
|
|
4410
|
+
] }),
|
|
4411
|
+
/* @__PURE__ */ jsx(CardContent, { children: Array.from({ length: contentLines }).map((_, i) => /* @__PURE__ */ jsx(
|
|
4412
|
+
reactNative.View,
|
|
4413
|
+
{
|
|
4414
|
+
className: cn(
|
|
4415
|
+
"h-4 bg-interactive-disabled rounded",
|
|
4416
|
+
i < contentLines - 1 ? "mb-2 w-full" : "w-4/5"
|
|
4417
|
+
)
|
|
4418
|
+
},
|
|
4419
|
+
i
|
|
4420
|
+
)) }),
|
|
4421
|
+
hasFooter && /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(reactNative.View, { className: "h-9 w-24 bg-interactive-disabled rounded" }) })
|
|
4422
|
+
] });
|
|
4423
|
+
}
|
|
4424
|
+
var solidFillToken = {
|
|
4425
|
+
success: "status-success",
|
|
4426
|
+
warning: "status-warning",
|
|
4427
|
+
error: "status-error",
|
|
4428
|
+
neutral: "text-tertiary"
|
|
4524
4429
|
};
|
|
4525
|
-
var
|
|
4526
|
-
"on-track": {
|
|
4527
|
-
|
|
4528
|
-
borderWidth: 1,
|
|
4529
|
-
borderColor: "rgba(46,213,115,0.3)"
|
|
4530
|
-
},
|
|
4531
|
-
deviation: {
|
|
4532
|
-
backgroundColor: "rgba(245,158,11,0.15)",
|
|
4533
|
-
borderWidth: 1,
|
|
4534
|
-
borderColor: "rgba(245,158,11,0.25)"
|
|
4535
|
-
},
|
|
4536
|
-
future: {
|
|
4537
|
-
backgroundColor: "rgba(107,114,128,0.1)",
|
|
4538
|
-
borderWidth: 1,
|
|
4539
|
-
borderStyle: "dashed",
|
|
4540
|
-
borderColor: "rgba(107,114,128,0.2)"
|
|
4541
|
-
}
|
|
4430
|
+
var ringWashToken = {
|
|
4431
|
+
"on-track": { fill: "status-success-subtle", border: "status-success-muted" },
|
|
4432
|
+
deviation: { fill: "status-warning-subtle", border: "status-warning-muted" }
|
|
4542
4433
|
};
|
|
4543
|
-
var
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4434
|
+
var FUTURE_FILL = alpha(greyRamp[500], 0.1);
|
|
4435
|
+
var FUTURE_BORDER = alpha(greyRamp[500], 0.2);
|
|
4436
|
+
var glyphToken = {
|
|
4437
|
+
success: "text-inverse",
|
|
4438
|
+
warning: "text-inverse",
|
|
4439
|
+
error: "text-inverse",
|
|
4440
|
+
neutral: "text-inverse",
|
|
4441
|
+
"on-track": "status-success",
|
|
4442
|
+
deviation: "status-warning",
|
|
4443
|
+
future: "text-tertiary"
|
|
4551
4444
|
};
|
|
4445
|
+
var glowColors = {
|
|
4446
|
+
success: semanticColorsDark["status-success"],
|
|
4447
|
+
warning: semanticColorsDark["status-warning"],
|
|
4448
|
+
error: semanticColorsDark["status-error"],
|
|
4449
|
+
neutral: greyRamp[500],
|
|
4450
|
+
"on-track": semanticColorsDark["status-success"],
|
|
4451
|
+
deviation: semanticColorsDark["status-warning"],
|
|
4452
|
+
future: greyRamp[500]
|
|
4453
|
+
};
|
|
4454
|
+
var glowStyles = Object.fromEntries(
|
|
4455
|
+
Object.entries(glowColors).map(([variant, color]) => [variant, getGlowShadow(color, "subtle")])
|
|
4456
|
+
);
|
|
4552
4457
|
var iconChars = {
|
|
4553
4458
|
check: "\u2713",
|
|
4554
4459
|
exclamation: "!",
|
|
4555
4460
|
dash: "\u2014"
|
|
4556
4461
|
};
|
|
4557
|
-
var iconColors = {
|
|
4558
|
-
success: "#0A5C52",
|
|
4559
|
-
warning: "#6B4000",
|
|
4560
|
-
error: "#5C1A1A",
|
|
4561
|
-
neutral: greyRamp[200],
|
|
4562
|
-
"on-track": t5["status-success"],
|
|
4563
|
-
deviation: t5["status-warning"],
|
|
4564
|
-
future: greyRamp[500]
|
|
4565
|
-
};
|
|
4566
4462
|
var sizeDimensions = {
|
|
4567
4463
|
sm: { size: 8, showIcon: false },
|
|
4568
4464
|
md: { size: 18, showIcon: true }
|
|
4569
4465
|
};
|
|
4570
4466
|
function isSolidVariant(variant) {
|
|
4571
|
-
return variant in
|
|
4467
|
+
return variant in solidFillToken;
|
|
4468
|
+
}
|
|
4469
|
+
function ringStyle(variant) {
|
|
4470
|
+
if (variant === "future") {
|
|
4471
|
+
return {
|
|
4472
|
+
backgroundColor: FUTURE_FILL,
|
|
4473
|
+
borderWidth: 1,
|
|
4474
|
+
borderStyle: "dashed",
|
|
4475
|
+
borderColor: FUTURE_BORDER
|
|
4476
|
+
};
|
|
4477
|
+
}
|
|
4478
|
+
if (variant === "on-track" || variant === "deviation") {
|
|
4479
|
+
const tokens = ringWashToken[variant];
|
|
4480
|
+
return {
|
|
4481
|
+
backgroundColor: resolveColor(tokens.fill),
|
|
4482
|
+
borderWidth: 1,
|
|
4483
|
+
borderColor: resolveColor(tokens.border)
|
|
4484
|
+
};
|
|
4485
|
+
}
|
|
4486
|
+
return void 0;
|
|
4572
4487
|
}
|
|
4573
4488
|
function StatusDot({
|
|
4574
4489
|
variant,
|
|
@@ -4581,7 +4496,7 @@ function StatusDot({
|
|
|
4581
4496
|
}) {
|
|
4582
4497
|
const config = sizeDimensions[size];
|
|
4583
4498
|
const solid = isSolidVariant(variant);
|
|
4584
|
-
const ring =
|
|
4499
|
+
const ring = ringStyle(variant);
|
|
4585
4500
|
const glowStyle = glow ? glowStyles[variant] : null;
|
|
4586
4501
|
const dot = /* @__PURE__ */ jsx(
|
|
4587
4502
|
reactNative.View,
|
|
@@ -4595,22 +4510,22 @@ function StatusDot({
|
|
|
4595
4510
|
justifyContent: "center",
|
|
4596
4511
|
flexShrink: 0
|
|
4597
4512
|
},
|
|
4598
|
-
solid ? { backgroundColor:
|
|
4599
|
-
ring
|
|
4513
|
+
solid ? { backgroundColor: resolveColor(solidFillToken[variant]) } : void 0,
|
|
4514
|
+
ring,
|
|
4600
4515
|
glowStyle ? glowStyle : void 0
|
|
4601
4516
|
],
|
|
4602
4517
|
accessibilityRole: "image",
|
|
4603
4518
|
accessibilityLabel: `${variant} status`,
|
|
4604
4519
|
testID: "status-dot",
|
|
4605
|
-
children: config.showIcon && icon &&
|
|
4606
|
-
|
|
4520
|
+
children: config.showIcon && icon && // The glyph was 11px/900, off the type scale (TOKENS.md §4); `boldLabel` is
|
|
4521
|
+
// the 12px sans label step and `font-black` keeps the original weight.
|
|
4522
|
+
/* @__PURE__ */ jsx(
|
|
4523
|
+
Typography,
|
|
4607
4524
|
{
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
color: iconColors[variant]
|
|
4613
|
-
},
|
|
4525
|
+
variant: "boldLabel",
|
|
4526
|
+
color: "inherit",
|
|
4527
|
+
className: "font-black leading-none",
|
|
4528
|
+
style: { color: resolveColor(glyphToken[variant]) },
|
|
4614
4529
|
accessibilityElementsHidden: true,
|
|
4615
4530
|
children: iconChars[icon]
|
|
4616
4531
|
}
|
|
@@ -4628,9 +4543,11 @@ function StatusDot({
|
|
|
4628
4543
|
children: [
|
|
4629
4544
|
/* @__PURE__ */ jsx(reactNative.View, { accessibilityElementsHidden: true, children: dot }),
|
|
4630
4545
|
/* @__PURE__ */ jsx(
|
|
4631
|
-
|
|
4546
|
+
Typography,
|
|
4632
4547
|
{
|
|
4633
|
-
|
|
4548
|
+
variant: "caption",
|
|
4549
|
+
color: "secondary",
|
|
4550
|
+
className: "leading-4",
|
|
4634
4551
|
accessibilityElementsHidden: true,
|
|
4635
4552
|
children: label
|
|
4636
4553
|
}
|
|
@@ -4646,14 +4563,14 @@ var MESO_ACCENT_GRADIENT_LIGHT = primitiveRamps.orange[300];
|
|
|
4646
4563
|
var WORKOUT_PILL_DELOAD = primitiveRamps.magenta[600];
|
|
4647
4564
|
|
|
4648
4565
|
// src/components/custom/Workout/MesoStatusCard.tsx
|
|
4649
|
-
var
|
|
4650
|
-
var
|
|
4566
|
+
var t3 = getSemanticColors("dark");
|
|
4567
|
+
var BRAND_PRIMARY4 = t3["brand-primary"];
|
|
4651
4568
|
var BRAND_PRIMARY_DARK = MESO_ACCENT_GRADIENT_DARK;
|
|
4652
4569
|
var BRAND_PRIMARY_LIGHT = MESO_ACCENT_GRADIENT_LIGHT;
|
|
4653
|
-
var SUCCESS =
|
|
4654
|
-
var WARNING =
|
|
4655
|
-
var ERROR =
|
|
4656
|
-
var ACCENT_STOPS = [BRAND_PRIMARY_DARK,
|
|
4570
|
+
var SUCCESS = t3["status-success"];
|
|
4571
|
+
var WARNING = t3["status-warning"];
|
|
4572
|
+
var ERROR = t3["status-error"];
|
|
4573
|
+
var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY4, BRAND_PRIMARY_LIGHT];
|
|
4657
4574
|
var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
|
|
4658
4575
|
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%)";
|
|
4659
4576
|
var STATUS_VARIANTS = {
|
|
@@ -4678,15 +4595,7 @@ function renderCoachingText(text, highlights) {
|
|
|
4678
4595
|
if (escaped.length === 0) return text;
|
|
4679
4596
|
const regex = new RegExp(`(${escaped.join("|")})`, "g");
|
|
4680
4597
|
return text.split(regex).map(
|
|
4681
|
-
(part, index) => highlights.includes(part) ? /* @__PURE__ */ jsx(
|
|
4682
|
-
reactNative.Text,
|
|
4683
|
-
{
|
|
4684
|
-
className: "text-text-primary",
|
|
4685
|
-
style: { fontWeight: "700" },
|
|
4686
|
-
children: part
|
|
4687
|
-
},
|
|
4688
|
-
`${part}-${index}`
|
|
4689
|
-
) : /* @__PURE__ */ jsx(react.Fragment, { children: part }, `t-${index}`)
|
|
4598
|
+
(part, index) => highlights.includes(part) ? /* @__PURE__ */ jsx(reactNative.Text, { className: "text-text-primary", style: { fontWeight: "700" }, children: part }, `${part}-${index}`) : /* @__PURE__ */ jsx(react.Fragment, { children: part }, `t-${index}`)
|
|
4690
4599
|
);
|
|
4691
4600
|
}
|
|
4692
4601
|
function StatusPill({ badge }) {
|
|
@@ -4771,41 +4680,34 @@ function Gauge({ gauge }) {
|
|
|
4771
4680
|
"aria-valuemax": 100,
|
|
4772
4681
|
testID: "meso-status-card-gauge",
|
|
4773
4682
|
children: [
|
|
4774
|
-
/* @__PURE__ */ jsxs(
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
},
|
|
4803
|
-
children: gauge.sublabel
|
|
4804
|
-
}
|
|
4805
|
-
)
|
|
4806
|
-
]
|
|
4807
|
-
}
|
|
4808
|
-
),
|
|
4683
|
+
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center justify-between", accessibilityElementsHidden: true, children: [
|
|
4684
|
+
/* @__PURE__ */ jsx(
|
|
4685
|
+
reactNative.Text,
|
|
4686
|
+
{
|
|
4687
|
+
className: "text-text-secondary",
|
|
4688
|
+
style: {
|
|
4689
|
+
fontSize: 10,
|
|
4690
|
+
fontFamily: "Inter, sans-serif",
|
|
4691
|
+
fontWeight: "500",
|
|
4692
|
+
letterSpacing: 0.5,
|
|
4693
|
+
textTransform: "uppercase"
|
|
4694
|
+
},
|
|
4695
|
+
children: gauge.label
|
|
4696
|
+
}
|
|
4697
|
+
),
|
|
4698
|
+
gauge.sublabel != null && /* @__PURE__ */ jsx(
|
|
4699
|
+
reactNative.Text,
|
|
4700
|
+
{
|
|
4701
|
+
className: "text-text-tertiary",
|
|
4702
|
+
style: {
|
|
4703
|
+
fontSize: 10,
|
|
4704
|
+
fontFamily: "Inter, sans-serif",
|
|
4705
|
+
fontWeight: "500"
|
|
4706
|
+
},
|
|
4707
|
+
children: gauge.sublabel
|
|
4708
|
+
}
|
|
4709
|
+
)
|
|
4710
|
+
] }),
|
|
4809
4711
|
/* @__PURE__ */ jsxs(
|
|
4810
4712
|
reactNative.View,
|
|
4811
4713
|
{
|
|
@@ -4846,7 +4748,8 @@ function Gauge({ gauge }) {
|
|
|
4846
4748
|
borderRadius: 9999,
|
|
4847
4749
|
borderWidth: 2,
|
|
4848
4750
|
backgroundColor: markerColor,
|
|
4849
|
-
|
|
4751
|
+
// A knob resting on the gauge: lift, with the ring as its edge.
|
|
4752
|
+
...liftStyle(1, "dark", { rim: 0 })
|
|
4850
4753
|
},
|
|
4851
4754
|
testID: "meso-status-card-gauge-marker"
|
|
4852
4755
|
}
|
|
@@ -4898,30 +4801,23 @@ function MesoStatusCard({
|
|
|
4898
4801
|
),
|
|
4899
4802
|
/* @__PURE__ */ jsxs(reactNative.View, { style: { padding: 14, gap: 14 }, testID: "meso-status-card-body", children: [
|
|
4900
4803
|
/* @__PURE__ */ jsxs(reactNative.View, { testID: "meso-status-card-header", children: [
|
|
4901
|
-
/* @__PURE__ */ jsxs(
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
children: mesoName
|
|
4919
|
-
}
|
|
4920
|
-
),
|
|
4921
|
-
/* @__PURE__ */ jsx(StatusPill, { badge: statusBadge })
|
|
4922
|
-
]
|
|
4923
|
-
}
|
|
4924
|
-
),
|
|
4804
|
+
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center justify-between", style: { gap: 8 }, children: [
|
|
4805
|
+
/* @__PURE__ */ jsx(
|
|
4806
|
+
reactNative.Text,
|
|
4807
|
+
{
|
|
4808
|
+
className: "text-text-primary",
|
|
4809
|
+
style: {
|
|
4810
|
+
flexShrink: 1,
|
|
4811
|
+
fontSize: 15,
|
|
4812
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
4813
|
+
fontWeight: "700"
|
|
4814
|
+
},
|
|
4815
|
+
testID: "meso-status-card-name",
|
|
4816
|
+
children: mesoName
|
|
4817
|
+
}
|
|
4818
|
+
),
|
|
4819
|
+
/* @__PURE__ */ jsx(StatusPill, { badge: statusBadge })
|
|
4820
|
+
] }),
|
|
4925
4821
|
/* @__PURE__ */ jsx(
|
|
4926
4822
|
reactNative.Text,
|
|
4927
4823
|
{
|
|
@@ -4936,15 +4832,7 @@ function MesoStatusCard({
|
|
|
4936
4832
|
}
|
|
4937
4833
|
)
|
|
4938
4834
|
] }),
|
|
4939
|
-
metrics.length > 0 && /* @__PURE__ */ jsx(
|
|
4940
|
-
reactNative.View,
|
|
4941
|
-
{
|
|
4942
|
-
className: "flex-row flex-wrap",
|
|
4943
|
-
style: { gap: 8 },
|
|
4944
|
-
testID: "meso-status-card-metrics",
|
|
4945
|
-
children: metrics.map((metric, index) => /* @__PURE__ */ jsx(MetricCell2, { metric }, `${metric.label}-${index}`))
|
|
4946
|
-
}
|
|
4947
|
-
),
|
|
4835
|
+
metrics.length > 0 && /* @__PURE__ */ jsx(reactNative.View, { className: "flex-row flex-wrap", style: { gap: 8 }, testID: "meso-status-card-metrics", children: metrics.map((metric, index) => /* @__PURE__ */ jsx(MetricCell2, { metric }, `${metric.label}-${index}`)) }),
|
|
4948
4836
|
gauges.length > 0 && /* @__PURE__ */ jsx(reactNative.View, { style: { gap: 12 }, testID: "meso-status-card-gauges", children: gauges.map((gauge, index) => /* @__PURE__ */ jsx(Gauge, { gauge }, `${gauge.label}-${index}`)) }),
|
|
4949
4837
|
coaching != null && /* @__PURE__ */ jsx(
|
|
4950
4838
|
reactNative.View,
|
|
@@ -5010,7 +4898,7 @@ function MesoStatusCard({
|
|
|
5010
4898
|
);
|
|
5011
4899
|
}
|
|
5012
4900
|
var sem = getSemanticColors("dark");
|
|
5013
|
-
var
|
|
4901
|
+
var BRAND_PRIMARY5 = sem["brand-primary"];
|
|
5014
4902
|
var PROJECTION_LINE_COLOR = resolveColor("text-tertiary");
|
|
5015
4903
|
var STATUS_SUCCESS2 = sem["status-success"];
|
|
5016
4904
|
var STATUS_ERROR2 = sem["status-error"];
|
|
@@ -5023,8 +4911,8 @@ var ERROR_PILL_BORDER = "rgba(209,67,67,0.20)";
|
|
|
5023
4911
|
var PLOT_LEFT = 26;
|
|
5024
4912
|
var TOOLTIP_WIDTH = 124;
|
|
5025
4913
|
function timeOf(dateStr) {
|
|
5026
|
-
const
|
|
5027
|
-
return Number.isNaN(
|
|
4914
|
+
const t7 = Date.parse(dateStr);
|
|
4915
|
+
return Number.isNaN(t7) ? 0 : t7;
|
|
5028
4916
|
}
|
|
5029
4917
|
function formatValue(value) {
|
|
5030
4918
|
return `${Math.round(value)}`;
|
|
@@ -5065,9 +4953,7 @@ function buildGeometry(data, projection, boundaries, width, height) {
|
|
|
5065
4953
|
point,
|
|
5066
4954
|
index
|
|
5067
4955
|
}));
|
|
5068
|
-
const tickValues = Array.from(
|
|
5069
|
-
new Set([yMax, (yMin + yMax) / 2, yMin].map((v) => Math.round(v)))
|
|
5070
|
-
);
|
|
4956
|
+
const tickValues = Array.from(new Set([yMax, (yMin + yMax) / 2, yMin].map((v) => Math.round(v))));
|
|
5071
4957
|
const gridLines = tickValues.map((v) => ({ y: toY(v), label: formatValue(v) }));
|
|
5072
4958
|
return {
|
|
5073
4959
|
hasData: true,
|
|
@@ -5156,10 +5042,7 @@ function StrengthTrendChart({
|
|
|
5156
5042
|
() => buildGeometry(data, projection, mesoBoundaries, width, height),
|
|
5157
5043
|
[data, projection, mesoBoundaries, width, height]
|
|
5158
5044
|
);
|
|
5159
|
-
const trend = react.useMemo(
|
|
5160
|
-
() => computeTrend(data, mesoBoundaries),
|
|
5161
|
-
[data, mesoBoundaries]
|
|
5162
|
-
);
|
|
5045
|
+
const trend = react.useMemo(() => computeTrend(data, mesoBoundaries), [data, mesoBoundaries]);
|
|
5163
5046
|
const [reveal] = react.useState(() => new reactNative.Animated.Value(animateOnMount ? 0 : 1));
|
|
5164
5047
|
const [selected, setSelected] = react.useState(null);
|
|
5165
5048
|
react.useEffect(() => {
|
|
@@ -5196,7 +5079,14 @@ function StrengthTrendChart({
|
|
|
5196
5079
|
alignItems: "center",
|
|
5197
5080
|
justifyContent: "center"
|
|
5198
5081
|
},
|
|
5199
|
-
children: /* @__PURE__ */ jsx(
|
|
5082
|
+
children: /* @__PURE__ */ jsx(
|
|
5083
|
+
reactNative.Text,
|
|
5084
|
+
{
|
|
5085
|
+
className: "text-text-tertiary",
|
|
5086
|
+
style: { fontSize: 12, fontFamily: "Inter, sans-serif" },
|
|
5087
|
+
children: "No strength data yet"
|
|
5088
|
+
}
|
|
5089
|
+
)
|
|
5200
5090
|
}
|
|
5201
5091
|
)
|
|
5202
5092
|
}
|
|
@@ -5207,316 +5097,333 @@ function StrengthTrendChart({
|
|
|
5207
5097
|
outputRange: [0, width]
|
|
5208
5098
|
});
|
|
5209
5099
|
const selectedCoord = selected != null ? geometry.actual[selected] : void 0;
|
|
5210
|
-
return /* @__PURE__ */ jsxs(
|
|
5211
|
-
reactNative.View,
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
right: 0,
|
|
5236
|
-
top: line.y,
|
|
5237
|
-
height: 1,
|
|
5238
|
-
backgroundColor: GRID_LINE
|
|
5239
|
-
},
|
|
5240
|
-
children: /* @__PURE__ */ jsx(
|
|
5241
|
-
reactNative.Text,
|
|
5242
|
-
{
|
|
5243
|
-
className: "text-text-tertiary",
|
|
5244
|
-
style: {
|
|
5245
|
-
position: "absolute",
|
|
5246
|
-
left: -PLOT_LEFT,
|
|
5247
|
-
top: -6,
|
|
5248
|
-
width: PLOT_LEFT - 4,
|
|
5249
|
-
textAlign: "right",
|
|
5250
|
-
fontSize: 9,
|
|
5251
|
-
fontFamily: "Inter, sans-serif"
|
|
5252
|
-
},
|
|
5253
|
-
children: line.label
|
|
5254
|
-
}
|
|
5255
|
-
)
|
|
5256
|
-
},
|
|
5257
|
-
`grid-${i}`
|
|
5258
|
-
)),
|
|
5259
|
-
geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
|
|
5260
|
-
reactNative.View,
|
|
5261
|
-
{
|
|
5262
|
-
accessibilityElementsHidden: true,
|
|
5263
|
-
testID: "strength-trend-chart-meso-boundary",
|
|
5264
|
-
style: {
|
|
5265
|
-
position: "absolute",
|
|
5266
|
-
left: boundary.x,
|
|
5267
|
-
top: 0,
|
|
5268
|
-
width: 0,
|
|
5269
|
-
height,
|
|
5270
|
-
borderLeftWidth: 1,
|
|
5271
|
-
borderStyle: "dashed",
|
|
5272
|
-
borderLeftColor: "rgba(255,255,255,0.10)"
|
|
5273
|
-
}
|
|
5274
|
-
},
|
|
5275
|
-
`boundary-${i}`
|
|
5276
|
-
)),
|
|
5277
|
-
/* @__PURE__ */ jsx(
|
|
5278
|
-
reactNative.Animated.View,
|
|
5100
|
+
return /* @__PURE__ */ jsxs(reactNative.View, { style: { width }, className: cn(className), testID: "strength-trend-chart", ...props, children: [
|
|
5101
|
+
/* @__PURE__ */ jsxs(reactNative.View, { style: { width, height, position: "relative" }, children: [
|
|
5102
|
+
/* @__PURE__ */ jsxs(
|
|
5103
|
+
reactNative.View,
|
|
5104
|
+
{
|
|
5105
|
+
style: { position: "absolute", top: 0, left: 0, width, height },
|
|
5106
|
+
accessibilityRole: "image",
|
|
5107
|
+
accessibilityLabel: ariaLabel,
|
|
5108
|
+
testID: "strength-trend-chart-canvas",
|
|
5109
|
+
children: [
|
|
5110
|
+
geometry.gridLines.map((line, i) => /* @__PURE__ */ jsx(
|
|
5111
|
+
reactNative.View,
|
|
5112
|
+
{
|
|
5113
|
+
accessibilityElementsHidden: true,
|
|
5114
|
+
testID: "strength-trend-chart-gridline",
|
|
5115
|
+
style: {
|
|
5116
|
+
position: "absolute",
|
|
5117
|
+
left: PLOT_LEFT,
|
|
5118
|
+
right: 0,
|
|
5119
|
+
top: line.y,
|
|
5120
|
+
height: 1,
|
|
5121
|
+
backgroundColor: GRID_LINE
|
|
5122
|
+
},
|
|
5123
|
+
children: /* @__PURE__ */ jsx(
|
|
5124
|
+
reactNative.Text,
|
|
5279
5125
|
{
|
|
5126
|
+
className: "text-text-tertiary",
|
|
5280
5127
|
style: {
|
|
5281
5128
|
position: "absolute",
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
width:
|
|
5285
|
-
|
|
5286
|
-
|
|
5129
|
+
left: -PLOT_LEFT,
|
|
5130
|
+
top: -6,
|
|
5131
|
+
width: PLOT_LEFT - 4,
|
|
5132
|
+
textAlign: "right",
|
|
5133
|
+
fontSize: 9,
|
|
5134
|
+
fontFamily: "Inter, sans-serif"
|
|
5287
5135
|
},
|
|
5288
|
-
|
|
5289
|
-
children: /* @__PURE__ */ jsxs(reactNative.View, { style: { width, height, position: "absolute", top: 0, left: 0 }, children: [
|
|
5290
|
-
/* @__PURE__ */ jsx(
|
|
5291
|
-
ChartLine,
|
|
5292
|
-
{
|
|
5293
|
-
coords: geometry.projection,
|
|
5294
|
-
color: PROJECTION_LINE_COLOR,
|
|
5295
|
-
strokeWidth: 2,
|
|
5296
|
-
dashed: true,
|
|
5297
|
-
testID: "strength-trend-chart-projection-segment"
|
|
5298
|
-
}
|
|
5299
|
-
),
|
|
5300
|
-
/* @__PURE__ */ jsx(
|
|
5301
|
-
ChartLine,
|
|
5302
|
-
{
|
|
5303
|
-
coords: geometry.actual,
|
|
5304
|
-
color: BRAND_PRIMARY6,
|
|
5305
|
-
strokeWidth: 2.5,
|
|
5306
|
-
testID: "strength-trend-chart-actual-segment"
|
|
5307
|
-
}
|
|
5308
|
-
)
|
|
5309
|
-
] })
|
|
5136
|
+
children: line.label
|
|
5310
5137
|
}
|
|
5311
|
-
),
|
|
5312
|
-
geometry.actual.map(
|
|
5313
|
-
(c2) => c2.point.isPR ? /* @__PURE__ */ jsx(
|
|
5314
|
-
reactNative.Text,
|
|
5315
|
-
{
|
|
5316
|
-
accessibilityElementsHidden: true,
|
|
5317
|
-
testID: "strength-trend-chart-pr-star",
|
|
5318
|
-
style: {
|
|
5319
|
-
position: "absolute",
|
|
5320
|
-
left: c2.x - 7,
|
|
5321
|
-
top: c2.y - 20,
|
|
5322
|
-
fontSize: 12,
|
|
5323
|
-
color: STATUS_WARNING2
|
|
5324
|
-
},
|
|
5325
|
-
children: "\u2605"
|
|
5326
|
-
},
|
|
5327
|
-
`star-${c2.index}`
|
|
5328
|
-
) : null
|
|
5329
5138
|
)
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5139
|
+
},
|
|
5140
|
+
`grid-${i}`
|
|
5141
|
+
)),
|
|
5142
|
+
geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
|
|
5143
|
+
reactNative.View,
|
|
5144
|
+
{
|
|
5145
|
+
accessibilityElementsHidden: true,
|
|
5146
|
+
testID: "strength-trend-chart-meso-boundary",
|
|
5147
|
+
style: {
|
|
5148
|
+
position: "absolute",
|
|
5149
|
+
left: boundary.x,
|
|
5150
|
+
top: 0,
|
|
5151
|
+
width: 0,
|
|
5152
|
+
height,
|
|
5153
|
+
borderLeftWidth: 1,
|
|
5154
|
+
borderStyle: "dashed",
|
|
5155
|
+
borderLeftColor: "rgba(255,255,255,0.10)"
|
|
5156
|
+
}
|
|
5157
|
+
},
|
|
5158
|
+
`boundary-${i}`
|
|
5159
|
+
)),
|
|
5160
|
+
/* @__PURE__ */ jsx(
|
|
5161
|
+
reactNative.Animated.View,
|
|
5162
|
+
{
|
|
5163
|
+
style: {
|
|
5164
|
+
position: "absolute",
|
|
5165
|
+
top: 0,
|
|
5166
|
+
left: 0,
|
|
5167
|
+
width: revealWidth,
|
|
5168
|
+
height,
|
|
5169
|
+
overflow: "hidden"
|
|
5170
|
+
},
|
|
5171
|
+
testID: "strength-trend-chart-reveal",
|
|
5172
|
+
children: /* @__PURE__ */ jsxs(reactNative.View, { style: { width, height, position: "absolute", top: 0, left: 0 }, children: [
|
|
5173
|
+
/* @__PURE__ */ jsx(
|
|
5174
|
+
ChartLine,
|
|
5175
|
+
{
|
|
5176
|
+
coords: geometry.projection,
|
|
5177
|
+
color: PROJECTION_LINE_COLOR,
|
|
5178
|
+
strokeWidth: 2,
|
|
5179
|
+
dashed: true,
|
|
5180
|
+
testID: "strength-trend-chart-projection-segment"
|
|
5358
5181
|
}
|
|
5182
|
+
),
|
|
5183
|
+
/* @__PURE__ */ jsx(
|
|
5184
|
+
ChartLine,
|
|
5185
|
+
{
|
|
5186
|
+
coords: geometry.actual,
|
|
5187
|
+
color: BRAND_PRIMARY5,
|
|
5188
|
+
strokeWidth: 2.5,
|
|
5189
|
+
testID: "strength-trend-chart-actual-segment"
|
|
5190
|
+
}
|
|
5191
|
+
)
|
|
5192
|
+
] })
|
|
5193
|
+
}
|
|
5194
|
+
),
|
|
5195
|
+
geometry.actual.map(
|
|
5196
|
+
(c2) => c2.point.isPR ? /* @__PURE__ */ jsx(
|
|
5197
|
+
reactNative.Text,
|
|
5198
|
+
{
|
|
5199
|
+
accessibilityElementsHidden: true,
|
|
5200
|
+
testID: "strength-trend-chart-pr-star",
|
|
5201
|
+
style: {
|
|
5202
|
+
position: "absolute",
|
|
5203
|
+
left: c2.x - 7,
|
|
5204
|
+
top: c2.y - 20,
|
|
5205
|
+
fontSize: 12,
|
|
5206
|
+
color: STATUS_WARNING2
|
|
5359
5207
|
},
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5208
|
+
children: "\u2605"
|
|
5209
|
+
},
|
|
5210
|
+
`star-${c2.index}`
|
|
5211
|
+
) : null
|
|
5212
|
+
)
|
|
5213
|
+
]
|
|
5214
|
+
}
|
|
5215
|
+
),
|
|
5216
|
+
/* @__PURE__ */ jsx(
|
|
5217
|
+
reactNative.View,
|
|
5218
|
+
{
|
|
5219
|
+
style: { position: "absolute", top: 0, left: 0, width, height },
|
|
5220
|
+
testID: "strength-trend-chart-points",
|
|
5221
|
+
children: geometry.actual.map((c2) => {
|
|
5222
|
+
const label = c2.point.sessionLabel ?? c2.point.date;
|
|
5223
|
+
return /* @__PURE__ */ jsx(
|
|
5224
|
+
reactNative.Pressable,
|
|
5225
|
+
{
|
|
5226
|
+
testID: "strength-trend-chart-point",
|
|
5227
|
+
accessibilityRole: "button",
|
|
5228
|
+
accessibilityLabel: `${label}: ${formatValue(c2.point.e1rm)} ${unit}${c2.point.isPR ? ", personal record" : ""}`,
|
|
5229
|
+
onPress: () => {
|
|
5230
|
+
setSelected(c2.index);
|
|
5231
|
+
onPointPress?.(c2.point);
|
|
5232
|
+
},
|
|
5233
|
+
style: {
|
|
5234
|
+
position: "absolute",
|
|
5235
|
+
left: c2.x - 4,
|
|
5236
|
+
top: c2.y - 4,
|
|
5237
|
+
width: 8,
|
|
5238
|
+
height: 8,
|
|
5239
|
+
borderRadius: 1,
|
|
5240
|
+
backgroundColor: BRAND_PRIMARY5
|
|
5241
|
+
}
|
|
5383
5242
|
},
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
reactNative.Text,
|
|
5411
|
-
{
|
|
5412
|
-
style: {
|
|
5413
|
-
marginTop: 1,
|
|
5414
|
-
fontSize: 10,
|
|
5415
|
-
fontFamily: "Inter, sans-serif",
|
|
5416
|
-
color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
5417
|
-
},
|
|
5418
|
-
children: `${selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? "+" : "-"}${Math.abs(
|
|
5419
|
-
selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm
|
|
5420
|
-
).toFixed(1)} ${unit}`
|
|
5421
|
-
}
|
|
5422
|
-
)
|
|
5423
|
-
]
|
|
5424
|
-
}
|
|
5425
|
-
)
|
|
5426
|
-
] }),
|
|
5427
|
-
geometry.boundaries.length > 0 && /* @__PURE__ */ jsx(
|
|
5428
|
-
reactNative.View,
|
|
5429
|
-
{
|
|
5430
|
-
style: { width, height: 14, position: "relative", marginTop: 2 },
|
|
5431
|
-
accessibilityElementsHidden: true,
|
|
5432
|
-
testID: "strength-trend-chart-axis",
|
|
5433
|
-
children: geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
|
|
5243
|
+
`point-${c2.index}`
|
|
5244
|
+
);
|
|
5245
|
+
})
|
|
5246
|
+
}
|
|
5247
|
+
),
|
|
5248
|
+
selectedCoord && /* @__PURE__ */ jsxs(
|
|
5249
|
+
reactNative.View,
|
|
5250
|
+
{
|
|
5251
|
+
testID: "strength-trend-chart-tooltip",
|
|
5252
|
+
accessibilityElementsHidden: true,
|
|
5253
|
+
className: "bg-surface-elevated border-hairline-strong",
|
|
5254
|
+
style: {
|
|
5255
|
+
position: "absolute",
|
|
5256
|
+
left: Math.max(
|
|
5257
|
+
0,
|
|
5258
|
+
Math.min(width - TOOLTIP_WIDTH, selectedCoord.x - TOOLTIP_WIDTH / 2)
|
|
5259
|
+
),
|
|
5260
|
+
top: Math.max(0, selectedCoord.y - 52),
|
|
5261
|
+
maxWidth: TOOLTIP_WIDTH,
|
|
5262
|
+
borderWidth: 1,
|
|
5263
|
+
borderRadius: 8,
|
|
5264
|
+
paddingVertical: 8,
|
|
5265
|
+
paddingHorizontal: 10
|
|
5266
|
+
},
|
|
5267
|
+
children: [
|
|
5268
|
+
/* @__PURE__ */ jsx(
|
|
5434
5269
|
reactNative.Text,
|
|
5435
5270
|
{
|
|
5436
|
-
testID: "strength-trend-chart-axis-label",
|
|
5437
5271
|
className: "text-text-tertiary",
|
|
5438
5272
|
style: {
|
|
5439
|
-
position: "absolute",
|
|
5440
|
-
left: boundary.x - 24,
|
|
5441
|
-
width: 48,
|
|
5442
|
-
textAlign: "center",
|
|
5443
5273
|
fontSize: 10,
|
|
5444
5274
|
fontFamily: "Inter, sans-serif"
|
|
5445
5275
|
},
|
|
5446
|
-
children:
|
|
5447
|
-
}
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
borderColor: trend.positive ? SUCCESS_PILL_BORDER : ERROR_PILL_BORDER
|
|
5464
|
-
},
|
|
5465
|
-
children: /* @__PURE__ */ jsx(
|
|
5276
|
+
children: selectedCoord.point.sessionLabel ?? selectedCoord.point.date
|
|
5277
|
+
}
|
|
5278
|
+
),
|
|
5279
|
+
/* @__PURE__ */ jsx(
|
|
5280
|
+
reactNative.Text,
|
|
5281
|
+
{
|
|
5282
|
+
className: "text-text-primary",
|
|
5283
|
+
style: {
|
|
5284
|
+
marginTop: 2,
|
|
5285
|
+
fontSize: 13,
|
|
5286
|
+
fontFamily: "Inter, sans-serif",
|
|
5287
|
+
fontWeight: "700"
|
|
5288
|
+
},
|
|
5289
|
+
children: `${formatValue(selectedCoord.point.e1rm)} ${unit}`
|
|
5290
|
+
}
|
|
5291
|
+
),
|
|
5292
|
+
selected != null && selected > 0 && /* @__PURE__ */ jsx(
|
|
5466
5293
|
reactNative.Text,
|
|
5467
5294
|
{
|
|
5468
5295
|
style: {
|
|
5469
|
-
|
|
5296
|
+
marginTop: 1,
|
|
5297
|
+
fontSize: 10,
|
|
5470
5298
|
fontFamily: "Inter, sans-serif",
|
|
5471
|
-
|
|
5472
|
-
color: trend.positive ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
5299
|
+
color: selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
5473
5300
|
},
|
|
5474
|
-
children:
|
|
5301
|
+
children: `${selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm >= 0 ? "+" : "-"}${Math.abs(
|
|
5302
|
+
selectedCoord.point.e1rm - geometry.actual[selected - 1].point.e1rm
|
|
5303
|
+
).toFixed(1)} ${unit}`
|
|
5475
5304
|
}
|
|
5476
5305
|
)
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5306
|
+
]
|
|
5307
|
+
}
|
|
5308
|
+
)
|
|
5309
|
+
] }),
|
|
5310
|
+
geometry.boundaries.length > 0 && /* @__PURE__ */ jsx(
|
|
5311
|
+
reactNative.View,
|
|
5312
|
+
{
|
|
5313
|
+
style: { width, height: 14, position: "relative", marginTop: 2 },
|
|
5314
|
+
accessibilityElementsHidden: true,
|
|
5315
|
+
testID: "strength-trend-chart-axis",
|
|
5316
|
+
children: geometry.boundaries.map((boundary, i) => /* @__PURE__ */ jsx(
|
|
5317
|
+
reactNative.Text,
|
|
5481
5318
|
{
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5319
|
+
testID: "strength-trend-chart-axis-label",
|
|
5320
|
+
className: "text-text-tertiary",
|
|
5321
|
+
style: {
|
|
5322
|
+
position: "absolute",
|
|
5323
|
+
left: boundary.x - 24,
|
|
5324
|
+
width: 48,
|
|
5325
|
+
textAlign: "center",
|
|
5326
|
+
fontSize: 10,
|
|
5327
|
+
fontFamily: "Inter, sans-serif"
|
|
5328
|
+
},
|
|
5329
|
+
children: boundary.label
|
|
5330
|
+
},
|
|
5331
|
+
`axis-${i}`
|
|
5332
|
+
))
|
|
5333
|
+
}
|
|
5334
|
+
),
|
|
5335
|
+
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-row", style: { marginTop: 8 }, children: /* @__PURE__ */ jsx(
|
|
5336
|
+
reactNative.View,
|
|
5337
|
+
{
|
|
5338
|
+
testID: "strength-trend-chart-trend-pill",
|
|
5339
|
+
accessibilityLabel: `Strength trend: ${trendText}`,
|
|
5340
|
+
style: {
|
|
5341
|
+
paddingVertical: 3,
|
|
5342
|
+
paddingHorizontal: 8,
|
|
5343
|
+
borderRadius: 4,
|
|
5344
|
+
borderWidth: 1,
|
|
5345
|
+
backgroundColor: trend.positive ? SUCCESS_PILL_BG : ERROR_PILL_BG,
|
|
5346
|
+
borderColor: trend.positive ? SUCCESS_PILL_BORDER : ERROR_PILL_BORDER
|
|
5347
|
+
},
|
|
5348
|
+
children: /* @__PURE__ */ jsx(
|
|
5349
|
+
reactNative.Text,
|
|
5350
|
+
{
|
|
5351
|
+
style: {
|
|
5352
|
+
fontSize: 11,
|
|
5353
|
+
fontFamily: "Inter, sans-serif",
|
|
5354
|
+
fontWeight: "600",
|
|
5355
|
+
color: trend.positive ? STATUS_SUCCESS2 : STATUS_ERROR2
|
|
5356
|
+
},
|
|
5357
|
+
children: trendText
|
|
5510
5358
|
}
|
|
5511
5359
|
)
|
|
5512
|
-
|
|
5513
|
-
}
|
|
5514
|
-
|
|
5360
|
+
}
|
|
5361
|
+
) }),
|
|
5362
|
+
/* @__PURE__ */ jsxs(
|
|
5363
|
+
reactNative.View,
|
|
5364
|
+
{
|
|
5365
|
+
className: "flex-row items-center",
|
|
5366
|
+
style: { marginTop: 8, gap: 14 },
|
|
5367
|
+
testID: "strength-trend-chart-legend",
|
|
5368
|
+
children: [
|
|
5369
|
+
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
5370
|
+
/* @__PURE__ */ jsx(
|
|
5371
|
+
reactNative.View,
|
|
5372
|
+
{
|
|
5373
|
+
style: { width: 14, height: 2.5, borderRadius: 1.5, backgroundColor: BRAND_PRIMARY5 }
|
|
5374
|
+
}
|
|
5375
|
+
),
|
|
5376
|
+
/* @__PURE__ */ jsx(
|
|
5377
|
+
reactNative.Text,
|
|
5378
|
+
{
|
|
5379
|
+
className: "text-text-secondary",
|
|
5380
|
+
style: { fontSize: 10, fontFamily: "Inter, sans-serif" },
|
|
5381
|
+
children: "Actual"
|
|
5382
|
+
}
|
|
5383
|
+
)
|
|
5384
|
+
] }),
|
|
5385
|
+
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
5386
|
+
/* @__PURE__ */ jsx(
|
|
5387
|
+
reactNative.View,
|
|
5388
|
+
{
|
|
5389
|
+
style: {
|
|
5390
|
+
width: 14,
|
|
5391
|
+
height: 0,
|
|
5392
|
+
borderTopWidth: 2,
|
|
5393
|
+
borderStyle: "dashed",
|
|
5394
|
+
borderTopColor: PROJECTION_LINE_COLOR
|
|
5395
|
+
}
|
|
5396
|
+
}
|
|
5397
|
+
),
|
|
5398
|
+
/* @__PURE__ */ jsx(
|
|
5399
|
+
reactNative.Text,
|
|
5400
|
+
{
|
|
5401
|
+
className: "text-text-secondary",
|
|
5402
|
+
style: { fontSize: 10, fontFamily: "Inter, sans-serif" },
|
|
5403
|
+
children: "Projected"
|
|
5404
|
+
}
|
|
5405
|
+
)
|
|
5406
|
+
] }),
|
|
5407
|
+
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 5 }, children: [
|
|
5408
|
+
/* @__PURE__ */ jsx(reactNative.Text, { style: { fontSize: 12, color: STATUS_WARNING2 }, children: "\u2605" }),
|
|
5409
|
+
/* @__PURE__ */ jsx(
|
|
5410
|
+
reactNative.Text,
|
|
5411
|
+
{
|
|
5412
|
+
className: "text-text-secondary",
|
|
5413
|
+
style: { fontSize: 10, fontFamily: "Inter, sans-serif" },
|
|
5414
|
+
children: "PR"
|
|
5415
|
+
}
|
|
5416
|
+
)
|
|
5417
|
+
] })
|
|
5418
|
+
]
|
|
5419
|
+
}
|
|
5420
|
+
)
|
|
5421
|
+
] });
|
|
5515
5422
|
}
|
|
5516
|
-
var
|
|
5517
|
-
var STATUS_SUCCESS3 =
|
|
5518
|
-
var STATUS_WARNING3 =
|
|
5519
|
-
var STATUS_INFO =
|
|
5423
|
+
var t4 = getSemanticColors("dark");
|
|
5424
|
+
var STATUS_SUCCESS3 = t4["status-success"];
|
|
5425
|
+
var STATUS_WARNING3 = t4["status-warning"];
|
|
5426
|
+
var STATUS_INFO = t4["status-info"];
|
|
5520
5427
|
var DOT_BORDER = "#F3F4F6";
|
|
5521
5428
|
var BAND_FILL = "rgba(46,213,115,0.1)";
|
|
5522
5429
|
var BAND_EDGE = "rgba(46,213,115,0.45)";
|
|
@@ -5559,8 +5466,8 @@ function interpEdge(pixels, x, key) {
|
|
|
5559
5466
|
const a = pixels[i];
|
|
5560
5467
|
const b = pixels[i + 1];
|
|
5561
5468
|
if (x >= a.x && x <= b.x) {
|
|
5562
|
-
const
|
|
5563
|
-
return a[key] +
|
|
5469
|
+
const t7 = b.x === a.x ? 0 : (x - a.x) / (b.x - a.x);
|
|
5470
|
+
return a[key] + t7 * (b[key] - a[key]);
|
|
5564
5471
|
}
|
|
5565
5472
|
}
|
|
5566
5473
|
return pixels[pixels.length - 1][key];
|
|
@@ -5746,18 +5653,53 @@ function CapacityBandChart({
|
|
|
5746
5653
|
/* @__PURE__ */ jsx(
|
|
5747
5654
|
reactNative.Animated.View,
|
|
5748
5655
|
{
|
|
5749
|
-
style: {
|
|
5656
|
+
style: {
|
|
5657
|
+
position: "absolute",
|
|
5658
|
+
top: 0,
|
|
5659
|
+
left: 0,
|
|
5660
|
+
height,
|
|
5661
|
+
width: revealWidth,
|
|
5662
|
+
overflow: "hidden"
|
|
5663
|
+
},
|
|
5750
5664
|
accessibilityElementsHidden: true,
|
|
5751
5665
|
importantForAccessibility: "no-hide-descendants",
|
|
5752
5666
|
testID: "capacity-band-chart-reveal",
|
|
5753
5667
|
children: /* @__PURE__ */ jsxs(reactNative.View, { style: { width, height, position: "relative" }, children: [
|
|
5754
5668
|
projection && /* @__PURE__ */ jsxs(reactNative.View, { testID: "capacity-band-chart-projection", children: [
|
|
5755
|
-
renderColumns(
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5669
|
+
renderColumns(
|
|
5670
|
+
buildColumns2(trainingPixels, COLUMN_STEP),
|
|
5671
|
+
PROJECTION_FILL,
|
|
5672
|
+
"capacity-band-chart-projection-fill"
|
|
5673
|
+
),
|
|
5674
|
+
renderColumns(
|
|
5675
|
+
buildColumns2(restPixels, COLUMN_STEP),
|
|
5676
|
+
PROJECTION_FILL,
|
|
5677
|
+
"capacity-band-chart-projection-fill"
|
|
5678
|
+
),
|
|
5679
|
+
renderEdges(
|
|
5680
|
+
buildEdges(trainingPixels, "yHigh"),
|
|
5681
|
+
STATUS_SUCCESS3,
|
|
5682
|
+
true,
|
|
5683
|
+
"capacity-band-chart-projection-training"
|
|
5684
|
+
),
|
|
5685
|
+
renderEdges(
|
|
5686
|
+
buildEdges(trainingPixels, "yLow"),
|
|
5687
|
+
STATUS_SUCCESS3,
|
|
5688
|
+
true,
|
|
5689
|
+
"capacity-band-chart-projection-training"
|
|
5690
|
+
),
|
|
5691
|
+
renderEdges(
|
|
5692
|
+
buildEdges(restPixels, "yHigh"),
|
|
5693
|
+
STATUS_INFO,
|
|
5694
|
+
true,
|
|
5695
|
+
"capacity-band-chart-projection-rest"
|
|
5696
|
+
),
|
|
5697
|
+
renderEdges(
|
|
5698
|
+
buildEdges(restPixels, "yLow"),
|
|
5699
|
+
STATUS_INFO,
|
|
5700
|
+
true,
|
|
5701
|
+
"capacity-band-chart-projection-rest"
|
|
5702
|
+
),
|
|
5761
5703
|
/* @__PURE__ */ jsx(
|
|
5762
5704
|
reactNative.Text,
|
|
5763
5705
|
{
|
|
@@ -5892,7 +5834,7 @@ function CapacityBandChart({
|
|
|
5892
5834
|
}
|
|
5893
5835
|
|
|
5894
5836
|
// src/components/custom/Workout/ExerciseDetailPage.tsx
|
|
5895
|
-
var
|
|
5837
|
+
var BRAND_PRIMARY6 = getSemanticColors("dark")["brand-primary"];
|
|
5896
5838
|
var CHART_WIDTH = 326;
|
|
5897
5839
|
var CHART_HEIGHT = 150;
|
|
5898
5840
|
var EXERCISE_DETAIL_TABS = [
|
|
@@ -5955,7 +5897,7 @@ function TabBar({ active, onSelect }) {
|
|
|
5955
5897
|
alignItems: "center",
|
|
5956
5898
|
paddingVertical: 10,
|
|
5957
5899
|
borderBottomWidth: 2,
|
|
5958
|
-
borderBottomColor: isActive ?
|
|
5900
|
+
borderBottomColor: isActive ? BRAND_PRIMARY6 : "transparent"
|
|
5959
5901
|
},
|
|
5960
5902
|
testID: `exercise-detail-page-tab-${key}`,
|
|
5961
5903
|
children: /* @__PURE__ */ jsx(
|
|
@@ -6286,7 +6228,7 @@ function ExerciseDetailPage({
|
|
|
6286
6228
|
fontSize: 15,
|
|
6287
6229
|
fontFamily: '"Space Grotesk", sans-serif',
|
|
6288
6230
|
fontWeight: "700",
|
|
6289
|
-
color:
|
|
6231
|
+
color: BRAND_PRIMARY6
|
|
6290
6232
|
},
|
|
6291
6233
|
children: `${exercise.currentE1rm} ${exercise.unit}`
|
|
6292
6234
|
}
|
|
@@ -6352,11 +6294,10 @@ function ExerciseDetailPage({
|
|
|
6352
6294
|
}
|
|
6353
6295
|
);
|
|
6354
6296
|
}
|
|
6355
|
-
var
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
upcoming: "rgba(255,255,255,0.06)"
|
|
6297
|
+
var segmentTrackToken = {
|
|
6298
|
+
completed: "status-success-muted",
|
|
6299
|
+
current: "brand-primary-strong",
|
|
6300
|
+
upcoming: "hairline-subtle"
|
|
6360
6301
|
};
|
|
6361
6302
|
function clampProgress(currentWeek, weekCount) {
|
|
6362
6303
|
if (currentWeek == null || weekCount <= 0) return 0;
|
|
@@ -6365,6 +6306,7 @@ function clampProgress(currentWeek, weekCount) {
|
|
|
6365
6306
|
}
|
|
6366
6307
|
function MesoSegment({ meso, isActive, onPress }) {
|
|
6367
6308
|
const [pressScale] = react.useState(() => new reactNative.Animated.Value(1));
|
|
6309
|
+
const brandPrimary = resolveColor("brand-primary");
|
|
6368
6310
|
const handlePressIn = () => {
|
|
6369
6311
|
reactNative.Animated.timing(pressScale, {
|
|
6370
6312
|
toValue: 0.98,
|
|
@@ -6399,12 +6341,12 @@ function MesoSegment({ meso, isActive, onPress }) {
|
|
|
6399
6341
|
height: 8,
|
|
6400
6342
|
borderRadius: 4,
|
|
6401
6343
|
overflow: "hidden",
|
|
6402
|
-
backgroundColor:
|
|
6344
|
+
backgroundColor: resolveColor(segmentTrackToken[meso.status]),
|
|
6403
6345
|
transform: [{ scale: pressScale }]
|
|
6404
6346
|
},
|
|
6405
6347
|
isActive ? {
|
|
6406
6348
|
borderWidth: 2,
|
|
6407
|
-
borderColor:
|
|
6349
|
+
borderColor: brandPrimary,
|
|
6408
6350
|
transform: [{ scale: 1.02 }, { scale: pressScale }]
|
|
6409
6351
|
} : void 0
|
|
6410
6352
|
],
|
|
@@ -6418,7 +6360,7 @@ function MesoSegment({ meso, isActive, onPress }) {
|
|
|
6418
6360
|
top: 0,
|
|
6419
6361
|
bottom: 0,
|
|
6420
6362
|
width: `${progress * 100}%`,
|
|
6421
|
-
backgroundColor:
|
|
6363
|
+
backgroundColor: brandPrimary
|
|
6422
6364
|
},
|
|
6423
6365
|
testID: `meso-segment-fill-${meso.id}`
|
|
6424
6366
|
}
|
|
@@ -6465,7 +6407,7 @@ var sizeStyles = {
|
|
|
6465
6407
|
md: "w-2 h-2",
|
|
6466
6408
|
lg: "w-2.5 h-2.5"
|
|
6467
6409
|
};
|
|
6468
|
-
var
|
|
6410
|
+
var colorStyles2 = {
|
|
6469
6411
|
default: "bg-text-tertiary",
|
|
6470
6412
|
primary: "bg-brand-primary",
|
|
6471
6413
|
success: "bg-status-success",
|
|
@@ -6475,6 +6417,17 @@ var colorStyles = {
|
|
|
6475
6417
|
info: "bg-status-info",
|
|
6476
6418
|
"error-vivid": "bg-status-error-vivid"
|
|
6477
6419
|
};
|
|
6420
|
+
var t5 = getSemanticColors("dark");
|
|
6421
|
+
var glowColors2 = {
|
|
6422
|
+
default: greyRamp[500],
|
|
6423
|
+
primary: t5["brand-primary"],
|
|
6424
|
+
success: t5["status-success"],
|
|
6425
|
+
live: t5["status-live"],
|
|
6426
|
+
error: t5["status-error"],
|
|
6427
|
+
warning: t5["status-warning"],
|
|
6428
|
+
info: t5["status-info"],
|
|
6429
|
+
"error-vivid": t5["status-error-vivid"]
|
|
6430
|
+
};
|
|
6478
6431
|
function Indicator({
|
|
6479
6432
|
size = "sm",
|
|
6480
6433
|
color = "default",
|
|
@@ -6487,7 +6440,7 @@ function Indicator({
|
|
|
6487
6440
|
...props
|
|
6488
6441
|
}) {
|
|
6489
6442
|
const pulseMode = pulse === true ? "opacity" : pulse || false;
|
|
6490
|
-
const colorClass = !customColor ?
|
|
6443
|
+
const colorClass = !customColor ? colorStyles2[color] : void 0;
|
|
6491
6444
|
const colorStyle = customColor ? { backgroundColor: customColor } : void 0;
|
|
6492
6445
|
if (pulseMode === "ping") {
|
|
6493
6446
|
return /* @__PURE__ */ jsxs(reactNative.View, { className: cn("relative", sizeStyles[size], className), style, ...props, children: [
|
|
@@ -6512,11 +6465,7 @@ function Indicator({
|
|
|
6512
6465
|
)
|
|
6513
6466
|
] });
|
|
6514
6467
|
}
|
|
6515
|
-
const
|
|
6516
|
-
...typeof style === "object" ? style : {},
|
|
6517
|
-
...colorStyle ?? {},
|
|
6518
|
-
...glow && customColor ? { boxShadow: `0 0 6px ${customColor}` } : {}
|
|
6519
|
-
};
|
|
6468
|
+
const glowStyle = glow ? getGlowShadow(customColor ?? glowColors2[color], "subtle") : null;
|
|
6520
6469
|
return /* @__PURE__ */ jsx(
|
|
6521
6470
|
reactNative.View,
|
|
6522
6471
|
{
|
|
@@ -6526,54 +6475,165 @@ function Indicator({
|
|
|
6526
6475
|
colorClass,
|
|
6527
6476
|
pulseMode === "opacity" && "animate-pulse",
|
|
6528
6477
|
ring && "border-2 border-background-base",
|
|
6529
|
-
glow && !customColor && (color === "success" || color === "live") && "shadow-[0_0_6px_rgba(46,213,115,0.6)]",
|
|
6530
|
-
glow && !customColor && color === "error" && "shadow-[0_0_6px_rgba(239,68,68,0.6)]",
|
|
6531
|
-
glow && !customColor && color === "warning" && "shadow-[0_0_6px_rgba(245,158,11,0.6)]",
|
|
6532
|
-
glow && !customColor && color === "primary" && "shadow-[0_0_6px_rgba(255,121,0,0.6)]",
|
|
6533
|
-
glow && !customColor && color === "error-vivid" && "shadow-[0_0_6px_rgba(255,71,87,0.6)]",
|
|
6534
6478
|
className
|
|
6535
6479
|
),
|
|
6536
|
-
style:
|
|
6480
|
+
style: [style, colorStyle, glowStyle],
|
|
6537
6481
|
...props
|
|
6538
6482
|
}
|
|
6539
6483
|
);
|
|
6540
6484
|
}
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6485
|
+
var colorToTone = {
|
|
6486
|
+
default: "neutral",
|
|
6487
|
+
primary: "brand",
|
|
6488
|
+
secondary: "brand-secondary",
|
|
6489
|
+
success: "success",
|
|
6490
|
+
error: "error",
|
|
6491
|
+
warning: "warning",
|
|
6492
|
+
info: "info"
|
|
6493
|
+
};
|
|
6494
|
+
var toneStyles = {
|
|
6544
6495
|
solid: {
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
secondary: "bg-brand-secondary text-text-inverse",
|
|
6548
|
-
success: "bg-status-success text-text-inverse",
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
info: "bg-status-info text-text-inverse"
|
|
6496
|
+
neutral: "bg-hairline-strong border-transparent text-text-inverse",
|
|
6497
|
+
brand: "bg-brand-primary border-transparent text-text-inverse",
|
|
6498
|
+
"brand-secondary": "bg-brand-secondary border-transparent text-text-inverse",
|
|
6499
|
+
success: "bg-status-success border-transparent text-text-inverse",
|
|
6500
|
+
warning: "bg-status-warning border-transparent text-text-inverse",
|
|
6501
|
+
error: "bg-status-error border-transparent text-text-inverse",
|
|
6502
|
+
info: "bg-status-info border-transparent text-text-inverse"
|
|
6552
6503
|
},
|
|
6553
6504
|
subtle: {
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6505
|
+
// Alpha-white rather than a ramp step: a pill sits on whatever plane its
|
|
6506
|
+
// host is, and an alpha fill composites by the same amount on all of them.
|
|
6507
|
+
// A `surface-*` fill would vanish on the plane it names. Borderless like the
|
|
6508
|
+
// six coloured tones — the fill carries the capsule, not a ring.
|
|
6509
|
+
neutral: "bg-hairline-subtle border-transparent text-text-secondary",
|
|
6510
|
+
brand: "bg-brand-primary-subtle border-transparent text-brand-primary",
|
|
6511
|
+
"brand-secondary": "bg-brand-secondary-subtle border-transparent text-brand-secondary",
|
|
6512
|
+
success: "bg-status-success-subtle border-transparent text-status-success",
|
|
6513
|
+
warning: "bg-status-warning-subtle border-transparent text-status-warning",
|
|
6514
|
+
error: "bg-status-error-subtle border-transparent text-status-error",
|
|
6515
|
+
info: "bg-status-info-subtle border-transparent text-status-info"
|
|
6561
6516
|
},
|
|
6562
6517
|
outline: {
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
secondary: "border
|
|
6566
|
-
success: "border
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
info: "border
|
|
6518
|
+
neutral: "border-hairline text-text-secondary",
|
|
6519
|
+
brand: "border-brand-primary text-brand-primary",
|
|
6520
|
+
"brand-secondary": "border-brand-secondary text-brand-secondary",
|
|
6521
|
+
success: "border-status-success text-status-success",
|
|
6522
|
+
warning: "border-status-warning text-status-warning",
|
|
6523
|
+
error: "border-status-error text-status-error",
|
|
6524
|
+
info: "border-status-info text-status-info"
|
|
6570
6525
|
}
|
|
6571
6526
|
};
|
|
6527
|
+
var dotToneStyles = {
|
|
6528
|
+
neutral: "bg-text-tertiary",
|
|
6529
|
+
brand: "bg-brand-primary",
|
|
6530
|
+
"brand-secondary": "bg-brand-secondary",
|
|
6531
|
+
success: "bg-status-success",
|
|
6532
|
+
warning: "bg-status-warning",
|
|
6533
|
+
error: "bg-status-error",
|
|
6534
|
+
info: "bg-status-info"
|
|
6535
|
+
};
|
|
6572
6536
|
var sizeStyles2 = {
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6537
|
+
xs: { container: "px-1 py-px", text: "text-3xs" },
|
|
6538
|
+
sm: { container: "px-2 py-0.5", text: "text-2xs" },
|
|
6539
|
+
md: { container: "px-2.5 py-1", text: "text-xs" },
|
|
6540
|
+
lg: { container: "px-3 py-1.5", text: "text-sm" },
|
|
6541
|
+
xl: { container: "px-4 py-2", text: "text-base" }
|
|
6542
|
+
};
|
|
6543
|
+
function PillDot({ tone, testID }) {
|
|
6544
|
+
return /* @__PURE__ */ jsx(
|
|
6545
|
+
reactNative.View,
|
|
6546
|
+
{
|
|
6547
|
+
className: cn("w-1.5 h-1.5 rounded-full shrink-0", dotToneStyles[tone]),
|
|
6548
|
+
accessibilityElementsHidden: true,
|
|
6549
|
+
testID: testID ? `${testID}-dot` : "pill-dot"
|
|
6550
|
+
}
|
|
6551
|
+
);
|
|
6552
|
+
}
|
|
6553
|
+
function containerClasses(p, tone) {
|
|
6554
|
+
return cn(
|
|
6555
|
+
"flex-row items-center gap-1 border self-start shrink-0",
|
|
6556
|
+
p.rounded === false ? "rounded" : "rounded-full",
|
|
6557
|
+
toneStyles[p.variant ?? "subtle"][tone],
|
|
6558
|
+
sizeStyles2[p.size ?? "sm"].container,
|
|
6559
|
+
p.isDisabled && "opacity-50",
|
|
6560
|
+
p.className
|
|
6561
|
+
);
|
|
6562
|
+
}
|
|
6563
|
+
function PillContent({ tone, ...p }) {
|
|
6564
|
+
const textClasses = cn(
|
|
6565
|
+
"font-heading font-semibold text-inherit",
|
|
6566
|
+
sizeStyles2[p.size ?? "sm"].text,
|
|
6567
|
+
p.textClassName
|
|
6568
|
+
);
|
|
6569
|
+
const slot = p.leading ?? p.leftElement;
|
|
6570
|
+
return /* @__PURE__ */ jsxs(jsxRuntime.Fragment, { children: [
|
|
6571
|
+
slot === "dot" ? /* @__PURE__ */ jsx(PillDot, { tone: p.dotTone ?? tone, testID: p.testID }) : slot,
|
|
6572
|
+
typeof p.children === "string" ? /* @__PURE__ */ jsx(reactNative.Text, { className: textClasses, children: p.children }) : p.children,
|
|
6573
|
+
p.trailing
|
|
6574
|
+
] });
|
|
6575
|
+
}
|
|
6576
|
+
function Pill(props) {
|
|
6577
|
+
const {
|
|
6578
|
+
variant,
|
|
6579
|
+
tone,
|
|
6580
|
+
color,
|
|
6581
|
+
size,
|
|
6582
|
+
rounded,
|
|
6583
|
+
leading,
|
|
6584
|
+
dotTone: dotTone2,
|
|
6585
|
+
leftElement,
|
|
6586
|
+
trailing,
|
|
6587
|
+
onPress,
|
|
6588
|
+
isDisabled,
|
|
6589
|
+
className,
|
|
6590
|
+
textClassName,
|
|
6591
|
+
children,
|
|
6592
|
+
...viewProps
|
|
6593
|
+
} = props;
|
|
6594
|
+
const resolvedTone = tone ?? (color ? colorToTone[color] : "neutral");
|
|
6595
|
+
const classes = containerClasses(props, resolvedTone);
|
|
6596
|
+
const content = /* @__PURE__ */ jsx(PillContent, { ...props, tone: resolvedTone });
|
|
6597
|
+
if (onPress) {
|
|
6598
|
+
return /* @__PURE__ */ jsx(
|
|
6599
|
+
reactNative.Pressable,
|
|
6600
|
+
{
|
|
6601
|
+
onPress,
|
|
6602
|
+
disabled: isDisabled,
|
|
6603
|
+
accessibilityRole: "button",
|
|
6604
|
+
className: classes,
|
|
6605
|
+
...viewProps,
|
|
6606
|
+
children: content
|
|
6607
|
+
}
|
|
6608
|
+
);
|
|
6609
|
+
}
|
|
6610
|
+
return /* @__PURE__ */ jsx(reactNative.View, { className: classes, ...viewProps, children: content });
|
|
6611
|
+
}
|
|
6612
|
+
|
|
6613
|
+
// src/components/ui/badge/Badge.tsx
|
|
6614
|
+
var colorToTone2 = {
|
|
6615
|
+
default: "neutral",
|
|
6616
|
+
primary: "brand",
|
|
6617
|
+
secondary: "brand-secondary",
|
|
6618
|
+
success: "success",
|
|
6619
|
+
error: "error",
|
|
6620
|
+
warning: "warning",
|
|
6621
|
+
info: "info"
|
|
6576
6622
|
};
|
|
6623
|
+
var sizeStyles3 = {
|
|
6624
|
+
sm: "px-1.5 py-0.5",
|
|
6625
|
+
md: "px-2 py-0.5",
|
|
6626
|
+
lg: "px-2.5 py-1"
|
|
6627
|
+
};
|
|
6628
|
+
var textSizeStyles = {
|
|
6629
|
+
sm: "text-xs",
|
|
6630
|
+
md: "text-xs",
|
|
6631
|
+
lg: "text-sm"
|
|
6632
|
+
};
|
|
6633
|
+
function dotIndicatorColor(color, dotColor) {
|
|
6634
|
+
if (dotColor) return dotColor;
|
|
6635
|
+
return color === "default" || color === "secondary" ? "default" : color;
|
|
6636
|
+
}
|
|
6577
6637
|
function Badge({
|
|
6578
6638
|
variant = "subtle",
|
|
6579
6639
|
color = "default",
|
|
@@ -6584,56 +6644,62 @@ function Badge({
|
|
|
6584
6644
|
children,
|
|
6585
6645
|
...props
|
|
6586
6646
|
}) {
|
|
6587
|
-
return /* @__PURE__ */
|
|
6588
|
-
|
|
6647
|
+
return /* @__PURE__ */ jsx(
|
|
6648
|
+
Pill,
|
|
6589
6649
|
{
|
|
6650
|
+
variant,
|
|
6651
|
+
tone: colorToTone2[color],
|
|
6652
|
+
leading: dot ? /* @__PURE__ */ jsx(Indicator, { size: "xs", color: dotIndicatorColor(color, dotColor), className: "mr-0.5" }) : void 0,
|
|
6590
6653
|
className: cn(
|
|
6591
|
-
"
|
|
6592
|
-
|
|
6593
|
-
|
|
6654
|
+
"justify-center self-auto gap-0",
|
|
6655
|
+
variant === "outline" ? "border" : "border-0",
|
|
6656
|
+
sizeStyles3[size],
|
|
6594
6657
|
className
|
|
6595
6658
|
),
|
|
6659
|
+
textClassName: cn("font-sans font-medium", textSizeStyles[size]),
|
|
6596
6660
|
...props,
|
|
6597
|
-
children
|
|
6598
|
-
dot && /* @__PURE__ */ jsx(
|
|
6599
|
-
Indicator,
|
|
6600
|
-
{
|
|
6601
|
-
size: "xs",
|
|
6602
|
-
color: dotColor ?? (color === "default" || color === "secondary" ? "default" : color),
|
|
6603
|
-
className: "mr-0.5"
|
|
6604
|
-
}
|
|
6605
|
-
),
|
|
6606
|
-
typeof children === "string" ? /* @__PURE__ */ jsx(reactNative.Text, { className: "text-inherit font-medium", children }) : children
|
|
6607
|
-
]
|
|
6661
|
+
children
|
|
6608
6662
|
}
|
|
6609
6663
|
);
|
|
6610
6664
|
}
|
|
6611
|
-
var
|
|
6612
|
-
var
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
};
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6665
|
+
var DELOAD_WASH = alpha(WORKOUT_PILL_DELOAD, 0.12);
|
|
6666
|
+
var DELOAD_RIM = alpha(WORKOUT_PILL_DELOAD, 0.3);
|
|
6667
|
+
function paintFor(status) {
|
|
6668
|
+
switch (status) {
|
|
6669
|
+
case "completed":
|
|
6670
|
+
return {
|
|
6671
|
+
background: resolveColor("status-success-subtle"),
|
|
6672
|
+
border: resolveColor("status-success-muted"),
|
|
6673
|
+
text: resolveColor("status-success")
|
|
6674
|
+
};
|
|
6675
|
+
case "current":
|
|
6676
|
+
return {
|
|
6677
|
+
background: resolveColor("brand-primary-subtle"),
|
|
6678
|
+
border: resolveColor("brand-primary-muted"),
|
|
6679
|
+
text: resolveColor("brand-primary")
|
|
6680
|
+
};
|
|
6681
|
+
case "next":
|
|
6682
|
+
return {
|
|
6683
|
+
background: "transparent",
|
|
6684
|
+
border: resolveColor("brand-primary-strong"),
|
|
6685
|
+
text: resolveColor("brand-primary")
|
|
6686
|
+
};
|
|
6687
|
+
case "upcoming":
|
|
6688
|
+
return {
|
|
6689
|
+
background: resolveColor("surface-raised"),
|
|
6690
|
+
border: resolveColor("hairline-default"),
|
|
6691
|
+
text: resolveColor("text-tertiary")
|
|
6692
|
+
};
|
|
6693
|
+
case "missed":
|
|
6694
|
+
return {
|
|
6695
|
+
background: resolveColor("status-error-subtle"),
|
|
6696
|
+
border: resolveColor("status-error-muted"),
|
|
6697
|
+
text: resolveColor("status-error-dark")
|
|
6698
|
+
};
|
|
6699
|
+
case "deload":
|
|
6700
|
+
return { background: DELOAD_WASH, border: DELOAD_RIM, text: WORKOUT_PILL_DELOAD };
|
|
6701
|
+
}
|
|
6702
|
+
}
|
|
6637
6703
|
function usePulse2(enabled) {
|
|
6638
6704
|
const [opacity] = react.useState(() => new reactNative.Animated.Value(1));
|
|
6639
6705
|
react.useEffect(() => {
|
|
@@ -6675,6 +6741,8 @@ function WorkoutPill({
|
|
|
6675
6741
|
const pulseOpacity = usePulse2(shouldPulse);
|
|
6676
6742
|
const isCompleted = status === "completed";
|
|
6677
6743
|
const isMissed = status === "missed";
|
|
6744
|
+
const paint = paintFor(status);
|
|
6745
|
+
const labelClass = "font-semibold leading-[normal]";
|
|
6678
6746
|
const pill = /* @__PURE__ */ jsx(
|
|
6679
6747
|
reactNative.Animated.View,
|
|
6680
6748
|
{
|
|
@@ -6691,53 +6759,46 @@ function WorkoutPill({
|
|
|
6691
6759
|
paddingHorizontal: 10,
|
|
6692
6760
|
paddingVertical: 4,
|
|
6693
6761
|
borderRadius: 6,
|
|
6694
|
-
backgroundColor:
|
|
6762
|
+
backgroundColor: paint.background,
|
|
6763
|
+
borderWidth: 1,
|
|
6764
|
+
borderColor: paint.border
|
|
6695
6765
|
},
|
|
6696
|
-
statusBorderStyles[status],
|
|
6697
6766
|
highlighted ? { borderWidth: 2, transform: [{ scale: 1.02 }] } : void 0
|
|
6698
6767
|
],
|
|
6699
6768
|
accessibilityLabel: onPress ? void 0 : `${name} workout, ${status}`,
|
|
6700
6769
|
...props,
|
|
6701
6770
|
children: [
|
|
6702
6771
|
isCompleted && /* @__PURE__ */ jsx(
|
|
6703
|
-
|
|
6772
|
+
Typography,
|
|
6704
6773
|
{
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
color: textColors[status],
|
|
6710
|
-
marginRight: 4
|
|
6711
|
-
},
|
|
6774
|
+
variant: "caption",
|
|
6775
|
+
color: "inherit",
|
|
6776
|
+
className: labelClass,
|
|
6777
|
+
style: { color: paint.text, marginRight: 4 },
|
|
6712
6778
|
accessibilityElementsHidden: true,
|
|
6713
6779
|
testID: "workout-pill-check",
|
|
6714
6780
|
children: "\u2713"
|
|
6715
6781
|
}
|
|
6716
6782
|
),
|
|
6717
6783
|
isMissed && /* @__PURE__ */ jsx(
|
|
6718
|
-
|
|
6784
|
+
Typography,
|
|
6719
6785
|
{
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
color: textColors[status],
|
|
6725
|
-
marginRight: 4
|
|
6726
|
-
},
|
|
6786
|
+
variant: "caption",
|
|
6787
|
+
color: "inherit",
|
|
6788
|
+
className: labelClass,
|
|
6789
|
+
style: { color: paint.text, marginRight: 4 },
|
|
6727
6790
|
accessibilityElementsHidden: true,
|
|
6728
6791
|
testID: "workout-pill-dash",
|
|
6729
6792
|
children: "\u2014"
|
|
6730
6793
|
}
|
|
6731
6794
|
),
|
|
6732
6795
|
/* @__PURE__ */ jsx(
|
|
6733
|
-
|
|
6796
|
+
Typography,
|
|
6734
6797
|
{
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
color: textColors[status]
|
|
6740
|
-
},
|
|
6798
|
+
variant: "caption",
|
|
6799
|
+
color: "inherit",
|
|
6800
|
+
className: labelClass,
|
|
6801
|
+
style: { color: paint.text },
|
|
6741
6802
|
accessibilityElementsHidden: onPress != null,
|
|
6742
6803
|
testID: "workout-pill-name",
|
|
6743
6804
|
children: name
|
|
@@ -6762,19 +6823,19 @@ function WorkoutPill({
|
|
|
6762
6823
|
}
|
|
6763
6824
|
return pill;
|
|
6764
6825
|
}
|
|
6765
|
-
var
|
|
6826
|
+
var t6 = getSemanticColors("dark");
|
|
6766
6827
|
var TRACK_BG = "#333333";
|
|
6767
6828
|
var LABEL_COLOR = "#6B7280";
|
|
6768
6829
|
var TARGET_LINE_COLOR = "rgba(33, 150, 243, 0.5)";
|
|
6769
|
-
var AT_TARGET_GLOW = "
|
|
6830
|
+
var AT_TARGET_GLOW = getGlowShadow(t6["status-info"], "subtle");
|
|
6770
6831
|
var ZONE = {
|
|
6771
|
-
building:
|
|
6832
|
+
building: t6["status-success"],
|
|
6772
6833
|
// below target ramp-up
|
|
6773
|
-
approaching:
|
|
6834
|
+
approaching: t6["status-warning"],
|
|
6774
6835
|
// nearing target
|
|
6775
|
-
target:
|
|
6836
|
+
target: t6["brand-primary"],
|
|
6776
6837
|
// exactly at target
|
|
6777
|
-
over1:
|
|
6838
|
+
over1: t6["status-error"],
|
|
6778
6839
|
// mild over-target
|
|
6779
6840
|
over2: WORKOUT_TOKENS.intensity.over2,
|
|
6780
6841
|
// moderate over-target
|
|
@@ -6889,7 +6950,7 @@ function IntensityBar({
|
|
|
6889
6950
|
borderRadius: 3,
|
|
6890
6951
|
backgroundColor: zone.color,
|
|
6891
6952
|
zIndex: 2,
|
|
6892
|
-
...atTarget ?
|
|
6953
|
+
...atTarget ? AT_TARGET_GLOW : null
|
|
6893
6954
|
},
|
|
6894
6955
|
testID: "intensity-fill"
|
|
6895
6956
|
}
|
|
@@ -6937,7 +6998,7 @@ function IntensityBar({
|
|
|
6937
6998
|
}
|
|
6938
6999
|
|
|
6939
7000
|
// src/components/custom/Workout/WeekRow.tsx
|
|
6940
|
-
var
|
|
7001
|
+
var DELOAD_ROW_WASH = alpha(WORKOUT_PILL_DELOAD, 0.06);
|
|
6941
7002
|
function WeekRow({
|
|
6942
7003
|
weekNumber,
|
|
6943
7004
|
totalWeeks,
|
|
@@ -6949,6 +7010,7 @@ function WeekRow({
|
|
|
6949
7010
|
className,
|
|
6950
7011
|
...props
|
|
6951
7012
|
}) {
|
|
7013
|
+
const brandPrimary = resolveColor("brand-primary");
|
|
6952
7014
|
const rowStyle = {
|
|
6953
7015
|
flexDirection: "row",
|
|
6954
7016
|
alignItems: "center",
|
|
@@ -6957,12 +7019,12 @@ function WeekRow({
|
|
|
6957
7019
|
gap: 12
|
|
6958
7020
|
};
|
|
6959
7021
|
if (isDeload) {
|
|
6960
|
-
rowStyle.backgroundColor =
|
|
7022
|
+
rowStyle.backgroundColor = DELOAD_ROW_WASH;
|
|
6961
7023
|
}
|
|
6962
7024
|
if (isCurrent) {
|
|
6963
|
-
rowStyle.backgroundColor = "
|
|
7025
|
+
rowStyle.backgroundColor = resolveColor("brand-primary-subtle");
|
|
6964
7026
|
rowStyle.borderLeftWidth = 2;
|
|
6965
|
-
rowStyle.borderLeftColor =
|
|
7027
|
+
rowStyle.borderLeftColor = brandPrimary;
|
|
6966
7028
|
}
|
|
6967
7029
|
return /* @__PURE__ */ jsxs(
|
|
6968
7030
|
reactNative.View,
|
|
@@ -6986,22 +7048,18 @@ function WeekRow({
|
|
|
6986
7048
|
width: 6,
|
|
6987
7049
|
height: 6,
|
|
6988
7050
|
borderRadius: 3,
|
|
6989
|
-
backgroundColor:
|
|
7051
|
+
backgroundColor: brandPrimary
|
|
6990
7052
|
},
|
|
6991
7053
|
accessibilityElementsHidden: true,
|
|
6992
7054
|
testID: "week-row-current-dot"
|
|
6993
7055
|
}
|
|
6994
7056
|
),
|
|
6995
7057
|
/* @__PURE__ */ jsx(
|
|
6996
|
-
|
|
7058
|
+
Typography,
|
|
6997
7059
|
{
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
fontWeight: "700",
|
|
7002
|
-
fontFamily: "Inter, sans-serif",
|
|
7003
|
-
color: isCurrent ? BRAND_PRIMARY9 : void 0
|
|
7004
|
-
},
|
|
7060
|
+
variant: "boldLabel",
|
|
7061
|
+
color: isCurrent ? "inherit" : "primary",
|
|
7062
|
+
className: isCurrent ? "text-brand-primary" : void 0,
|
|
7005
7063
|
accessibilityElementsHidden: true,
|
|
7006
7064
|
children: `W${weekNumber}`
|
|
7007
7065
|
}
|
|
@@ -7041,12 +7099,12 @@ function WeekRow({
|
|
|
7041
7099
|
}
|
|
7042
7100
|
|
|
7043
7101
|
// src/components/custom/Workout/MesoCard.tsx
|
|
7044
|
-
var
|
|
7045
|
-
var
|
|
7102
|
+
var HAIRLINE_DEFAULT = getSemanticColors("dark")["hairline-default"];
|
|
7103
|
+
var BRAND_PRIMARY7 = getSemanticColors("dark")["brand-primary"];
|
|
7046
7104
|
var BRAND_PRIMARY_DARK2 = MESO_ACCENT_GRADIENT_DARK;
|
|
7047
7105
|
var BRAND_PRIMARY_LIGHT2 = MESO_ACCENT_GRADIENT_LIGHT;
|
|
7048
|
-
var BORDER_DEFAULT =
|
|
7049
|
-
var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2,
|
|
7106
|
+
var BORDER_DEFAULT = HAIRLINE_DEFAULT;
|
|
7107
|
+
var ACCENT_STOPS2 = [BRAND_PRIMARY_DARK2, BRAND_PRIMARY7, BRAND_PRIMARY_LIGHT2];
|
|
7050
7108
|
function heatmapColor(percentage) {
|
|
7051
7109
|
const clamped = Math.max(0, Math.min(100, percentage));
|
|
7052
7110
|
const opacity = 0.12 + clamped / 100 * 0.78;
|
|
@@ -7081,130 +7139,139 @@ function MesoCard({
|
|
|
7081
7139
|
}, [highlighted, highlight]);
|
|
7082
7140
|
const borderColor = highlight.interpolate({
|
|
7083
7141
|
inputRange: [0, 1],
|
|
7084
|
-
outputRange: [BORDER_DEFAULT,
|
|
7142
|
+
outputRange: [BORDER_DEFAULT, BRAND_PRIMARY7]
|
|
7085
7143
|
});
|
|
7086
|
-
const header = /* @__PURE__ */ jsxs(
|
|
7087
|
-
|
|
7088
|
-
/* @__PURE__ */ jsx(
|
|
7089
|
-
reactNative.Text,
|
|
7090
|
-
{
|
|
7091
|
-
className: "text-text-primary",
|
|
7092
|
-
style: {
|
|
7093
|
-
fontSize: 15,
|
|
7094
|
-
fontFamily: '"Space Grotesk", sans-serif',
|
|
7095
|
-
fontWeight: "700"
|
|
7096
|
-
},
|
|
7097
|
-
testID: "meso-card-name",
|
|
7098
|
-
children: name
|
|
7099
|
-
}
|
|
7100
|
-
),
|
|
7101
|
-
/* @__PURE__ */ jsx(Badge, { variant: "subtle", color: "primary", size: "sm", testID: "meso-card-goal-badge", children: goal })
|
|
7102
|
-
] }),
|
|
7103
|
-
/* @__PURE__ */ jsx(
|
|
7104
|
-
reactNative.Text,
|
|
7105
|
-
{
|
|
7106
|
-
className: "text-text-secondary",
|
|
7107
|
-
style: {
|
|
7108
|
-
marginTop: 4,
|
|
7109
|
-
fontSize: 12,
|
|
7110
|
-
fontFamily: "Inter, sans-serif"
|
|
7111
|
-
},
|
|
7112
|
-
testID: "meso-card-subheader",
|
|
7113
|
-
children: `${split} \xB7 ${weekRange}`
|
|
7114
|
-
}
|
|
7115
|
-
),
|
|
7116
|
-
volumeHeatmap && volumeHeatmap.length > 0 && /* @__PURE__ */ jsx(
|
|
7117
|
-
reactNative.View,
|
|
7118
|
-
{
|
|
7119
|
-
className: "flex-row items-center",
|
|
7120
|
-
style: { marginTop: 10, gap: 3 },
|
|
7121
|
-
accessibilityElementsHidden: true,
|
|
7122
|
-
testID: "meso-card-heatmap",
|
|
7123
|
-
children: volumeHeatmap.map((entry) => /* @__PURE__ */ jsx(
|
|
7124
|
-
reactNative.View,
|
|
7125
|
-
{
|
|
7126
|
-
style: {
|
|
7127
|
-
flex: 1,
|
|
7128
|
-
height: 8,
|
|
7129
|
-
borderRadius: 2,
|
|
7130
|
-
backgroundColor: heatmapColor(entry.percentage)
|
|
7131
|
-
},
|
|
7132
|
-
testID: "meso-card-heatmap-cell"
|
|
7133
|
-
},
|
|
7134
|
-
entry.group
|
|
7135
|
-
))
|
|
7136
|
-
}
|
|
7137
|
-
)
|
|
7138
|
-
] });
|
|
7139
|
-
return /* @__PURE__ */ jsx(reactNative.Animated.View, { style: highlighted ? { transform: [{ scale: 1 }] } : void 0, testID: "meso-card-wrapper", children: /* @__PURE__ */ jsxs(
|
|
7140
|
-
Card,
|
|
7144
|
+
const header = /* @__PURE__ */ jsxs(
|
|
7145
|
+
reactNative.View,
|
|
7141
7146
|
{
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
borderColor: highlighted ? BRAND_PRIMARY10 : BORDER_DEFAULT,
|
|
7145
|
-
className,
|
|
7146
|
-
style: [
|
|
7147
|
-
{ borderColor },
|
|
7148
|
-
highlighted ? { boxShadow: "0 0 12px 2px rgba(255,121,0,0.25)" } : void 0
|
|
7149
|
-
],
|
|
7150
|
-
testID: "meso-card",
|
|
7151
|
-
...props,
|
|
7147
|
+
style: { paddingHorizontal: 14, paddingTop: 12, paddingBottom: 10 },
|
|
7148
|
+
testID: "meso-card-body",
|
|
7152
7149
|
children: [
|
|
7150
|
+
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", style: { gap: 8 }, testID: "meso-card-header", children: [
|
|
7151
|
+
/* @__PURE__ */ jsx(
|
|
7152
|
+
reactNative.Text,
|
|
7153
|
+
{
|
|
7154
|
+
className: "text-text-primary",
|
|
7155
|
+
style: {
|
|
7156
|
+
fontSize: 15,
|
|
7157
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
7158
|
+
fontWeight: "700"
|
|
7159
|
+
},
|
|
7160
|
+
testID: "meso-card-name",
|
|
7161
|
+
children: name
|
|
7162
|
+
}
|
|
7163
|
+
),
|
|
7164
|
+
/* @__PURE__ */ jsx(Badge, { variant: "subtle", color: "primary", size: "sm", testID: "meso-card-goal-badge", children: goal })
|
|
7165
|
+
] }),
|
|
7153
7166
|
/* @__PURE__ */ jsx(
|
|
7154
|
-
reactNative.
|
|
7155
|
-
{
|
|
7156
|
-
className: "flex-row",
|
|
7157
|
-
style: { position: "absolute", top: 0, left: 0, right: 0, height: 3, zIndex: 1 },
|
|
7158
|
-
accessibilityElementsHidden: true,
|
|
7159
|
-
testID: "meso-card-accent",
|
|
7160
|
-
children: ACCENT_STOPS2.map((color) => /* @__PURE__ */ jsx(reactNative.View, { style: { flex: 1, backgroundColor: color } }, color))
|
|
7161
|
-
}
|
|
7162
|
-
),
|
|
7163
|
-
isExpandable ? /* @__PURE__ */ jsx(
|
|
7164
|
-
reactNative.Pressable,
|
|
7165
|
-
{
|
|
7166
|
-
onPress: onToggle,
|
|
7167
|
-
accessibilityRole: "button",
|
|
7168
|
-
accessibilityLabel: `${name}, ${goal}, ${weekRange}`,
|
|
7169
|
-
"aria-expanded": expanded,
|
|
7170
|
-
testID: "meso-card-toggle",
|
|
7171
|
-
children: header
|
|
7172
|
-
}
|
|
7173
|
-
) : /* @__PURE__ */ jsx(
|
|
7174
|
-
reactNative.View,
|
|
7167
|
+
reactNative.Text,
|
|
7175
7168
|
{
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7169
|
+
className: "text-text-secondary",
|
|
7170
|
+
style: {
|
|
7171
|
+
marginTop: 4,
|
|
7172
|
+
fontSize: 12,
|
|
7173
|
+
fontFamily: "Inter, sans-serif"
|
|
7174
|
+
},
|
|
7175
|
+
testID: "meso-card-subheader",
|
|
7176
|
+
children: `${split} \xB7 ${weekRange}`
|
|
7179
7177
|
}
|
|
7180
7178
|
),
|
|
7181
|
-
|
|
7179
|
+
volumeHeatmap && volumeHeatmap.length > 0 && /* @__PURE__ */ jsx(
|
|
7182
7180
|
reactNative.View,
|
|
7183
7181
|
{
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7182
|
+
className: "flex-row items-center",
|
|
7183
|
+
style: { marginTop: 10, gap: 3 },
|
|
7184
|
+
accessibilityElementsHidden: true,
|
|
7185
|
+
testID: "meso-card-heatmap",
|
|
7186
|
+
children: volumeHeatmap.map((entry) => /* @__PURE__ */ jsx(
|
|
7187
|
+
reactNative.View,
|
|
7188
7188
|
{
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7189
|
+
style: {
|
|
7190
|
+
flex: 1,
|
|
7191
|
+
height: 8,
|
|
7192
|
+
borderRadius: 2,
|
|
7193
|
+
backgroundColor: heatmapColor(entry.percentage)
|
|
7194
|
+
},
|
|
7195
|
+
testID: "meso-card-heatmap-cell"
|
|
7192
7196
|
},
|
|
7193
|
-
|
|
7197
|
+
entry.group
|
|
7194
7198
|
))
|
|
7195
7199
|
}
|
|
7196
7200
|
)
|
|
7197
7201
|
]
|
|
7198
7202
|
}
|
|
7199
|
-
)
|
|
7203
|
+
);
|
|
7204
|
+
return /* @__PURE__ */ jsx(
|
|
7205
|
+
reactNative.Animated.View,
|
|
7206
|
+
{
|
|
7207
|
+
style: highlighted ? { transform: [{ scale: 1 }] } : void 0,
|
|
7208
|
+
testID: "meso-card-wrapper",
|
|
7209
|
+
children: /* @__PURE__ */ jsxs(
|
|
7210
|
+
Card,
|
|
7211
|
+
{
|
|
7212
|
+
variant: "outline",
|
|
7213
|
+
elevation: 2,
|
|
7214
|
+
borderColor: highlighted ? BRAND_PRIMARY7 : BORDER_DEFAULT,
|
|
7215
|
+
className,
|
|
7216
|
+
style: [
|
|
7217
|
+
{ borderColor },
|
|
7218
|
+
// Highlight is emphasis, not depth: a brand glow through the shared builder.
|
|
7219
|
+
highlighted ? getGlowShadow(BRAND_PRIMARY7, "subtle") : void 0
|
|
7220
|
+
],
|
|
7221
|
+
testID: "meso-card",
|
|
7222
|
+
...props,
|
|
7223
|
+
children: [
|
|
7224
|
+
/* @__PURE__ */ jsx(
|
|
7225
|
+
reactNative.View,
|
|
7226
|
+
{
|
|
7227
|
+
className: "flex-row",
|
|
7228
|
+
style: { position: "absolute", top: 0, left: 0, right: 0, height: 3, zIndex: 1 },
|
|
7229
|
+
accessibilityElementsHidden: true,
|
|
7230
|
+
testID: "meso-card-accent",
|
|
7231
|
+
children: ACCENT_STOPS2.map((color) => /* @__PURE__ */ jsx(reactNative.View, { style: { flex: 1, backgroundColor: color } }, color))
|
|
7232
|
+
}
|
|
7233
|
+
),
|
|
7234
|
+
isExpandable ? /* @__PURE__ */ jsx(
|
|
7235
|
+
reactNative.Pressable,
|
|
7236
|
+
{
|
|
7237
|
+
onPress: onToggle,
|
|
7238
|
+
accessibilityRole: "button",
|
|
7239
|
+
accessibilityLabel: `${name}, ${goal}, ${weekRange}`,
|
|
7240
|
+
"aria-expanded": expanded,
|
|
7241
|
+
testID: "meso-card-toggle",
|
|
7242
|
+
children: header
|
|
7243
|
+
}
|
|
7244
|
+
) : /* @__PURE__ */ jsx(reactNative.View, { accessibilityLabel: `${name}, ${goal}, ${weekRange}`, testID: "meso-card-static", children: header }),
|
|
7245
|
+
expanded && weeks.length > 0 && /* @__PURE__ */ jsx(
|
|
7246
|
+
reactNative.View,
|
|
7247
|
+
{
|
|
7248
|
+
style: { borderTopWidth: 1, borderTopColor: BORDER_DEFAULT },
|
|
7249
|
+
testID: "meso-card-weeks",
|
|
7250
|
+
children: weeks.map((week) => /* @__PURE__ */ jsx(
|
|
7251
|
+
WeekRow,
|
|
7252
|
+
{
|
|
7253
|
+
...week,
|
|
7254
|
+
totalWeeks: week.totalWeeks ?? totalWeeks,
|
|
7255
|
+
isCurrent: week.isCurrent ?? week.weekNumber === currentWeek
|
|
7256
|
+
},
|
|
7257
|
+
week.weekNumber
|
|
7258
|
+
))
|
|
7259
|
+
}
|
|
7260
|
+
)
|
|
7261
|
+
]
|
|
7262
|
+
}
|
|
7263
|
+
)
|
|
7264
|
+
}
|
|
7265
|
+
);
|
|
7200
7266
|
}
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7267
|
+
|
|
7268
|
+
// src/components/custom/Workout/MuscleGroupChip.tsx
|
|
7269
|
+
var dotTone = {
|
|
7270
|
+
untrained: "neutral",
|
|
7271
|
+
behind: "brand-secondary",
|
|
7272
|
+
ontrack: "success",
|
|
7273
|
+
target: "brand",
|
|
7274
|
+
over: "error"
|
|
7208
7275
|
};
|
|
7209
7276
|
function MuscleGroupChip({
|
|
7210
7277
|
name,
|
|
@@ -7213,83 +7280,31 @@ function MuscleGroupChip({
|
|
|
7213
7280
|
className,
|
|
7214
7281
|
...props
|
|
7215
7282
|
}) {
|
|
7216
|
-
const dotColor = volumeStatus ? dotColorMap[volumeStatus] : greyRamp[900];
|
|
7217
7283
|
const statusLabel = volumeStatus ?? "no status";
|
|
7218
|
-
|
|
7219
|
-
|
|
7284
|
+
return /* @__PURE__ */ jsx(
|
|
7285
|
+
Pill,
|
|
7220
7286
|
{
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
},
|
|
7230
|
-
|
|
7231
|
-
testID: "muscle-group-chip",
|
|
7287
|
+
tone: "neutral",
|
|
7288
|
+
dotTone: volumeStatus ? dotTone[volumeStatus] : "neutral",
|
|
7289
|
+
variant: "subtle",
|
|
7290
|
+
size: "md",
|
|
7291
|
+
leading: "dot",
|
|
7292
|
+
onPress,
|
|
7293
|
+
className: ["gap-1.5", className].filter(Boolean).join(" "),
|
|
7294
|
+
textClassName: "font-sans font-medium text-text-secondary",
|
|
7295
|
+
accessibilityLabel: `${name}, volume status: ${statusLabel}`,
|
|
7296
|
+
testID: onPress ? "muscle-group-chip-pressable" : "muscle-group-chip",
|
|
7232
7297
|
...props,
|
|
7233
|
-
children:
|
|
7234
|
-
/* @__PURE__ */ jsx(
|
|
7235
|
-
reactNative.View,
|
|
7236
|
-
{
|
|
7237
|
-
style: {
|
|
7238
|
-
width: 6,
|
|
7239
|
-
height: 6,
|
|
7240
|
-
borderRadius: 9999,
|
|
7241
|
-
marginRight: 5,
|
|
7242
|
-
flexShrink: 0,
|
|
7243
|
-
backgroundColor: dotColor
|
|
7244
|
-
},
|
|
7245
|
-
accessibilityElementsHidden: true,
|
|
7246
|
-
testID: "muscle-group-chip-dot"
|
|
7247
|
-
}
|
|
7248
|
-
),
|
|
7249
|
-
/* @__PURE__ */ jsx(
|
|
7250
|
-
reactNative.Text,
|
|
7251
|
-
{
|
|
7252
|
-
className: "text-text-secondary",
|
|
7253
|
-
style: {
|
|
7254
|
-
fontFamily: "Inter, sans-serif",
|
|
7255
|
-
fontWeight: "500",
|
|
7256
|
-
fontSize: 11
|
|
7257
|
-
},
|
|
7258
|
-
accessibilityElementsHidden: true,
|
|
7259
|
-
children: name
|
|
7260
|
-
}
|
|
7261
|
-
)
|
|
7262
|
-
]
|
|
7298
|
+
children: name
|
|
7263
7299
|
}
|
|
7264
7300
|
);
|
|
7265
|
-
if (onPress) {
|
|
7266
|
-
return /* @__PURE__ */ jsx(
|
|
7267
|
-
reactNative.Pressable,
|
|
7268
|
-
{
|
|
7269
|
-
onPress,
|
|
7270
|
-
accessibilityRole: "button",
|
|
7271
|
-
accessibilityLabel: `${name}, volume status: ${statusLabel}`,
|
|
7272
|
-
testID: "muscle-group-chip-pressable",
|
|
7273
|
-
children: content
|
|
7274
|
-
}
|
|
7275
|
-
);
|
|
7276
|
-
}
|
|
7277
|
-
return content;
|
|
7278
7301
|
}
|
|
7279
7302
|
|
|
7280
7303
|
// src/components/custom/Workout/WorkoutCard.tsx
|
|
7281
|
-
var
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
brandPrimary: t11["brand-primary"],
|
|
7286
|
-
borderDefault: HAIRLINE_DEFAULT3,
|
|
7287
|
-
brandPrimarySubtle: "rgba(255,121,0,0.06)"
|
|
7288
|
-
};
|
|
7289
|
-
var statusBorderColors = {
|
|
7290
|
-
completed: COLORS.statusSuccess,
|
|
7291
|
-
today: COLORS.brandPrimary,
|
|
7292
|
-
upcoming: COLORS.borderDefault
|
|
7304
|
+
var statusAccentToken = {
|
|
7305
|
+
completed: "status-success",
|
|
7306
|
+
today: "brand-primary",
|
|
7307
|
+
upcoming: "hairline-default"
|
|
7293
7308
|
};
|
|
7294
7309
|
var volumeStatusMap = {
|
|
7295
7310
|
under: "behind",
|
|
@@ -7324,41 +7339,33 @@ function WorkoutCard({
|
|
|
7324
7339
|
const summary = /* @__PURE__ */ jsxs(reactNative.View, { style: { padding: 14 }, testID: "workout-card-body", children: [
|
|
7325
7340
|
/* @__PURE__ */ jsxs(reactNative.View, { className: "flex-row items-center", testID: "workout-card-header", children: [
|
|
7326
7341
|
/* @__PURE__ */ jsx(
|
|
7327
|
-
|
|
7342
|
+
Typography,
|
|
7328
7343
|
{
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
fontFamily: '"Space Grotesk", sans-serif',
|
|
7333
|
-
fontWeight: "700"
|
|
7334
|
-
},
|
|
7344
|
+
variant: "h6",
|
|
7345
|
+
color: "primary",
|
|
7346
|
+
className: "text-base font-bold leading-[normal]",
|
|
7335
7347
|
testID: "workout-card-name",
|
|
7336
7348
|
children: name
|
|
7337
7349
|
}
|
|
7338
7350
|
),
|
|
7339
7351
|
/* @__PURE__ */ jsx(reactNative.View, { className: "flex-1" }),
|
|
7340
7352
|
/* @__PURE__ */ jsx(
|
|
7341
|
-
|
|
7353
|
+
Typography,
|
|
7342
7354
|
{
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
fontFamily: "Inter, sans-serif"
|
|
7347
|
-
},
|
|
7355
|
+
variant: "caption",
|
|
7356
|
+
color: "tertiary",
|
|
7357
|
+
className: "text-2xs leading-[normal]",
|
|
7348
7358
|
testID: "workout-card-date",
|
|
7349
7359
|
children: date
|
|
7350
7360
|
}
|
|
7351
7361
|
)
|
|
7352
7362
|
] }),
|
|
7353
7363
|
/* @__PURE__ */ jsx(
|
|
7354
|
-
|
|
7364
|
+
Typography,
|
|
7355
7365
|
{
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
fontSize: 12,
|
|
7360
|
-
fontFamily: "Inter, sans-serif"
|
|
7361
|
-
},
|
|
7366
|
+
variant: "caption",
|
|
7367
|
+
color: "secondary",
|
|
7368
|
+
className: "mt-1 leading-[normal]",
|
|
7362
7369
|
testID: "workout-card-stats",
|
|
7363
7370
|
children: formatStats(totalSets, totalVolume, unit, duration)
|
|
7364
7371
|
}
|
|
@@ -7387,8 +7394,8 @@ function WorkoutCard({
|
|
|
7387
7394
|
{
|
|
7388
7395
|
variant: "accent",
|
|
7389
7396
|
elevation: 1,
|
|
7390
|
-
accentColor:
|
|
7391
|
-
bgColor: isToday ?
|
|
7397
|
+
accentColor: resolveColor(statusAccentToken[status]),
|
|
7398
|
+
bgColor: isToday ? resolveColor("brand-primary-subtle") : void 0,
|
|
7392
7399
|
className,
|
|
7393
7400
|
style: isUpcoming ? { opacity: 0.6 } : void 0,
|
|
7394
7401
|
testID: "workout-card",
|
|
@@ -7426,7 +7433,7 @@ function WorkoutCard({
|
|
|
7426
7433
|
}
|
|
7427
7434
|
|
|
7428
7435
|
// src/components/custom/Workout/ProgramPlanningPage.tsx
|
|
7429
|
-
var
|
|
7436
|
+
var BRAND_PRIMARY8 = getSemanticColors("dark")["brand-primary"];
|
|
7430
7437
|
var WORKOUT_PILL_STATUS = {
|
|
7431
7438
|
completed: "completed",
|
|
7432
7439
|
today: "current",
|
|
@@ -7494,7 +7501,7 @@ function Breadcrumbs({ crumbs, onNavigate }) {
|
|
|
7494
7501
|
fontSize: 12,
|
|
7495
7502
|
fontFamily: "Inter, sans-serif",
|
|
7496
7503
|
fontWeight: isLast ? "700" : "500",
|
|
7497
|
-
color: isLast ? void 0 :
|
|
7504
|
+
color: isLast ? void 0 : BRAND_PRIMARY8
|
|
7498
7505
|
},
|
|
7499
7506
|
children: crumb.label
|
|
7500
7507
|
}
|