@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/src/utils/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { cn } from './cn'
|
|
2
|
+
export { formatCompact, formatSignedCompact } from './number-format'
|
|
2
3
|
export {
|
|
3
4
|
getStatusColor,
|
|
4
5
|
getResultColor,
|
|
@@ -20,13 +21,7 @@ export {
|
|
|
20
21
|
validationRules,
|
|
21
22
|
composeValidators,
|
|
22
23
|
} from './form'
|
|
23
|
-
export type {
|
|
24
|
-
FieldState,
|
|
25
|
-
FieldWrapperProps,
|
|
26
|
-
FormValues,
|
|
27
|
-
FormErrors,
|
|
28
|
-
FormTouched,
|
|
29
|
-
} from './form'
|
|
24
|
+
export type { FieldState, FieldWrapperProps, FormValues, FormErrors, FormTouched } from './form'
|
|
30
25
|
export {
|
|
31
26
|
roundRpe,
|
|
32
27
|
rpeColor,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact integer formatting for dense readouts (stat tiles, sparkline
|
|
3
|
+
* captions) where a full-precision number would blow the column width.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** 1234 → "1.2k", 1048576 → "1.0M", 42 → "42". Sign is preserved. */
|
|
7
|
+
export function formatCompact(n: number): string {
|
|
8
|
+
const abs = Math.abs(n)
|
|
9
|
+
if (abs >= 1_000_000) return (n / 1_000_000).toFixed(1) + 'M'
|
|
10
|
+
if (abs >= 1_000) return (n / 1_000).toFixed(1) + 'k'
|
|
11
|
+
return String(n)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Like {@link formatCompact} but always signed: 514689 → "+514.7k", -20 → "-20". */
|
|
15
|
+
export function formatSignedCompact(n: number): string {
|
|
16
|
+
return (n >= 0 ? '+' : '') + formatCompact(n)
|
|
17
|
+
}
|
|
@@ -52,6 +52,20 @@ export function formatSignedPct(ratio: number): string {
|
|
|
52
52
|
return `${pct > 0 ? '+' : ''}${pct}%`
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Rep-range label, e.g. `"8–10"`. `"8"` when the bounds are equal or only one is
|
|
57
|
+
* given; `null` when neither is set. Shared by {@link formatPrescription} and the
|
|
58
|
+
* set strip's per-set prescribed-range label so the two never drift apart.
|
|
59
|
+
*/
|
|
60
|
+
export function formatRepsRange(repsLow?: number, repsHigh?: number): string | null {
|
|
61
|
+
if (repsLow != null && repsHigh != null) {
|
|
62
|
+
return repsLow === repsHigh ? `${repsLow}` : `${repsLow}–${repsHigh}`
|
|
63
|
+
}
|
|
64
|
+
if (repsLow != null) return `${repsLow}`
|
|
65
|
+
if (repsHigh != null) return `${repsHigh}`
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
|
|
55
69
|
/** Structured prescription for the active exercise (from the plan). */
|
|
56
70
|
export interface PrescriptionInput {
|
|
57
71
|
repsLow?: number
|
|
@@ -67,12 +81,7 @@ export interface PrescriptionInput {
|
|
|
67
81
|
*/
|
|
68
82
|
export function formatPrescription(p: PrescriptionInput | null | undefined): string | null {
|
|
69
83
|
if (p == null) return null
|
|
70
|
-
|
|
71
|
-
if (p.repsLow != null && p.repsHigh != null) {
|
|
72
|
-
reps = p.repsLow === p.repsHigh ? `${p.repsLow}` : `${p.repsLow}–${p.repsHigh}`
|
|
73
|
-
} else if (p.repsLow != null) {
|
|
74
|
-
reps = `${p.repsLow}`
|
|
75
|
-
}
|
|
84
|
+
const reps = formatRepsRange(p.repsLow, p.repsHigh)
|
|
76
85
|
const weight = p.weightLbs != null ? `${p.weightLbs} lb` : null
|
|
77
86
|
const head = [reps, weight].filter((s): s is string => s != null).join(' @ ')
|
|
78
87
|
const rpe = p.rpe != null ? `RPE ${p.rpe}` : null
|
|
@@ -10,11 +10,7 @@
|
|
|
10
10
|
* native Metro). It is only inlined into the dist by tsup via
|
|
11
11
|
* an esbuild onResolve plugin.
|
|
12
12
|
*/
|
|
13
|
-
import {
|
|
14
|
-
jsx as reactJsx,
|
|
15
|
-
jsxs as reactJsxs,
|
|
16
|
-
Fragment,
|
|
17
|
-
} from 'react/jsx-runtime'
|
|
13
|
+
import { jsx as reactJsx, jsxs as reactJsxs, Fragment } from 'react/jsx-runtime'
|
|
18
14
|
import type { StyleProp } from 'react-native'
|
|
19
15
|
|
|
20
16
|
type JsxFn = typeof reactJsx
|
package/tailwind.config.js
CHANGED
|
@@ -183,6 +183,11 @@ module.exports = {
|
|
|
183
183
|
mono: ['var(--font-family-mono)', 'monospace'],
|
|
184
184
|
},
|
|
185
185
|
fontSize: {
|
|
186
|
+
// Micro steps. `2xs` carries a paired line-height like the rest of the
|
|
187
|
+
// scale (Typography's microLabel needs it); `3xs` is bare because a pill
|
|
188
|
+
// capsule takes its height from padding, not from the label's leading.
|
|
189
|
+
'3xs': '0.5625rem',
|
|
190
|
+
'2xs': ['0.625rem', { lineHeight: '0.875rem' }],
|
|
186
191
|
xs: ['0.75rem', { lineHeight: '1rem' }],
|
|
187
192
|
sm: ['0.875rem', { lineHeight: '1.25rem' }],
|
|
188
193
|
base: ['1rem', { lineHeight: '1.5rem' }],
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SHEET · Unified exercise card (page 2) — the LOCKED rail-expansion, hardened onto the
|
|
3
|
-
* REAL {@link ExerciseCard}. The collapsed rail item and the expanded card are ONE object: the
|
|
4
|
-
* persistent header is the real {@link ExerciseCardHeading}, and expanding reveals the body on the
|
|
5
|
-
* SAME surface — PREV dropped, done + upcoming sets share ONE muted treatment, the ACTIVE set
|
|
6
|
-
* stands out by brightness. Every per-row strip is the REAL {@link VelocityStrip} via its `set`
|
|
7
|
-
* descriptor: `mini` (flat 3px) for done/upcoming, and the `compact` velocity-height variant as
|
|
8
|
-
* the active-set SPOTLIGHT (option B, locked). No hand-built prototype strip remains.
|
|
9
|
-
*/
|
|
10
|
-
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
11
|
-
import { View, Text } from 'react-native'
|
|
12
|
-
import { ExerciseCard } from './ExerciseCard'
|
|
13
|
-
import { ExerciseCardHeading } from './ExerciseCardHeading'
|
|
14
|
-
import { VelocityStrip } from './VelocityStrip'
|
|
15
|
-
import { type SetRowProps } from './SetRow'
|
|
16
|
-
import { type SetStripSet } from './SetStrip'
|
|
17
|
-
import { INSET, BORDER_SUBTLE, T_PRIMARY, T_SECONDARY, Page, monoTag } from './setHeadingKit'
|
|
18
|
-
|
|
19
|
-
const INTER = 'Inter, sans-serif'
|
|
20
|
-
|
|
21
|
-
/** Per-rep mean velocity that DECAYS across a set (fast → slow). */
|
|
22
|
-
const decay = (n: number, start: number, span = 0.5) =>
|
|
23
|
-
Array.from({ length: n }, (_, r) => +(start - (span * r) / Math.max(1, n - 1)).toFixed(3))
|
|
24
|
-
|
|
25
|
-
// The exercise: a flat straight set (Cable Chest Press, 3 × 10 @ 90 lb).
|
|
26
|
-
const DONE = decay(10, 1.05)
|
|
27
|
-
const ACTIVE = decay(5, 0.95, 0.3)
|
|
28
|
-
|
|
29
|
-
// One data source drives both representations. Set 1 done · set 2 LIVE · set 3 upcoming.
|
|
30
|
-
const SETS: SetRowProps[] = [
|
|
31
|
-
{ state: 'done', setNumber: 1, unit: 'lbs', reps: 10, weight: 90, rpe: 7.5, velocities: DONE },
|
|
32
|
-
{
|
|
33
|
-
state: 'live',
|
|
34
|
-
setNumber: 2,
|
|
35
|
-
unit: 'lbs',
|
|
36
|
-
target: { reps: 10, weight: 90 },
|
|
37
|
-
reps: 5,
|
|
38
|
-
weight: 90,
|
|
39
|
-
velocities: ACTIVE,
|
|
40
|
-
},
|
|
41
|
-
{ state: 'todo', setNumber: 3, unit: 'lbs', target: { reps: 10, weight: 90 } },
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
// The header's per-set strip: the same lifecycle the card derives internally, built here
|
|
45
|
-
// so the collapsed rail item (ExerciseCardHeading) reads from the same source as the body.
|
|
46
|
-
const HEADER_STATES: SetStripSet[] = [
|
|
47
|
-
{ status: 'done', velocities: DONE },
|
|
48
|
-
{ status: 'active', velocities: ACTIVE, planned: 10 },
|
|
49
|
-
{ status: 'todo', planned: 10 },
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
const CARD_PROPS = {
|
|
53
|
-
name: 'Cable Chest Press',
|
|
54
|
-
summary: { sets: 3, reps: 10, weight: 90, unit: 'lbs' as const },
|
|
55
|
-
tempo: [2, 1, 2, 0] as [number, number, number, number],
|
|
56
|
-
indicator: 'info' as const,
|
|
57
|
-
sets: SETS,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function Surface({ children, width = 260 }: { children: React.ReactNode; width?: number }) {
|
|
61
|
-
return (
|
|
62
|
-
<View style={{ width, backgroundColor: INSET, borderRadius: 8, overflow: 'hidden' }}>
|
|
63
|
-
{children}
|
|
64
|
-
</View>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const meta: Meta = {
|
|
69
|
-
title: 'Lab/Explorations/Unified Exercise Card',
|
|
70
|
-
parameters: { layout: 'fullscreen' },
|
|
71
|
-
}
|
|
72
|
-
export default meta
|
|
73
|
-
type Story = StoryObj
|
|
74
|
-
|
|
75
|
-
export const Unified: Story = {
|
|
76
|
-
name: 'One object · rail header → expanded body (real ExerciseCard)',
|
|
77
|
-
render: () => (
|
|
78
|
-
<Page
|
|
79
|
-
title="Unified exercise card — the rail heading IS the header"
|
|
80
|
-
note="The LOCKED rail-expansion, hardened onto the real ExerciseCard. Collapsed, it's the rail item (the real ExerciseCardHeading); expanded, the SAME surface reveals the table body — PREV dropped, done + upcoming sets share ONE muted treatment, the ACTIVE set stands out by brightness. Every per-row strip is the real VelocityStrip: `mini` for done/upcoming, the `compact` velocity-height variant as the active-set spotlight (B, locked). No hand-built prototype strip remains."
|
|
81
|
-
>
|
|
82
|
-
<View style={{ flexDirection: 'row', gap: 40, alignItems: 'flex-start', flexWrap: 'wrap' }}>
|
|
83
|
-
<View style={{ gap: 8 }}>
|
|
84
|
-
<Text style={{ ...monoTag, color: T_SECONDARY }}>
|
|
85
|
-
collapsed · rail item (ExerciseCardHeading)
|
|
86
|
-
</Text>
|
|
87
|
-
<Surface>
|
|
88
|
-
<ExerciseCardHeading
|
|
89
|
-
name={CARD_PROPS.name}
|
|
90
|
-
sets={3}
|
|
91
|
-
reps={10}
|
|
92
|
-
load={90}
|
|
93
|
-
unit="lbs"
|
|
94
|
-
tempo={CARD_PROPS.tempo}
|
|
95
|
-
indicator={CARD_PROPS.indicator}
|
|
96
|
-
setStates={HEADER_STATES}
|
|
97
|
-
/>
|
|
98
|
-
</Surface>
|
|
99
|
-
</View>
|
|
100
|
-
|
|
101
|
-
<View style={{ gap: 8 }}>
|
|
102
|
-
<Text style={{ ...monoTag, color: T_SECONDARY }}>
|
|
103
|
-
expanded · same header + revealed body
|
|
104
|
-
</Text>
|
|
105
|
-
<Surface>
|
|
106
|
-
<ExerciseCard {...CARD_PROPS} defaultExpanded />
|
|
107
|
-
</Surface>
|
|
108
|
-
</View>
|
|
109
|
-
</View>
|
|
110
|
-
|
|
111
|
-
<View style={{ height: 1, backgroundColor: BORDER_SUBTLE, marginVertical: 8 }} />
|
|
112
|
-
|
|
113
|
-
<View style={{ gap: 10, maxWidth: 320 }}>
|
|
114
|
-
<Text style={{ ...monoTag, color: T_SECONDARY }}>
|
|
115
|
-
the locked active-set spotlight · VelocityStrip variant="expanded" (bare)
|
|
116
|
-
</Text>
|
|
117
|
-
<View style={{ backgroundColor: INSET, borderRadius: 8, padding: 12 }}>
|
|
118
|
-
<VelocityStrip
|
|
119
|
-
variant="expanded"
|
|
120
|
-
showNumbers={false}
|
|
121
|
-
showInfo={false}
|
|
122
|
-
height={24}
|
|
123
|
-
scale="fixed"
|
|
124
|
-
set={{ type: 'straight', velocities: ACTIVE, planned: 10 }}
|
|
125
|
-
/>
|
|
126
|
-
</View>
|
|
127
|
-
<Text style={{ fontFamily: INTER, fontSize: 12.5, color: T_SECONDARY, lineHeight: 19 }}>
|
|
128
|
-
A small fixed-height (~24px) velocity-HEIGHT strip: bar height ∝ velocity against a fixed
|
|
129
|
-
1.15 m/s ceiling, planned reps as grey stubs, set-type aware — none of the full
|
|
130
|
-
variant's labels, info row, or mount animation. It reads as the same object as the
|
|
131
|
-
flat `mini` strips above it, just taller and brighter to mark the live set.
|
|
132
|
-
</Text>
|
|
133
|
-
</View>
|
|
134
|
-
|
|
135
|
-
<Text
|
|
136
|
-
style={{
|
|
137
|
-
fontFamily: INTER,
|
|
138
|
-
fontSize: 12.5,
|
|
139
|
-
color: T_PRIMARY,
|
|
140
|
-
lineHeight: 19,
|
|
141
|
-
maxWidth: 780,
|
|
142
|
-
marginTop: 6,
|
|
143
|
-
}}
|
|
144
|
-
>
|
|
145
|
-
The header is the same molecule collapsed and expanded — the card reads as one object, the
|
|
146
|
-
body flowing out of the rail row rather than a separate panel. The expanded card is the real
|
|
147
|
-
ExerciseCard; its header per-set strip is derived from the same rows the body renders.
|
|
148
|
-
</Text>
|
|
149
|
-
</Page>
|
|
150
|
-
),
|
|
151
|
-
}
|
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Row Inventory — a READ-ONLY survey of every existing way the Workout library renders
|
|
3
|
-
* "an exercise / set / workout / week / mesocycle" as a row / list-entry / card.
|
|
4
|
-
*
|
|
5
|
-
* Built from the 2026-07-08 duplication audit (S3 SessionRail reuse question). This pane only
|
|
6
|
-
* NAMES and DISPLAYS what exists — no extraction, no changes to the components. It's here so we
|
|
7
|
-
* can eyeball the overlapping row representations together before deciding a reuse strategy.
|
|
8
|
-
*/
|
|
9
|
-
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
10
|
-
import { Component, type ReactNode } from 'react'
|
|
11
|
-
import { View, Text } from 'react-native'
|
|
12
|
-
import { ExerciseCard } from './ExerciseCard'
|
|
13
|
-
import { SetRow } from './SetRow'
|
|
14
|
-
import { WorkoutCard } from './WorkoutCard'
|
|
15
|
-
import { WorkoutPill } from './WorkoutPill'
|
|
16
|
-
import { WeekRow } from './WeekRow'
|
|
17
|
-
import { MesoCard } from './MesoCard'
|
|
18
|
-
import { MesoProgressBar } from './MesoProgressBar'
|
|
19
|
-
import { MuscleGroupChip } from './MuscleGroupChip'
|
|
20
|
-
import { StatusDot } from './StatusDot'
|
|
21
|
-
import { WeightBadge } from './WeightBadge'
|
|
22
|
-
import { PrBadge } from './PrBadge'
|
|
23
|
-
import { PlaceholderStrip } from './PlaceholderStrip'
|
|
24
|
-
import { SupersetWrapper } from './SupersetWrapper'
|
|
25
|
-
import { getSemanticColors } from '../../../theme/tokens/semantic'
|
|
26
|
-
|
|
27
|
-
const t = getSemanticColors('dark')
|
|
28
|
-
|
|
29
|
-
// ----------------------------------------------------------------------------- gallery scaffold
|
|
30
|
-
class Boundary extends Component<{ children: ReactNode }, { err: string | null }> {
|
|
31
|
-
state = { err: null as string | null }
|
|
32
|
-
static getDerivedStateFromError(e: Error) {
|
|
33
|
-
return { err: e.message }
|
|
34
|
-
}
|
|
35
|
-
render() {
|
|
36
|
-
if (this.state.err)
|
|
37
|
-
return (
|
|
38
|
-
<div style={{ color: '#ff6b6b', fontFamily: 'monospace', fontSize: 11, padding: 8 }}>
|
|
39
|
-
render error: {this.state.err}
|
|
40
|
-
</div>
|
|
41
|
-
)
|
|
42
|
-
return this.props.children
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function Cell({
|
|
47
|
-
name,
|
|
48
|
-
entity,
|
|
49
|
-
expand,
|
|
50
|
-
width = 340,
|
|
51
|
-
children,
|
|
52
|
-
}: {
|
|
53
|
-
name: string
|
|
54
|
-
entity: string
|
|
55
|
-
expand: string
|
|
56
|
-
width?: number
|
|
57
|
-
children: ReactNode
|
|
58
|
-
}) {
|
|
59
|
-
return (
|
|
60
|
-
<div
|
|
61
|
-
style={{
|
|
62
|
-
width,
|
|
63
|
-
display: 'flex',
|
|
64
|
-
flexDirection: 'column',
|
|
65
|
-
gap: 8,
|
|
66
|
-
padding: 14,
|
|
67
|
-
borderRadius: 12,
|
|
68
|
-
border: '1px solid #24262d',
|
|
69
|
-
background: '#131418',
|
|
70
|
-
}}
|
|
71
|
-
>
|
|
72
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
73
|
-
<span style={{ fontSize: 13, fontWeight: 800, color: '#E8EAED' }}>{name}</span>
|
|
74
|
-
<span
|
|
75
|
-
style={{ fontFamily: 'monospace', fontSize: 10, color: '#5b616d', letterSpacing: 0.3 }}
|
|
76
|
-
>
|
|
77
|
-
{entity} · {expand}
|
|
78
|
-
</span>
|
|
79
|
-
</div>
|
|
80
|
-
<div style={{ marginTop: 2 }}>
|
|
81
|
-
<Boundary>{children}</Boundary>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function Section({ title, note, children }: { title: string; note?: string; children: ReactNode }) {
|
|
88
|
-
return (
|
|
89
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
|
90
|
-
<div style={{ display: 'flex', alignItems: 'baseline', gap: 10 }}>
|
|
91
|
-
<span
|
|
92
|
-
style={{
|
|
93
|
-
fontSize: 11,
|
|
94
|
-
fontWeight: 800,
|
|
95
|
-
letterSpacing: 1.2,
|
|
96
|
-
textTransform: 'uppercase',
|
|
97
|
-
color: '#FF7900',
|
|
98
|
-
}}
|
|
99
|
-
>
|
|
100
|
-
{title}
|
|
101
|
-
</span>
|
|
102
|
-
{note && <span style={{ fontSize: 11, color: '#8D95A3' }}>{note}</span>}
|
|
103
|
-
</div>
|
|
104
|
-
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 14, alignItems: 'flex-start' }}>
|
|
105
|
-
{children}
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// ----------------------------------------------------------------------------- sample data
|
|
112
|
-
const setVel = [
|
|
113
|
-
[0.6, 0.58, 0.55, 0.52],
|
|
114
|
-
[0.58, 0.55, 0.53, 0.5],
|
|
115
|
-
[0.55, 0.52, 0.5, 0.47],
|
|
116
|
-
]
|
|
117
|
-
const exSets = [1, 2, 3, 4].map((n) => ({
|
|
118
|
-
state: 'done' as const,
|
|
119
|
-
setNumber: n,
|
|
120
|
-
reps: 8,
|
|
121
|
-
weight: 145,
|
|
122
|
-
rpe: 6.5 + n * 0.5,
|
|
123
|
-
unit: 'lbs' as const,
|
|
124
|
-
velocities: setVel[(n - 1) % 3],
|
|
125
|
-
}))
|
|
126
|
-
const weeks = [
|
|
127
|
-
{
|
|
128
|
-
weekNumber: 1,
|
|
129
|
-
workouts: [
|
|
130
|
-
{ name: 'Upper', status: 'completed' as const },
|
|
131
|
-
{ name: 'Lower', status: 'completed' as const },
|
|
132
|
-
],
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
weekNumber: 2,
|
|
136
|
-
workouts: [
|
|
137
|
-
{ name: 'Upper', status: 'current' as const },
|
|
138
|
-
{ name: 'Lower', status: 'upcoming' as const },
|
|
139
|
-
],
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
weekNumber: 3,
|
|
143
|
-
workouts: [
|
|
144
|
-
{ name: 'Upper', status: 'upcoming' as const },
|
|
145
|
-
{ name: 'Lower', status: 'upcoming' as const },
|
|
146
|
-
],
|
|
147
|
-
},
|
|
148
|
-
]
|
|
149
|
-
const mesos = [
|
|
150
|
-
{ id: 'm1', name: 'Accumulation', weekCount: 4, status: 'completed' as const },
|
|
151
|
-
{ id: 'm2', name: 'Intensification', weekCount: 3, status: 'current' as const, currentWeek: 2 },
|
|
152
|
-
{ id: 'm3', name: 'Peak', weekCount: 2, status: 'upcoming' as const },
|
|
153
|
-
]
|
|
154
|
-
|
|
155
|
-
// ----------------------------------------------------------------------------- the pane
|
|
156
|
-
const meta: Meta = {
|
|
157
|
-
title: 'Lab/Audits/Row Inventory',
|
|
158
|
-
parameters: { layout: 'fullscreen' },
|
|
159
|
-
}
|
|
160
|
-
export default meta
|
|
161
|
-
type Story = StoryObj
|
|
162
|
-
|
|
163
|
-
export const AllRows: Story = {
|
|
164
|
-
name: 'All row representations',
|
|
165
|
-
render: () => (
|
|
166
|
-
<div
|
|
167
|
-
style={{
|
|
168
|
-
minHeight: '100vh',
|
|
169
|
-
background: '#0c0d0f',
|
|
170
|
-
padding: 28,
|
|
171
|
-
display: 'flex',
|
|
172
|
-
flexDirection: 'column',
|
|
173
|
-
gap: 34,
|
|
174
|
-
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
175
|
-
}}
|
|
176
|
-
>
|
|
177
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
|
178
|
-
<span style={{ fontSize: 20, fontWeight: 800, color: '#E8EAED' }}>
|
|
179
|
-
Workout library · row representations
|
|
180
|
-
</span>
|
|
181
|
-
<span style={{ fontSize: 12, color: '#8D95A3', maxWidth: 720 }}>
|
|
182
|
-
Every existing component that draws an exercise / set / workout / week / meso as a list
|
|
183
|
-
entry. Read-only survey for the S3 reuse decision — names + entity + expand behavior, no
|
|
184
|
-
code changes.
|
|
185
|
-
</span>
|
|
186
|
-
</div>
|
|
187
|
-
|
|
188
|
-
<Section
|
|
189
|
-
title="Exercise"
|
|
190
|
-
note="3 representations of the one ExerciseCard: collapsed glance, expanded body, upcoming"
|
|
191
|
-
>
|
|
192
|
-
<Cell name="ExerciseCard" entity="exercise" expand="collapsed · expandable">
|
|
193
|
-
<ExerciseCard
|
|
194
|
-
name="Seated Cable Row"
|
|
195
|
-
summary={{ sets: 4, reps: 8, weight: 145, unit: 'lbs' }}
|
|
196
|
-
isPR
|
|
197
|
-
totalPlannedSets={5}
|
|
198
|
-
setVelocities={setVel}
|
|
199
|
-
/>
|
|
200
|
-
</Cell>
|
|
201
|
-
<Cell name="ExerciseCard" entity="exercise" expand="expanded → reveals SetRows">
|
|
202
|
-
<ExerciseCard
|
|
203
|
-
name="Seated Cable Row"
|
|
204
|
-
defaultExpanded
|
|
205
|
-
summary={{ sets: 4, reps: 8, weight: 145, unit: 'lbs' }}
|
|
206
|
-
tempo={[3, 1, 2, 0]}
|
|
207
|
-
sets={exSets}
|
|
208
|
-
/>
|
|
209
|
-
</Cell>
|
|
210
|
-
<Cell name="ExerciseCard" entity="exercise" expand="upcoming (static)">
|
|
211
|
-
<ExerciseCard
|
|
212
|
-
name="Face Pull"
|
|
213
|
-
upcoming
|
|
214
|
-
prescription="3 × 12-15 @ RPE 7"
|
|
215
|
-
previousBest="15 × 35 lb"
|
|
216
|
-
/>
|
|
217
|
-
</Cell>
|
|
218
|
-
</Section>
|
|
219
|
-
|
|
220
|
-
<Section
|
|
221
|
-
title="Set"
|
|
222
|
-
note="SetRow is the primitive — one row per set lifecycle state (done / live / todo)"
|
|
223
|
-
>
|
|
224
|
-
<Cell name="SetRow" entity="set · done" expand="no · flat mini strip" width={360}>
|
|
225
|
-
<SetRow
|
|
226
|
-
state="done"
|
|
227
|
-
setNumber={1}
|
|
228
|
-
reps={8}
|
|
229
|
-
weight={145}
|
|
230
|
-
rpe={8}
|
|
231
|
-
unit="lbs"
|
|
232
|
-
velocities={[0.6, 0.58, 0.55, 0.52]}
|
|
233
|
-
/>
|
|
234
|
-
</Cell>
|
|
235
|
-
<Cell name="SetRow" entity="set · live" expand="no · compact spotlight" width={360}>
|
|
236
|
-
<SetRow
|
|
237
|
-
state="live"
|
|
238
|
-
setNumber={2}
|
|
239
|
-
unit="lbs"
|
|
240
|
-
target={{ reps: 8, weight: 145 }}
|
|
241
|
-
reps={8}
|
|
242
|
-
weight={145}
|
|
243
|
-
velocities={[0.58, 0.55, 0.53, 0.5]}
|
|
244
|
-
/>
|
|
245
|
-
</Cell>
|
|
246
|
-
<Cell name="SetRow" entity="set · todo" expand="no · grey stub strip" width={360}>
|
|
247
|
-
<SetRow state="todo" setNumber={4} unit="lbs" target={{ reps: 8, weight: 145 }} />
|
|
248
|
-
</Cell>
|
|
249
|
-
</Section>
|
|
250
|
-
|
|
251
|
-
<Section
|
|
252
|
-
title="Workout"
|
|
253
|
-
note="WorkoutCard (full) and WorkoutPill (chip) = two legit densities; ExerciseDetailPage overloads ExerciseCard as a 3rd"
|
|
254
|
-
>
|
|
255
|
-
<Cell
|
|
256
|
-
name="WorkoutCard"
|
|
257
|
-
entity="workout"
|
|
258
|
-
expand="expandable · expanded+onToggle → ExerciseCards"
|
|
259
|
-
width={380}
|
|
260
|
-
>
|
|
261
|
-
<WorkoutCard
|
|
262
|
-
name="Push Day A"
|
|
263
|
-
date="Mon · Jul 6"
|
|
264
|
-
duration="52 min"
|
|
265
|
-
status="today"
|
|
266
|
-
muscleGroups={[
|
|
267
|
-
{ group: 'chest', label: 'Chest', volumeStatus: 'productive' },
|
|
268
|
-
{ group: 'delts', label: 'Delts', volumeStatus: 'maintenance' },
|
|
269
|
-
{ group: 'triceps', label: 'Triceps', volumeStatus: 'under' },
|
|
270
|
-
]}
|
|
271
|
-
totalSets={18}
|
|
272
|
-
totalVolume={7340}
|
|
273
|
-
unit="lbs"
|
|
274
|
-
onToggle={() => {}}
|
|
275
|
-
/>
|
|
276
|
-
</Cell>
|
|
277
|
-
<Cell name="WorkoutPill" entity="workout · chip" expand="no">
|
|
278
|
-
<View style={{ flexDirection: 'row', gap: 8, flexWrap: 'wrap' }}>
|
|
279
|
-
<WorkoutPill name="Push" status="completed" />
|
|
280
|
-
<WorkoutPill name="Pull" status="current" />
|
|
281
|
-
<WorkoutPill name="Legs" status="upcoming" />
|
|
282
|
-
<WorkoutPill name="Deload" status="deload" />
|
|
283
|
-
</View>
|
|
284
|
-
</Cell>
|
|
285
|
-
</Section>
|
|
286
|
-
|
|
287
|
-
<Section
|
|
288
|
-
title="Week"
|
|
289
|
-
note="WeekRow is the primitive; ExerciseDetailPage overloads ExerciseCard as a competing week row"
|
|
290
|
-
>
|
|
291
|
-
<Cell
|
|
292
|
-
name="WeekRow"
|
|
293
|
-
entity="week"
|
|
294
|
-
expand="no · row of WorkoutPills + intensity bar"
|
|
295
|
-
width={380}
|
|
296
|
-
>
|
|
297
|
-
<WeekRow
|
|
298
|
-
weekNumber={3}
|
|
299
|
-
totalWeeks={4}
|
|
300
|
-
isCurrent
|
|
301
|
-
intensityLevel={0.55}
|
|
302
|
-
intensityThreshold={0.8}
|
|
303
|
-
workouts={weeks[1].workouts}
|
|
304
|
-
/>
|
|
305
|
-
</Cell>
|
|
306
|
-
</Section>
|
|
307
|
-
|
|
308
|
-
<Section
|
|
309
|
-
title="Mesocycle"
|
|
310
|
-
note="3 views for different jobs (list card / timeline / detail) — each with its own status enum"
|
|
311
|
-
>
|
|
312
|
-
<Cell
|
|
313
|
-
name="MesoCard"
|
|
314
|
-
entity="meso"
|
|
315
|
-
expand="expandable · expanded+onToggle → WeekRows"
|
|
316
|
-
width={380}
|
|
317
|
-
>
|
|
318
|
-
<MesoCard
|
|
319
|
-
name="Accumulation"
|
|
320
|
-
goal="Hypertrophy"
|
|
321
|
-
split="Upper/Lower"
|
|
322
|
-
weekRange="Weeks 1-4"
|
|
323
|
-
currentWeek={2}
|
|
324
|
-
totalWeeks={4}
|
|
325
|
-
weeks={weeks}
|
|
326
|
-
volumeHeatmap={[
|
|
327
|
-
{ group: 'chest', percentage: 80 },
|
|
328
|
-
{ group: 'back', percentage: 70 },
|
|
329
|
-
{ group: 'legs', percentage: 90 },
|
|
330
|
-
]}
|
|
331
|
-
/>
|
|
332
|
-
</Cell>
|
|
333
|
-
<Cell name="MesoProgressBar" entity="meso · timeline" expand="no · segments" width={380}>
|
|
334
|
-
<MesoProgressBar mesos={mesos} />
|
|
335
|
-
</Cell>
|
|
336
|
-
</Section>
|
|
337
|
-
|
|
338
|
-
<Section
|
|
339
|
-
title="Shared sub-parts"
|
|
340
|
-
note="appear inside the rows above — not entity rows themselves"
|
|
341
|
-
>
|
|
342
|
-
<Cell name="MuscleGroupChip" entity="muscle-group" expand="no">
|
|
343
|
-
<View style={{ flexDirection: 'row', gap: 8, flexWrap: 'wrap' }}>
|
|
344
|
-
<MuscleGroupChip name="Chest" volumeStatus="ontrack" />
|
|
345
|
-
<MuscleGroupChip name="Quads" volumeStatus="behind" />
|
|
346
|
-
<MuscleGroupChip name="Lats" volumeStatus="over" />
|
|
347
|
-
</View>
|
|
348
|
-
</Cell>
|
|
349
|
-
<Cell name="StatusDot" entity="status glyph" expand="no">
|
|
350
|
-
<StatusDot variant="success" label="On track" />
|
|
351
|
-
</Cell>
|
|
352
|
-
<Cell name="WeightBadge" entity="badge" expand="no">
|
|
353
|
-
<View style={{ flexDirection: 'row', gap: 8 }}>
|
|
354
|
-
<WeightBadge value={205} unit="lbs" />
|
|
355
|
-
<WeightBadge value={217} unit="lbs" isPr />
|
|
356
|
-
</View>
|
|
357
|
-
</Cell>
|
|
358
|
-
<Cell name="PrBadge" entity="badge" expand="no">
|
|
359
|
-
<PrBadge type="e1rm" animate={false} />
|
|
360
|
-
</Cell>
|
|
361
|
-
<Cell name="PlaceholderStrip" entity="pending-set strip" expand="no">
|
|
362
|
-
<View style={{ flexDirection: 'row', gap: 4 }}>
|
|
363
|
-
<PlaceholderStrip />
|
|
364
|
-
<PlaceholderStrip />
|
|
365
|
-
<PlaceholderStrip />
|
|
366
|
-
</View>
|
|
367
|
-
</Cell>
|
|
368
|
-
<Cell name="SupersetWrapper" entity="grouping bracket" expand="no">
|
|
369
|
-
<SupersetWrapper label="SS1" color="#FF7900">
|
|
370
|
-
<View style={{ padding: 10, backgroundColor: t['surface-raised'], borderRadius: 8 }}>
|
|
371
|
-
<Text style={{ color: '#F3F4F6' }}>Exercise A</Text>
|
|
372
|
-
</View>
|
|
373
|
-
<View style={{ padding: 10, backgroundColor: t['surface-raised'], borderRadius: 8 }}>
|
|
374
|
-
<Text style={{ color: '#F3F4F6' }}>Exercise B</Text>
|
|
375
|
-
</View>
|
|
376
|
-
</SupersetWrapper>
|
|
377
|
-
</Cell>
|
|
378
|
-
</Section>
|
|
379
|
-
|
|
380
|
-
<Section
|
|
381
|
-
title="Page-level organisms"
|
|
382
|
-
note="composition roots (390px+), not rows — listed for reference, see their own stories"
|
|
383
|
-
>
|
|
384
|
-
{[
|
|
385
|
-
['ActiveWorkoutPage', 'renders ExerciseCards + SupersetWrapper + InputBar/RestTimer'],
|
|
386
|
-
['ProgramPlanningPage', 'MesoProgressBar + MesoCard → WeekRow → WorkoutCard drill-down'],
|
|
387
|
-
['ExerciseDetailPage', 'EntryList overloads ExerciseCard as week AND session rows'],
|
|
388
|
-
['MesoStatusCard', 'per-exercise meso detail card (StatusDot + metric grid + gauges)'],
|
|
389
|
-
['ReadinessCheck', 'pre-workout factor rows + score gauge'],
|
|
390
|
-
].map(([n, d]) => (
|
|
391
|
-
<div
|
|
392
|
-
key={n}
|
|
393
|
-
style={{
|
|
394
|
-
width: 340,
|
|
395
|
-
padding: 14,
|
|
396
|
-
borderRadius: 12,
|
|
397
|
-
border: '1px dashed #31343d',
|
|
398
|
-
background: '#0f1012',
|
|
399
|
-
}}
|
|
400
|
-
>
|
|
401
|
-
<div style={{ fontSize: 13, fontWeight: 800, color: '#E8EAED' }}>{n}</div>
|
|
402
|
-
<div style={{ fontSize: 11, color: '#8D95A3', marginTop: 4 }}>{d}</div>
|
|
403
|
-
</div>
|
|
404
|
-
))}
|
|
405
|
-
</Section>
|
|
406
|
-
</div>
|
|
407
|
-
),
|
|
408
|
-
}
|