@titan-design/react-ui 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -47
- package/dist/bodymap.js +856 -736
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +858 -738
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +1431 -237
- package/dist/index.d.ts +1431 -237
- package/dist/index.js +6506 -4781
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6280 -4642
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-B1hqnGIC.d.ts → pages-CsjsUn0G.d.ts} +51 -16
- package/dist/{pages-CvsFqNtx.d.mts → pages-ZbT_pD_U.d.mts} +51 -16
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +1919 -1937
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +1927 -1945
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +225 -140
- package/dist/theme/index.d.ts +225 -140
- package/dist/theme/index.js +298 -319
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +283 -315
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +145 -24
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +145 -24
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/dist/theme/tokens.d.mts +128 -11
- package/dist/theme/tokens.d.ts +128 -11
- package/dist/theme/tokens.js +126 -26
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme/tokens.mjs +124 -27
- 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/docs/render-testing-pattern.md +130 -0
- package/package.json +1 -1
- package/src/arch/Architecture.stories.tsx +3 -1
- package/src/arch/arch-graph.freshness.test.ts +52 -0
- package/src/arch/arch-graph.json +4989 -1583
- 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 +182 -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 +12 -6
- 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 +6 -3
- package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.tsx +7 -2
- 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 +55 -14
- package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
- package/src/components/custom/Scatter/Scatter.tsx +122 -18
- package/src/components/custom/Sidebar/Sidebar.stories.tsx +41 -8
- 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 +99 -16
- 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 +15 -12
- package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
- package/src/components/custom/Treemap/Treemap.tsx +11 -3
- 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 +11 -2
- package/src/components/custom/Workout/BaseBadge.stories.tsx +27 -11
- package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
- package/src/components/custom/Workout/BaseBadge.tsx +6 -2
- package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
- package/src/components/custom/Workout/BodyMap.tsx +8 -4
- package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +28 -6
- package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +50 -12
- package/src/components/custom/Workout/CapacityBandChart.stories.tsx +12 -9
- package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
- package/src/components/custom/Workout/CapacityBandChart.tsx +144 -111
- package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
- package/src/components/custom/Workout/DeviationBar.test.tsx +10 -4
- package/src/components/custom/Workout/DeviationBar.tsx +24 -16
- package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +183 -0
- package/src/components/custom/Workout/DualVelocityStrip.test.tsx +32 -18
- package/src/components/custom/Workout/ExerciseCard.stories.tsx +12 -11
- package/src/components/custom/Workout/ExerciseCard.test.tsx +52 -22
- package/src/components/custom/Workout/ExerciseCard.tsx +99 -183
- package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +95 -12
- package/src/components/custom/Workout/ExerciseCardHeading.test.tsx +189 -1
- package/src/components/custom/Workout/ExerciseCardHeading.tsx +167 -18
- package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
- package/src/components/custom/Workout/ExerciseDetailPage.tsx +3 -2
- package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
- package/src/components/custom/Workout/ExerciseHeading.tsx +194 -46
- package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +12 -9
- 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/InputBar.tsx +4 -2
- 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 +8 -3
- 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 +14 -10
- 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 +20 -33
- 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 +9 -4
- 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 +16 -3
- 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 +68 -17
- 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 +22 -4
- package/src/components/custom/Workout/RestTimer.stories.tsx +16 -4
- package/src/components/custom/Workout/RestTimer.tsx +4 -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 +21 -17
- package/src/components/custom/Workout/SegmentedBar.tsx +10 -5
- 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 +63 -7
- 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 +24 -12
- package/src/components/custom/Workout/Sparkline.stories.tsx +14 -11
- 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 +11 -4
- package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
- package/src/components/custom/Workout/StrengthTrendChart.tsx +39 -36
- 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 +26 -10
- package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
- package/src/components/custom/Workout/TempoDisplay.tsx +2 -0
- 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 +10 -6
- package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +5 -2
- package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +44 -1
- package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
- package/src/components/custom/Workout/VelocityStrip.test.tsx +48 -6
- package/src/components/custom/Workout/VelocityStrip.tsx +26 -14
- 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 +10 -7
- package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
- package/src/components/custom/Workout/exerciseRowState.ts +29 -0
- package/src/components/custom/Workout/index.ts +17 -2
- package/src/components/custom/Workout/metricText.stories.tsx +15 -13
- package/src/components/custom/Workout/metricText.tsx +8 -2
- package/src/components/custom/Workout/setHeadingKit.tsx +219 -36
- package/src/components/custom/Workout/velocity-story-kit.tsx +2 -2
- package/src/components/custom/charts/README.md +66 -0
- package/src/components/custom/charts/SetBarChart.test.tsx +46 -1
- package/src/components/custom/charts/SetBarChart.tsx +56 -9
- 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/flatBarGeometry.test.ts +41 -0
- package/src/components/custom/charts/flatBarGeometry.ts +32 -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 +21 -34
- 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 +15 -5
- package/src/components/ui/alert/Alert.tsx +24 -3
- 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 +44 -37
- 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 +7 -27
- 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 +14 -3
- 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 -27
- 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 +10 -18
- package/src/components/ui/indicator/Indicator.stories.tsx +5 -4
- 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 +17 -5
- 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 +31 -19
- package/src/components/ui/pill/Pill.stories.tsx +111 -23
- package/src/components/ui/pill/Pill.test.tsx +101 -3
- package/src/components/ui/pill/Pill.tsx +168 -49
- package/src/components/ui/pill/index.ts +1 -1
- package/src/components/ui/popover/Popover.stories.tsx +6 -8
- 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/progress/Progress.tsx +9 -6
- 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 +12 -21
- 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 +16 -15
- 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 +4 -5
- package/src/components/ui/stack/Stack.stories.tsx +8 -8
- package/src/components/ui/stack/Stack.tsx +1 -1
- package/src/components/ui/surface/Surface.stories.tsx +92 -33
- 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 +8 -21
- 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 +49 -57
- 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 +38 -49
- 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 +101 -48
- package/src/test/no-device-internals.test.ts +3 -3
- package/src/test/no-raw-color.test.ts +39 -0
- package/src/theme/Alpha.stories.tsx +103 -0
- 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/ProposedTokensVW82.stories.tsx +414 -0
- 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 +40 -0
- package/src/theme/elevation.test.ts +82 -56
- package/src/theme/elevation.ts +77 -561
- package/src/theme/global.css +45 -5
- 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/subtle-tone-weight.test.ts +163 -0
- package/src/theme/surface-planes.test.ts +37 -0
- package/src/theme/surface-planes.ts +68 -0
- package/src/theme/tailwind-var-opacity.test.ts +163 -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 +98 -33
- package/src/theme/tokens/semantic-hex-guard.test.ts +322 -0
- package/src/theme/tokens/semantic.ts +124 -54
- 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.alpha-adoption.test.ts +408 -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 +55 -9
- 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/bodymap.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useMemo, useState, useEffect, Fragment
|
|
1
|
+
import { createContext, useMemo, useState, useEffect, Fragment, useContext } from 'react';
|
|
2
2
|
import { Platform, Animated, Easing, View, Text, Pressable, ScrollView } from 'react-native';
|
|
3
3
|
import BodyHighlighter from 'react-native-body-highlighter';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
|
-
import { Fragment, jsx as jsx$1, jsxs as jsxs$1 } from 'react/jsx-runtime';
|
|
6
|
+
import { Fragment as Fragment$1, jsx as jsx$1, jsxs as jsxs$1 } from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
8
|
// src/components/custom/Workout/BodyMap.tsx
|
|
9
9
|
function cn(...inputs) {
|
|
@@ -12,7 +12,29 @@ function cn(...inputs) {
|
|
|
12
12
|
|
|
13
13
|
// src/theme/tokens/primitives.ts
|
|
14
14
|
var primitiveColors = {
|
|
15
|
-
white: "#FFFFFF"
|
|
15
|
+
white: "#FFFFFF",
|
|
16
|
+
black: "#000000"};
|
|
17
|
+
var alertRedVivid = "#FF4757";
|
|
18
|
+
var resultPaletteColors = {
|
|
19
|
+
improve: "#4caf50",
|
|
20
|
+
improveDark: "#248a24",
|
|
21
|
+
degrade: "#ef5350",
|
|
22
|
+
degradeDark: "#b30000",
|
|
23
|
+
inconclusive: "#9E9A97"
|
|
24
|
+
};
|
|
25
|
+
var semanticPins = {
|
|
26
|
+
// Cool navy-black; darker and more blue-shifted than any warm greyRamp step.
|
|
27
|
+
textPrimaryLight: "#121828",
|
|
28
|
+
// Cool blue-grey; outside greyRamp's warm (R>=G>=B) scale.
|
|
29
|
+
textSecondaryLight: "#65748B",
|
|
30
|
+
// Pure neutral grey (R=G=B); no warm greyRamp step lands on it exactly.
|
|
31
|
+
backgroundBaseLight: "#EBEBEB",
|
|
32
|
+
// Near-neutral grey, kept one step off backgroundBaseLight by design.
|
|
33
|
+
dividerLight: "#E8E9EB",
|
|
34
|
+
// Periwinkle/indigo; more purple than any primitiveRamps.blue step. Shared by
|
|
35
|
+
// dark-mode text-link, border-focus and border-input-focus.
|
|
36
|
+
focusIndigoDark: "#828DF8"
|
|
37
|
+
};
|
|
16
38
|
var greyRamp = {
|
|
17
39
|
50: "#F9F6F3",
|
|
18
40
|
// L*97.0 W6
|
|
@@ -46,6 +68,7 @@ var greyRamp = {
|
|
|
46
68
|
var primitiveRamps = {
|
|
47
69
|
red: {
|
|
48
70
|
50: "#FFF4F4",
|
|
71
|
+
400: "#F77175",
|
|
49
72
|
500: "#E05254",
|
|
50
73
|
600: "#D14343",
|
|
51
74
|
// pin
|
|
@@ -135,22 +158,34 @@ var semanticColorsLight = {
|
|
|
135
158
|
"brand-primary-light": primitiveRamps.orange[300],
|
|
136
159
|
"brand-primary-dark": primitiveRamps.orange[500],
|
|
137
160
|
"brand-primary-subtle": "rgba(255, 121, 0, 0.08)",
|
|
161
|
+
"brand-primary-muted": "rgba(255, 121, 0, 0.30)",
|
|
162
|
+
"brand-primary-strong": "rgba(255, 121, 0, 0.50)",
|
|
138
163
|
"brand-primary-hover": primitiveRamps.orange[500],
|
|
139
164
|
"brand-primary-active": primitiveRamps.orange[600],
|
|
140
165
|
"brand-secondary": primitiveRamps.cyan[600],
|
|
141
166
|
"brand-secondary-light": primitiveRamps.cyan[500],
|
|
142
167
|
"brand-secondary-dark": primitiveRamps.cyan[700],
|
|
143
168
|
"brand-secondary-subtle": "rgba(48, 123, 155, 0.08)",
|
|
169
|
+
"brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
|
|
170
|
+
"brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
|
|
144
171
|
"brand-secondary-hover": primitiveRamps.cyan[700],
|
|
145
172
|
"brand-secondary-active": primitiveRamps.cyan[800],
|
|
146
173
|
// Text on brand backgrounds (on-*)
|
|
147
174
|
"on-brand-primary": primitiveColors.white,
|
|
148
175
|
"on-brand-secondary": primitiveColors.white,
|
|
176
|
+
// Text ON a `-subtle` fill. Light mode keeps today's pairing (the base token) so
|
|
177
|
+
// nothing moves here: light has the same disease mirrored — a light rung on a
|
|
178
|
+
// near-white ramp[50] fill — but correcting it belongs with the light-mode pass
|
|
179
|
+
// in AW-121, not this one.
|
|
180
|
+
"on-brand-primary-subtle": primitiveRamps.orange[400],
|
|
181
|
+
"on-brand-secondary-subtle": primitiveRamps.cyan[600],
|
|
149
182
|
// Status colors (status-*)
|
|
150
183
|
"status-success": primitiveRamps.green[300],
|
|
151
184
|
"status-success-light": primitiveRamps.green[200],
|
|
152
185
|
"status-success-dark": primitiveRamps.green[600],
|
|
153
186
|
"status-success-subtle": primitiveRamps.green[50],
|
|
187
|
+
"status-success-muted": "rgba(46, 213, 115, 0.30)",
|
|
188
|
+
"status-success-strong": "rgba(46, 213, 115, 0.50)",
|
|
154
189
|
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
155
190
|
"status-live": primitiveRamps.green[300],
|
|
156
191
|
"status-live-muted": primitiveRamps.green[500],
|
|
@@ -158,34 +193,47 @@ var semanticColorsLight = {
|
|
|
158
193
|
"status-error-light": primitiveRamps.red[500],
|
|
159
194
|
"status-error-dark": primitiveRamps.red[700],
|
|
160
195
|
"status-error-subtle": primitiveRamps.red[50],
|
|
161
|
-
"status-error-
|
|
162
|
-
|
|
196
|
+
"status-error-muted": "rgba(209, 67, 67, 0.30)",
|
|
197
|
+
"status-error-strong": "rgba(209, 67, 67, 0.50)",
|
|
198
|
+
"status-error-vivid": alertRedVivid,
|
|
199
|
+
// NOT red[600], that is status-error
|
|
163
200
|
"status-error-vivid-light": primitiveRamps.red[500],
|
|
164
201
|
"status-error-vivid-dark": primitiveRamps.red[700],
|
|
165
202
|
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
203
|
+
"status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
|
|
204
|
+
"status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
|
|
166
205
|
"status-warning": primitiveRamps.amber[300],
|
|
167
206
|
"status-warning-light": primitiveRamps.amber[200],
|
|
168
207
|
"status-warning-dark": primitiveRamps.amber[500],
|
|
169
208
|
"status-warning-subtle": primitiveRamps.amber[50],
|
|
209
|
+
"status-warning-muted": "rgba(249, 180, 21, 0.30)",
|
|
210
|
+
"status-warning-strong": "rgba(249, 180, 21, 0.50)",
|
|
170
211
|
"status-info": primitiveRamps.blue[500],
|
|
171
212
|
"status-info-light": primitiveRamps.blue[300],
|
|
172
213
|
"status-info-dark": primitiveRamps.blue[600],
|
|
173
214
|
"status-info-subtle": primitiveRamps.blue[50],
|
|
215
|
+
"status-info-muted": "rgba(33, 150, 243, 0.30)",
|
|
216
|
+
"status-info-strong": "rgba(33, 150, 243, 0.50)",
|
|
217
|
+
// Text ON a `-subtle` fill — see the on-brand-*-subtle note above.
|
|
218
|
+
"on-status-success-subtle": primitiveRamps.green[300],
|
|
219
|
+
"on-status-error-subtle": primitiveRamps.red[600],
|
|
220
|
+
"on-status-warning-subtle": primitiveRamps.amber[300],
|
|
221
|
+
"on-status-info-subtle": primitiveRamps.blue[500],
|
|
174
222
|
// Text on status backgrounds (on-status-*)
|
|
175
223
|
"on-status-success": primitiveColors.white,
|
|
176
224
|
"on-status-error": primitiveColors.white,
|
|
177
225
|
"on-status-warning": primitiveColors.white,
|
|
178
226
|
"on-status-info": primitiveColors.white,
|
|
179
227
|
// Result/outcome indicators (result-*)
|
|
180
|
-
"result-improve":
|
|
228
|
+
"result-improve": resultPaletteColors.improve,
|
|
181
229
|
// Green - positive outcome
|
|
182
230
|
"result-improve-light": "rgba(76, 175, 80, 0.12)",
|
|
183
|
-
"result-improve-dark":
|
|
184
|
-
"result-degrade":
|
|
231
|
+
"result-improve-dark": resultPaletteColors.improveDark,
|
|
232
|
+
"result-degrade": resultPaletteColors.degrade,
|
|
185
233
|
// Red - negative outcome
|
|
186
234
|
"result-degrade-light": "rgba(239, 83, 80, 0.12)",
|
|
187
|
-
"result-degrade-dark":
|
|
188
|
-
"result-inconclusive":
|
|
235
|
+
"result-degrade-dark": resultPaletteColors.degradeDark,
|
|
236
|
+
"result-inconclusive": resultPaletteColors.inconclusive,
|
|
189
237
|
// Gray - no clear result
|
|
190
238
|
"result-inconclusive-light": "rgba(158, 154, 151, 0.12)",
|
|
191
239
|
"result-neutral": greyRamp[600],
|
|
@@ -217,8 +265,8 @@ var semanticColorsLight = {
|
|
|
217
265
|
"data-10": discreteRainbow[22],
|
|
218
266
|
// Dark Orange
|
|
219
267
|
// Text colors (text-*)
|
|
220
|
-
"text-primary":
|
|
221
|
-
"text-secondary":
|
|
268
|
+
"text-primary": semanticPins.textPrimaryLight,
|
|
269
|
+
"text-secondary": semanticPins.textSecondaryLight,
|
|
222
270
|
"text-tertiary": greyRamp[400],
|
|
223
271
|
"text-disabled": "rgba(55, 65, 81, 0.48)",
|
|
224
272
|
"text-inverse": primitiveColors.white,
|
|
@@ -234,7 +282,7 @@ var semanticColorsLight = {
|
|
|
234
282
|
"surface-input": greyRamp[50],
|
|
235
283
|
// Input field background (filled variant)
|
|
236
284
|
// Background colors (background-*)
|
|
237
|
-
"background-base":
|
|
285
|
+
"background-base": semanticPins.backgroundBaseLight,
|
|
238
286
|
"background-default": primitiveColors.white,
|
|
239
287
|
"background-subtle": greyRamp[50],
|
|
240
288
|
// Frame/bezel chrome — top bar + side nav shell, one step below
|
|
@@ -265,7 +313,7 @@ var semanticColorsLight = {
|
|
|
265
313
|
"interactive-disabled": "rgba(55, 65, 81, 0.12)",
|
|
266
314
|
"interactive-disabled-text": "rgba(55, 65, 81, 0.26)",
|
|
267
315
|
// Divider
|
|
268
|
-
|
|
316
|
+
divider: semanticPins.dividerLight,
|
|
269
317
|
// Avatar default
|
|
270
318
|
"avatar-background": greyRamp[600],
|
|
271
319
|
"avatar-text": primitiveColors.white
|
|
@@ -276,54 +324,87 @@ var semanticColorsDark = {
|
|
|
276
324
|
"brand-primary-light": primitiveRamps.orange[300],
|
|
277
325
|
"brand-primary-dark": primitiveRamps.orange[500],
|
|
278
326
|
"brand-primary-subtle": "rgba(255, 121, 0, 0.12)",
|
|
327
|
+
"brand-primary-muted": "rgba(255, 121, 0, 0.30)",
|
|
328
|
+
"brand-primary-strong": "rgba(255, 121, 0, 0.50)",
|
|
279
329
|
"brand-primary-hover": primitiveRamps.orange[300],
|
|
280
330
|
"brand-primary-active": primitiveRamps.orange[200],
|
|
281
331
|
"brand-secondary": primitiveRamps.cyan[600],
|
|
282
332
|
"brand-secondary-light": primitiveRamps.cyan[500],
|
|
283
333
|
"brand-secondary-dark": primitiveRamps.cyan[700],
|
|
284
|
-
"brand-secondary-subtle": "rgba(
|
|
334
|
+
"brand-secondary-subtle": "rgba(34, 211, 238, 0.12)",
|
|
335
|
+
"brand-secondary-muted": "rgba(48, 123, 155, 0.30)",
|
|
336
|
+
"brand-secondary-strong": "rgba(48, 123, 155, 0.50)",
|
|
285
337
|
"brand-secondary-hover": primitiveRamps.cyan[500],
|
|
286
338
|
"brand-secondary-active": primitiveRamps.cyan[400],
|
|
287
339
|
// Text on brand backgrounds
|
|
288
340
|
"on-brand-primary": primitiveColors.white,
|
|
289
341
|
"on-brand-secondary": primitiveColors.white,
|
|
342
|
+
// Text ON a `-subtle` fill. Its own role: `brand-primary` and friends are tuned to
|
|
343
|
+
// carry a white label as a solid fill, which makes the two deepest of them
|
|
344
|
+
// (cyan[600], red[600]) too dark to read as text on a dark plane. Levelling the
|
|
345
|
+
// family at rung 300 puts every tone within OKLCH L 0.769-0.813 instead of
|
|
346
|
+
// 0.550-0.813. Brand is deliberately left at its own orange[400] (operator, AW-133)
|
|
347
|
+
// so the Voltras tone never drifts; it is the one tone under AA on a raised card.
|
|
348
|
+
"on-brand-primary-subtle": primitiveRamps.orange[400],
|
|
349
|
+
"on-brand-secondary-subtle": primitiveRamps.cyan[300],
|
|
290
350
|
// Status colors
|
|
291
351
|
"status-success": primitiveRamps.green[300],
|
|
292
352
|
"status-success-light": primitiveRamps.green[200],
|
|
293
353
|
"status-success-dark": primitiveRamps.green[600],
|
|
294
354
|
"status-success-subtle": "rgba(46, 213, 115, 0.12)",
|
|
355
|
+
"status-success-muted": "rgba(46, 213, 115, 0.30)",
|
|
356
|
+
"status-success-strong": "rgba(46, 213, 115, 0.50)",
|
|
295
357
|
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
296
358
|
"status-live": primitiveRamps.green[300],
|
|
297
359
|
"status-live-muted": primitiveRamps.green[500],
|
|
298
360
|
"status-error": primitiveRamps.red[600],
|
|
299
361
|
"status-error-light": primitiveRamps.red[500],
|
|
300
362
|
"status-error-dark": primitiveRamps.red[700],
|
|
301
|
-
|
|
302
|
-
|
|
363
|
+
// Alpha 0.08, not the family's 0.12: error's label is red[400], a rung darker than
|
|
364
|
+
// its siblings so it reads RED rather than pink (rung 300 has only 0.121 chroma).
|
|
365
|
+
// Thinning the fill buys back the contrast that extra darkness costs. See AW-133.
|
|
366
|
+
"status-error-subtle": "rgba(247, 113, 117, 0.08)",
|
|
367
|
+
"status-error-muted": "rgba(209, 67, 67, 0.30)",
|
|
368
|
+
"status-error-strong": "rgba(209, 67, 67, 0.50)",
|
|
369
|
+
"status-error-vivid": alertRedVivid,
|
|
303
370
|
"status-error-vivid-light": primitiveRamps.red[500],
|
|
304
371
|
"status-error-vivid-dark": primitiveRamps.red[700],
|
|
305
372
|
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
373
|
+
"status-error-vivid-muted": "rgba(255, 71, 87, 0.30)",
|
|
374
|
+
"status-error-vivid-strong": "rgba(255, 71, 87, 0.50)",
|
|
306
375
|
"status-warning": primitiveRamps.amber[300],
|
|
307
376
|
"status-warning-light": primitiveRamps.amber[200],
|
|
308
377
|
"status-warning-dark": primitiveRamps.amber[500],
|
|
309
378
|
"status-warning-subtle": "rgba(249, 180, 21, 0.12)",
|
|
379
|
+
"status-warning-muted": "rgba(249, 180, 21, 0.30)",
|
|
380
|
+
"status-warning-strong": "rgba(249, 180, 21, 0.50)",
|
|
310
381
|
"status-info": primitiveRamps.blue[500],
|
|
311
382
|
"status-info-light": primitiveRamps.blue[300],
|
|
312
383
|
"status-info-dark": primitiveRamps.blue[600],
|
|
313
|
-
"status-info-subtle": "rgba(
|
|
384
|
+
"status-info-subtle": "rgba(120, 194, 255, 0.12)",
|
|
385
|
+
"status-info-muted": "rgba(33, 150, 243, 0.30)",
|
|
386
|
+
"status-info-strong": "rgba(33, 150, 243, 0.50)",
|
|
314
387
|
// Text on status backgrounds
|
|
315
388
|
"on-status-success": primitiveColors.white,
|
|
316
389
|
"on-status-error": primitiveColors.white,
|
|
317
390
|
"on-status-warning": primitiveColors.white,
|
|
318
391
|
"on-status-info": primitiveColors.white,
|
|
392
|
+
// Text ON a `-subtle` fill — see the on-brand-*-subtle note above. Error is the
|
|
393
|
+
// second deliberate exception to the rung-300 rule (operator, AW-133): red[300]
|
|
394
|
+
// levelled perfectly but read PINK, because a red that light can only hold 0.121
|
|
395
|
+
// chroma. red[400] carries 0.165 and reads red; its fill is thinned to compensate.
|
|
396
|
+
"on-status-success-subtle": primitiveRamps.green[300],
|
|
397
|
+
"on-status-error-subtle": primitiveRamps.red[400],
|
|
398
|
+
"on-status-warning-subtle": primitiveRamps.amber[300],
|
|
399
|
+
"on-status-info-subtle": primitiveRamps.blue[300],
|
|
319
400
|
// Result/outcome indicators (result-*)
|
|
320
|
-
"result-improve":
|
|
401
|
+
"result-improve": resultPaletteColors.improve,
|
|
321
402
|
"result-improve-light": "rgba(76, 175, 80, 0.16)",
|
|
322
|
-
"result-improve-dark":
|
|
323
|
-
"result-degrade":
|
|
403
|
+
"result-improve-dark": resultPaletteColors.improveDark,
|
|
404
|
+
"result-degrade": resultPaletteColors.degrade,
|
|
324
405
|
"result-degrade-light": "rgba(239, 83, 80, 0.16)",
|
|
325
|
-
"result-degrade-dark":
|
|
326
|
-
"result-inconclusive":
|
|
406
|
+
"result-degrade-dark": resultPaletteColors.degradeDark,
|
|
407
|
+
"result-inconclusive": resultPaletteColors.inconclusive,
|
|
327
408
|
"result-inconclusive-light": "rgba(158, 154, 151, 0.16)",
|
|
328
409
|
"result-neutral": greyRamp[400],
|
|
329
410
|
// Text on result backgrounds
|
|
@@ -354,7 +435,7 @@ var semanticColorsDark = {
|
|
|
354
435
|
"text-tertiary": greyRamp[500],
|
|
355
436
|
"text-disabled": "rgba(255, 255, 255, 0.38)",
|
|
356
437
|
"text-inverse": greyRamp[950],
|
|
357
|
-
"text-link":
|
|
438
|
+
"text-link": semanticPins.focusIndigoDark,
|
|
358
439
|
"text-link-hover": primitiveRamps.blue[400],
|
|
359
440
|
// Surface colors - dark backgrounds — warm-tapered DERIVED ramp (TD-surface-tokens,
|
|
360
441
|
// S-1, re-spaced S-3). Shipped verbatim from `deriveSurfaceRamp()` — see
|
|
@@ -404,10 +485,10 @@ var semanticColorsDark = {
|
|
|
404
485
|
// plane, so it keeps its job without collision.
|
|
405
486
|
"border-prominent": greyRamp[800],
|
|
406
487
|
// high-visibility divider
|
|
407
|
-
"border-focus":
|
|
488
|
+
"border-focus": semanticPins.focusIndigoDark,
|
|
408
489
|
"border-input": greyRamp[700],
|
|
409
490
|
"border-input-hover": greyRamp[600],
|
|
410
|
-
"border-input-focus":
|
|
491
|
+
"border-input-focus": semanticPins.focusIndigoDark,
|
|
411
492
|
"border-input-error": primitiveRamps.red[500],
|
|
412
493
|
// Alpha hairline separators — the primary separation cue (§4/S-2). Self-
|
|
413
494
|
// normalizing: composites toward white by ~the same amount on ANY plane, so
|
|
@@ -450,7 +531,7 @@ var semanticColorsDark = {
|
|
|
450
531
|
"interactive-disabled": "rgba(255, 255, 255, 0.12)",
|
|
451
532
|
"interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
|
|
452
533
|
// Divider
|
|
453
|
-
|
|
534
|
+
divider: "rgba(255, 255, 255, 0.09)",
|
|
454
535
|
// Avatar default
|
|
455
536
|
"avatar-background": greyRamp[700],
|
|
456
537
|
"avatar-text": primitiveColors.white
|
|
@@ -464,6 +545,182 @@ function resolveColor(token, mode = "dark") {
|
|
|
464
545
|
return Platform.OS === "web" ? `var(--color-${token})` : getSemanticColors(mode)[token];
|
|
465
546
|
}
|
|
466
547
|
|
|
548
|
+
// src/theme/color-utils.ts
|
|
549
|
+
function hexToRgb(hex) {
|
|
550
|
+
const cleaned = hex.replace("#", "");
|
|
551
|
+
let r, g, b;
|
|
552
|
+
if (cleaned.length === 3) {
|
|
553
|
+
r = parseInt(cleaned[0] + cleaned[0], 16);
|
|
554
|
+
g = parseInt(cleaned[1] + cleaned[1], 16);
|
|
555
|
+
b = parseInt(cleaned[2] + cleaned[2], 16);
|
|
556
|
+
} else if (cleaned.length === 6) {
|
|
557
|
+
r = parseInt(cleaned.slice(0, 2), 16);
|
|
558
|
+
g = parseInt(cleaned.slice(2, 4), 16);
|
|
559
|
+
b = parseInt(cleaned.slice(4, 6), 16);
|
|
560
|
+
} else {
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
return { r, g, b };
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/utils/colors.ts
|
|
567
|
+
function alpha(color, opacity) {
|
|
568
|
+
const clampedOpacity = Math.max(0, Math.min(1, opacity));
|
|
569
|
+
if (color.startsWith("#")) {
|
|
570
|
+
const hex = color.slice(1);
|
|
571
|
+
let r, g, b;
|
|
572
|
+
if (hex.length === 3) {
|
|
573
|
+
r = parseInt(hex[0] + hex[0], 16);
|
|
574
|
+
g = parseInt(hex[1] + hex[1], 16);
|
|
575
|
+
b = parseInt(hex[2] + hex[2], 16);
|
|
576
|
+
} else if (hex.length === 6) {
|
|
577
|
+
r = parseInt(hex.slice(0, 2), 16);
|
|
578
|
+
g = parseInt(hex.slice(2, 4), 16);
|
|
579
|
+
b = parseInt(hex.slice(4, 6), 16);
|
|
580
|
+
} else {
|
|
581
|
+
return color;
|
|
582
|
+
}
|
|
583
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
584
|
+
}
|
|
585
|
+
const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
586
|
+
if (rgbMatch) {
|
|
587
|
+
const [, r, g, b] = rgbMatch;
|
|
588
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
589
|
+
}
|
|
590
|
+
const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
|
|
591
|
+
if (rgbaMatch) {
|
|
592
|
+
const [, r, g, b] = rgbaMatch;
|
|
593
|
+
return `rgba(${r}, ${g}, ${b}, ${clampedOpacity})`;
|
|
594
|
+
}
|
|
595
|
+
return color;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// src/theme/materials.ts
|
|
599
|
+
var c = getSemanticColors("dark");
|
|
600
|
+
function insetWell(tone = c["surface-input"]) {
|
|
601
|
+
return {
|
|
602
|
+
backgroundColor: tone,
|
|
603
|
+
boxShadow: "inset 0 2px 6px rgba(0,0,0,0.55), inset 0 -1px 0 rgba(255,255,255,0.12)"
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
var FLOATING_LIFT_MIN = 4;
|
|
607
|
+
var LIFT_RIM_ALPHA = { dark: 0.12, light: 0.9 };
|
|
608
|
+
var AMBIENT = {
|
|
609
|
+
1: [
|
|
610
|
+
{ y: 1, blur: 2, alpha: 0.35 },
|
|
611
|
+
{ y: 2, blur: 6, alpha: 0.3 }
|
|
612
|
+
],
|
|
613
|
+
2: [
|
|
614
|
+
{ y: 1, blur: 2, alpha: 0.35 },
|
|
615
|
+
{ y: 4, blur: 12, alpha: 0.32 }
|
|
616
|
+
],
|
|
617
|
+
3: [
|
|
618
|
+
{ y: 2, blur: 4, alpha: 0.35 },
|
|
619
|
+
{ y: 8, blur: 22, alpha: 0.35 }
|
|
620
|
+
],
|
|
621
|
+
4: [
|
|
622
|
+
{ y: 1, blur: 2, alpha: 0.35 },
|
|
623
|
+
{ y: 10, blur: 24, alpha: 0.3 },
|
|
624
|
+
{ y: 24, blur: 48, alpha: 0.2 }
|
|
625
|
+
],
|
|
626
|
+
5: [
|
|
627
|
+
{ y: 2, blur: 4, alpha: 0.4 },
|
|
628
|
+
{ y: 16, blur: 32, alpha: 0.35 },
|
|
629
|
+
{ y: 32, blur: 64, alpha: 0.25 }
|
|
630
|
+
]
|
|
631
|
+
};
|
|
632
|
+
var AMBIENT_ALPHA_SCALE = { dark: 1, light: 0.4 };
|
|
633
|
+
function ambientLayers(step, mode) {
|
|
634
|
+
const scale = AMBIENT_ALPHA_SCALE[mode];
|
|
635
|
+
return AMBIENT[step].map(
|
|
636
|
+
({ y, blur, alpha: alpha2 }) => `0 ${y}px ${blur}px rgba(0,0,0,${(alpha2 * scale).toFixed(2)})`
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
function liftShadow(step, mode = "dark", opts = {}) {
|
|
640
|
+
const rim = opts.rim ?? LIFT_RIM_ALPHA[mode];
|
|
641
|
+
const layers = ambientLayers(step, mode);
|
|
642
|
+
if (rim > 0) layers.unshift(`inset 0 1px 0 rgba(255,255,255,${rim.toFixed(2)})`);
|
|
643
|
+
return layers.join(", ");
|
|
644
|
+
}
|
|
645
|
+
function liftStyle(step, mode = "dark", opts = {}) {
|
|
646
|
+
const deepest = AMBIENT[step][AMBIENT[step].length - 1];
|
|
647
|
+
return Platform.select({
|
|
648
|
+
web: { boxShadow: liftShadow(step, mode, opts) },
|
|
649
|
+
default: {
|
|
650
|
+
shadowColor: "#000",
|
|
651
|
+
shadowOffset: { width: 0, height: Math.round(deepest.y / 2) },
|
|
652
|
+
shadowOpacity: deepest.alpha * AMBIENT_ALPHA_SCALE[mode],
|
|
653
|
+
shadowRadius: deepest.blur / 2,
|
|
654
|
+
elevation: step
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// src/theme/surface-planes.ts
|
|
660
|
+
var SURFACE_LEVEL_TOKEN = {
|
|
661
|
+
frame: "background-frame",
|
|
662
|
+
background: "background-base",
|
|
663
|
+
base: "surface-base",
|
|
664
|
+
elevated: "surface-elevated",
|
|
665
|
+
raised: "surface-raised",
|
|
666
|
+
overlay: "surface-overlay"
|
|
667
|
+
};
|
|
668
|
+
var PLANE_ORDER = [
|
|
669
|
+
"frame",
|
|
670
|
+
"background",
|
|
671
|
+
"base",
|
|
672
|
+
"elevated",
|
|
673
|
+
"raised",
|
|
674
|
+
"overlay"
|
|
675
|
+
];
|
|
676
|
+
function surfaceBackground(level, mode) {
|
|
677
|
+
return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]];
|
|
678
|
+
}
|
|
679
|
+
function stepPlane(from, delta) {
|
|
680
|
+
const index = PLANE_ORDER.indexOf(from);
|
|
681
|
+
const clamped = Math.min(PLANE_ORDER.length - 1, Math.max(0, index + delta));
|
|
682
|
+
return PLANE_ORDER[clamped];
|
|
683
|
+
}
|
|
684
|
+
function pressedLevel(parent) {
|
|
685
|
+
return stepPlane(parent, -1);
|
|
686
|
+
}
|
|
687
|
+
function raisedLevel(parent, steps) {
|
|
688
|
+
return stepPlane(parent, Math.max(0, steps));
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// src/theme/elevation.ts
|
|
692
|
+
var FLOATING_ELEVATION_MIN = FLOATING_LIFT_MIN;
|
|
693
|
+
function getPressedRecessShadow(fillColor, _mode = "dark") {
|
|
694
|
+
const { boxShadow } = insetWell(fillColor);
|
|
695
|
+
return Platform.select({
|
|
696
|
+
web: { boxShadow },
|
|
697
|
+
default: {}
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
var glowConfig = {
|
|
701
|
+
tight: { blur: 4, spread: 0, opacity: 0.4 },
|
|
702
|
+
subtle: { blur: 12, spread: 0, opacity: 0.25 },
|
|
703
|
+
medium: { blur: 20, spread: 2, opacity: 0.4 },
|
|
704
|
+
strong: { blur: 30, spread: 4, opacity: 0.55 }
|
|
705
|
+
};
|
|
706
|
+
function getGlowShadow(color, intensity = "medium") {
|
|
707
|
+
const config = glowConfig[intensity];
|
|
708
|
+
const rgb = hexToRgb(color);
|
|
709
|
+
if (!rgb) return {};
|
|
710
|
+
return Platform.select({
|
|
711
|
+
web: {
|
|
712
|
+
boxShadow: `0 0 ${config.blur}px ${config.spread}px rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${config.opacity})`
|
|
713
|
+
},
|
|
714
|
+
default: {
|
|
715
|
+
shadowColor: color,
|
|
716
|
+
shadowOffset: { width: 0, height: 0 },
|
|
717
|
+
shadowOpacity: config.opacity,
|
|
718
|
+
shadowRadius: config.blur / 2,
|
|
719
|
+
elevation: 0
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
|
|
467
724
|
// src/theme/workout-tokens.ts
|
|
468
725
|
var WORKOUT_TOKENS = {
|
|
469
726
|
// BodyMap volume heatmap — the canonical `divergingScale` (under → optimal →
|
|
@@ -688,8 +945,8 @@ var jsxs = wrapJsx(jsxs$1);
|
|
|
688
945
|
// src/components/custom/Workout/BodyMap.tsx
|
|
689
946
|
var Body = BodyHighlighter.default ?? BodyHighlighter;
|
|
690
947
|
var BRAND_PRIMARY = getSemanticColors("dark")["brand-primary"];
|
|
691
|
-
var OUTLINE_FILL =
|
|
692
|
-
var OUTLINE_BORDER =
|
|
948
|
+
var OUTLINE_FILL = alpha(primitiveColors.white, 0.08);
|
|
949
|
+
var OUTLINE_BORDER = alpha(primitiveColors.white, 0.12);
|
|
693
950
|
var BODY_SCALE = 0.8;
|
|
694
951
|
function buildSlugParts(data) {
|
|
695
952
|
const bySlug = /* @__PURE__ */ new Map();
|
|
@@ -791,7 +1048,8 @@ function BodyMap({
|
|
|
791
1048
|
alignSelf: "center",
|
|
792
1049
|
transform: [{ scale }]
|
|
793
1050
|
},
|
|
794
|
-
|
|
1051
|
+
// The highlight halo is emphasis, not depth.
|
|
1052
|
+
glowColor ? getGlowShadow(glowColor, "medium") : void 0
|
|
795
1053
|
],
|
|
796
1054
|
"aria-hidden": true,
|
|
797
1055
|
accessibilityElementsHidden: true,
|
|
@@ -864,7 +1122,7 @@ function ViewToggle({ view, onViewChange }) {
|
|
|
864
1122
|
paddingHorizontal: 12,
|
|
865
1123
|
paddingVertical: 4,
|
|
866
1124
|
borderRadius: 9999,
|
|
867
|
-
backgroundColor: active ?
|
|
1125
|
+
backgroundColor: active ? alpha(BRAND_PRIMARY, 0.16) : "transparent",
|
|
868
1126
|
borderWidth: 1,
|
|
869
1127
|
borderColor: active ? BRAND_PRIMARY : resolveColor("hairline-strong")
|
|
870
1128
|
},
|
|
@@ -953,6 +1211,17 @@ var colorStyles = {
|
|
|
953
1211
|
info: "bg-status-info",
|
|
954
1212
|
"error-vivid": "bg-status-error-vivid"
|
|
955
1213
|
};
|
|
1214
|
+
var t = getSemanticColors("dark");
|
|
1215
|
+
var glowColors = {
|
|
1216
|
+
default: greyRamp[500],
|
|
1217
|
+
primary: t["brand-primary"],
|
|
1218
|
+
success: t["status-success"],
|
|
1219
|
+
live: t["status-live"],
|
|
1220
|
+
error: t["status-error"],
|
|
1221
|
+
warning: t["status-warning"],
|
|
1222
|
+
info: t["status-info"],
|
|
1223
|
+
"error-vivid": t["status-error-vivid"]
|
|
1224
|
+
};
|
|
956
1225
|
function Indicator({
|
|
957
1226
|
size = "sm",
|
|
958
1227
|
color = "default",
|
|
@@ -990,11 +1259,7 @@ function Indicator({
|
|
|
990
1259
|
)
|
|
991
1260
|
] });
|
|
992
1261
|
}
|
|
993
|
-
const
|
|
994
|
-
...typeof style === "object" ? style : {},
|
|
995
|
-
...colorStyle ?? {},
|
|
996
|
-
...glow && customColor ? { boxShadow: `0 0 6px ${customColor}` } : {}
|
|
997
|
-
};
|
|
1262
|
+
const glowStyle = glow ? getGlowShadow(customColor ?? glowColors[color], "subtle") : null;
|
|
998
1263
|
return /* @__PURE__ */ jsx(
|
|
999
1264
|
View,
|
|
1000
1265
|
{
|
|
@@ -1004,54 +1269,168 @@ function Indicator({
|
|
|
1004
1269
|
colorClass,
|
|
1005
1270
|
pulseMode === "opacity" && "animate-pulse",
|
|
1006
1271
|
ring && "border-2 border-background-base",
|
|
1007
|
-
glow && !customColor && (color === "success" || color === "live") && "shadow-[0_0_6px_rgba(46,213,115,0.6)]",
|
|
1008
|
-
glow && !customColor && color === "error" && "shadow-[0_0_6px_rgba(239,68,68,0.6)]",
|
|
1009
|
-
glow && !customColor && color === "warning" && "shadow-[0_0_6px_rgba(245,158,11,0.6)]",
|
|
1010
|
-
glow && !customColor && color === "primary" && "shadow-[0_0_6px_rgba(255,121,0,0.6)]",
|
|
1011
|
-
glow && !customColor && color === "error-vivid" && "shadow-[0_0_6px_rgba(255,71,87,0.6)]",
|
|
1012
1272
|
className
|
|
1013
1273
|
),
|
|
1014
|
-
style:
|
|
1274
|
+
style: [style, colorStyle, glowStyle],
|
|
1015
1275
|
...props
|
|
1016
1276
|
}
|
|
1017
1277
|
);
|
|
1018
1278
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1279
|
+
var colorToTone = {
|
|
1280
|
+
default: "neutral",
|
|
1281
|
+
primary: "brand",
|
|
1282
|
+
secondary: "brand-secondary",
|
|
1283
|
+
success: "success",
|
|
1284
|
+
error: "error",
|
|
1285
|
+
warning: "warning",
|
|
1286
|
+
info: "info"
|
|
1287
|
+
};
|
|
1288
|
+
var toneStyles = {
|
|
1022
1289
|
solid: {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
secondary: "bg-brand-secondary text-text-inverse",
|
|
1026
|
-
success: "bg-status-success text-text-inverse",
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
info: "bg-status-info text-text-inverse"
|
|
1290
|
+
neutral: "bg-hairline-strong border-transparent text-text-inverse",
|
|
1291
|
+
brand: "bg-brand-primary border-transparent text-text-inverse",
|
|
1292
|
+
"brand-secondary": "bg-brand-secondary border-transparent text-text-inverse",
|
|
1293
|
+
success: "bg-status-success border-transparent text-text-inverse",
|
|
1294
|
+
warning: "bg-status-warning border-transparent text-text-inverse",
|
|
1295
|
+
error: "bg-status-error border-transparent text-text-inverse",
|
|
1296
|
+
info: "bg-status-info border-transparent text-text-inverse"
|
|
1030
1297
|
},
|
|
1031
1298
|
subtle: {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1299
|
+
// Alpha-white rather than a ramp step: a pill sits on whatever plane its
|
|
1300
|
+
// host is, and an alpha fill composites by the same amount on all of them.
|
|
1301
|
+
// A `surface-*` fill would vanish on the plane it names. Borderless like the
|
|
1302
|
+
// six coloured tones — the fill carries the capsule, not a ring.
|
|
1303
|
+
// Label comes from `on-*-subtle`, not the base tone token: the base is tuned to
|
|
1304
|
+
// carry a white label as a solid fill, which left error and accent unreadable
|
|
1305
|
+
// here (AW-133). The on-subtle tokens level the family at one weight.
|
|
1306
|
+
neutral: "bg-hairline-subtle border-transparent text-text-secondary",
|
|
1307
|
+
brand: "bg-brand-primary-subtle border-transparent text-on-brand-primary-subtle",
|
|
1308
|
+
"brand-secondary": "bg-brand-secondary-subtle border-transparent text-on-brand-secondary-subtle",
|
|
1309
|
+
success: "bg-status-success-subtle border-transparent text-on-status-success-subtle",
|
|
1310
|
+
warning: "bg-status-warning-subtle border-transparent text-on-status-warning-subtle",
|
|
1311
|
+
error: "bg-status-error-subtle border-transparent text-on-status-error-subtle",
|
|
1312
|
+
info: "bg-status-info-subtle border-transparent text-on-status-info-subtle"
|
|
1039
1313
|
},
|
|
1040
1314
|
outline: {
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
secondary: "border
|
|
1044
|
-
success: "border
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
info: "border
|
|
1315
|
+
neutral: "border-hairline text-text-secondary",
|
|
1316
|
+
brand: "border-brand-primary text-brand-primary",
|
|
1317
|
+
"brand-secondary": "border-brand-secondary text-brand-secondary",
|
|
1318
|
+
success: "border-status-success text-status-success",
|
|
1319
|
+
warning: "border-status-warning text-status-warning",
|
|
1320
|
+
error: "border-status-error text-status-error",
|
|
1321
|
+
info: "border-status-info text-status-info"
|
|
1048
1322
|
}
|
|
1049
1323
|
};
|
|
1324
|
+
var dotToneStyles = {
|
|
1325
|
+
neutral: "bg-text-tertiary",
|
|
1326
|
+
brand: "bg-brand-primary",
|
|
1327
|
+
"brand-secondary": "bg-brand-secondary",
|
|
1328
|
+
success: "bg-status-success",
|
|
1329
|
+
warning: "bg-status-warning",
|
|
1330
|
+
error: "bg-status-error",
|
|
1331
|
+
info: "bg-status-info"
|
|
1332
|
+
};
|
|
1050
1333
|
var sizeStyles2 = {
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1334
|
+
xs: { container: "px-1 py-px", text: "text-3xs" },
|
|
1335
|
+
sm: { container: "px-2 py-0.5", text: "text-2xs" },
|
|
1336
|
+
md: { container: "px-2.5 py-1", text: "text-xs" },
|
|
1337
|
+
lg: { container: "px-3 py-1.5", text: "text-sm" },
|
|
1338
|
+
xl: { container: "px-4 py-2", text: "text-base" }
|
|
1339
|
+
};
|
|
1340
|
+
function PillDot({ tone, testID }) {
|
|
1341
|
+
return /* @__PURE__ */ jsx(
|
|
1342
|
+
View,
|
|
1343
|
+
{
|
|
1344
|
+
className: cn("w-1.5 h-1.5 rounded-full shrink-0", dotToneStyles[tone]),
|
|
1345
|
+
accessibilityElementsHidden: true,
|
|
1346
|
+
testID: testID ? `${testID}-dot` : "pill-dot"
|
|
1347
|
+
}
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
function containerClasses(p, tone) {
|
|
1351
|
+
return cn(
|
|
1352
|
+
"flex-row items-center gap-1 border self-start shrink-0",
|
|
1353
|
+
p.rounded === false ? "rounded" : "rounded-full",
|
|
1354
|
+
toneStyles[p.variant ?? "subtle"][tone],
|
|
1355
|
+
sizeStyles2[p.size ?? "sm"].container,
|
|
1356
|
+
p.isDisabled && "opacity-50",
|
|
1357
|
+
p.className
|
|
1358
|
+
);
|
|
1359
|
+
}
|
|
1360
|
+
function PillContent({ tone, ...p }) {
|
|
1361
|
+
const textClasses = cn(
|
|
1362
|
+
"font-heading font-semibold text-inherit",
|
|
1363
|
+
sizeStyles2[p.size ?? "sm"].text,
|
|
1364
|
+
p.textClassName
|
|
1365
|
+
);
|
|
1366
|
+
const slot = p.leading ?? p.leftElement;
|
|
1367
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1368
|
+
slot === "dot" ? /* @__PURE__ */ jsx(PillDot, { tone: p.dotTone ?? tone, testID: p.testID }) : slot,
|
|
1369
|
+
typeof p.children === "string" ? /* @__PURE__ */ jsx(Text, { className: textClasses, children: p.children }) : p.children,
|
|
1370
|
+
p.trailing
|
|
1371
|
+
] });
|
|
1372
|
+
}
|
|
1373
|
+
function Pill(props) {
|
|
1374
|
+
const {
|
|
1375
|
+
variant,
|
|
1376
|
+
tone,
|
|
1377
|
+
color,
|
|
1378
|
+
size,
|
|
1379
|
+
rounded,
|
|
1380
|
+
leading,
|
|
1381
|
+
dotTone,
|
|
1382
|
+
leftElement,
|
|
1383
|
+
trailing,
|
|
1384
|
+
onPress,
|
|
1385
|
+
isDisabled,
|
|
1386
|
+
className,
|
|
1387
|
+
textClassName,
|
|
1388
|
+
children,
|
|
1389
|
+
...viewProps
|
|
1390
|
+
} = props;
|
|
1391
|
+
const resolvedTone = tone ?? (color ? colorToTone[color] : "neutral");
|
|
1392
|
+
const classes = containerClasses(props, resolvedTone);
|
|
1393
|
+
const content = /* @__PURE__ */ jsx(PillContent, { ...props, tone: resolvedTone });
|
|
1394
|
+
if (onPress) {
|
|
1395
|
+
return /* @__PURE__ */ jsx(
|
|
1396
|
+
Pressable,
|
|
1397
|
+
{
|
|
1398
|
+
onPress,
|
|
1399
|
+
disabled: isDisabled,
|
|
1400
|
+
accessibilityRole: "button",
|
|
1401
|
+
className: classes,
|
|
1402
|
+
...viewProps,
|
|
1403
|
+
children: content
|
|
1404
|
+
}
|
|
1405
|
+
);
|
|
1406
|
+
}
|
|
1407
|
+
return /* @__PURE__ */ jsx(View, { className: classes, ...viewProps, children: content });
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
// src/components/ui/badge/Badge.tsx
|
|
1411
|
+
var colorToTone2 = {
|
|
1412
|
+
default: "neutral",
|
|
1413
|
+
primary: "brand",
|
|
1414
|
+
secondary: "brand-secondary",
|
|
1415
|
+
success: "success",
|
|
1416
|
+
error: "error",
|
|
1417
|
+
warning: "warning",
|
|
1418
|
+
info: "info"
|
|
1419
|
+
};
|
|
1420
|
+
var sizeStyles3 = {
|
|
1421
|
+
sm: "px-1.5 py-0.5",
|
|
1422
|
+
md: "px-2 py-0.5",
|
|
1423
|
+
lg: "px-2.5 py-1"
|
|
1054
1424
|
};
|
|
1425
|
+
var textSizeStyles = {
|
|
1426
|
+
sm: "text-xs",
|
|
1427
|
+
md: "text-xs",
|
|
1428
|
+
lg: "text-sm"
|
|
1429
|
+
};
|
|
1430
|
+
function dotIndicatorColor(color, dotColor) {
|
|
1431
|
+
if (dotColor) return dotColor;
|
|
1432
|
+
return color === "default" || color === "secondary" ? "default" : color;
|
|
1433
|
+
}
|
|
1055
1434
|
function Badge({
|
|
1056
1435
|
variant = "subtle",
|
|
1057
1436
|
color = "default",
|
|
@@ -1062,31 +1441,116 @@ function Badge({
|
|
|
1062
1441
|
children,
|
|
1063
1442
|
...props
|
|
1064
1443
|
}) {
|
|
1065
|
-
return /* @__PURE__ */
|
|
1066
|
-
|
|
1444
|
+
return /* @__PURE__ */ jsx(
|
|
1445
|
+
Pill,
|
|
1067
1446
|
{
|
|
1447
|
+
variant,
|
|
1448
|
+
tone: colorToTone2[color],
|
|
1449
|
+
leading: dot ? /* @__PURE__ */ jsx(Indicator, { size: "xs", color: dotIndicatorColor(color, dotColor), className: "mr-0.5" }) : void 0,
|
|
1068
1450
|
className: cn(
|
|
1069
|
-
"
|
|
1070
|
-
|
|
1071
|
-
|
|
1451
|
+
"justify-center self-auto gap-0",
|
|
1452
|
+
variant === "outline" ? "border" : "border-0",
|
|
1453
|
+
sizeStyles3[size],
|
|
1072
1454
|
className
|
|
1073
1455
|
),
|
|
1456
|
+
textClassName: cn("font-sans font-medium", textSizeStyles[size]),
|
|
1074
1457
|
...props,
|
|
1075
|
-
children
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1458
|
+
children
|
|
1459
|
+
}
|
|
1460
|
+
);
|
|
1461
|
+
}
|
|
1462
|
+
var variantStyles = {
|
|
1463
|
+
h1: "font-heading text-5xl font-bold leading-tight",
|
|
1464
|
+
h2: "font-heading text-4xl font-bold leading-tight",
|
|
1465
|
+
h3: "font-heading text-3xl font-bold leading-tight",
|
|
1466
|
+
h4: "font-heading text-2xl font-bold leading-tight",
|
|
1467
|
+
h5: "font-heading text-xl font-semibold leading-tight",
|
|
1468
|
+
h6: "font-heading text-lg font-semibold leading-tight",
|
|
1469
|
+
body1: "font-body text-base font-normal leading-normal",
|
|
1470
|
+
body2: "font-body text-sm font-normal leading-normal",
|
|
1471
|
+
subtitle1: "font-body text-base font-medium leading-relaxed",
|
|
1472
|
+
subtitle2: "font-body text-sm font-medium leading-normal",
|
|
1473
|
+
caption: "font-body text-xs font-normal leading-loose",
|
|
1474
|
+
overline: "font-body text-xs font-semibold uppercase tracking-widest leading-relaxed",
|
|
1475
|
+
button: "font-sans text-sm font-semibold leading-relaxed",
|
|
1476
|
+
// Monospace technical readouts (clocks, ids, metrics) and their all-caps label form.
|
|
1477
|
+
mono: "font-mono text-xs font-normal leading-normal",
|
|
1478
|
+
monoLabel: "font-mono text-xs font-bold uppercase tracking-wide leading-normal",
|
|
1479
|
+
// The sans (Inter) label pair: 10px for dense table/column headers, 12px bold for
|
|
1480
|
+
// badge and row labels. `overline` is the 12px font-body form of the same idea.
|
|
1481
|
+
microLabel: "font-sans text-2xs font-semibold uppercase tracking-widest leading-normal",
|
|
1482
|
+
boldLabel: "font-sans text-xs font-bold leading-normal"
|
|
1483
|
+
};
|
|
1484
|
+
var colorStyles2 = {
|
|
1485
|
+
primary: "text-text-primary",
|
|
1486
|
+
secondary: "text-text-secondary",
|
|
1487
|
+
tertiary: "text-text-tertiary",
|
|
1488
|
+
disabled: "text-text-disabled",
|
|
1489
|
+
inverse: "text-text-inverse",
|
|
1490
|
+
success: "text-status-success",
|
|
1491
|
+
error: "text-status-error",
|
|
1492
|
+
warning: "text-status-warning",
|
|
1493
|
+
info: "text-status-info",
|
|
1494
|
+
inherit: ""
|
|
1495
|
+
// No color class, inherit from parent
|
|
1496
|
+
};
|
|
1497
|
+
var alignStyles = {
|
|
1498
|
+
left: "text-left",
|
|
1499
|
+
center: "text-center",
|
|
1500
|
+
right: "text-right",
|
|
1501
|
+
justify: "text-justify"
|
|
1502
|
+
};
|
|
1503
|
+
var headingVariants = ["h1", "h2", "h3", "h4", "h5", "h6"];
|
|
1504
|
+
var marginBottomStyles = {
|
|
1505
|
+
none: "",
|
|
1506
|
+
sm: "mb-1",
|
|
1507
|
+
md: "mb-2",
|
|
1508
|
+
lg: "mb-4"
|
|
1509
|
+
};
|
|
1510
|
+
function Typography({
|
|
1511
|
+
variant = "body1",
|
|
1512
|
+
color = "primary",
|
|
1513
|
+
align,
|
|
1514
|
+
truncate = false,
|
|
1515
|
+
noWrap = false,
|
|
1516
|
+
// deprecated, kept for backward compatibility
|
|
1517
|
+
marginBottom,
|
|
1518
|
+
gutterBottom = false,
|
|
1519
|
+
// deprecated, kept for backward compatibility
|
|
1520
|
+
maxLines,
|
|
1521
|
+
className,
|
|
1522
|
+
children,
|
|
1523
|
+
...props
|
|
1524
|
+
}) {
|
|
1525
|
+
const isHeading = headingVariants.includes(variant);
|
|
1526
|
+
const shouldTruncate = truncate || noWrap;
|
|
1527
|
+
const mb = marginBottom || (gutterBottom ? "md" : "none");
|
|
1528
|
+
let numLines;
|
|
1529
|
+
if (maxLines) {
|
|
1530
|
+
numLines = maxLines;
|
|
1531
|
+
} else if (shouldTruncate) {
|
|
1532
|
+
numLines = 1;
|
|
1533
|
+
}
|
|
1534
|
+
return /* @__PURE__ */ jsx(
|
|
1535
|
+
Text,
|
|
1536
|
+
{
|
|
1537
|
+
accessibilityRole: isHeading ? "header" : "text",
|
|
1538
|
+
numberOfLines: numLines,
|
|
1539
|
+
className: cn(
|
|
1540
|
+
variantStyles[variant],
|
|
1541
|
+
color !== "inherit" && colorStyles2[color],
|
|
1542
|
+
align && alignStyles[align],
|
|
1543
|
+
shouldTruncate && "truncate",
|
|
1544
|
+
marginBottomStyles[mb],
|
|
1545
|
+
className
|
|
1546
|
+
),
|
|
1547
|
+
...props,
|
|
1548
|
+
children
|
|
1086
1549
|
}
|
|
1087
1550
|
);
|
|
1088
1551
|
}
|
|
1089
|
-
|
|
1552
|
+
|
|
1553
|
+
// src/components/custom/Workout/Sparkline.tsx
|
|
1090
1554
|
function normalizeData(data, height) {
|
|
1091
1555
|
if (data.length === 0) return [];
|
|
1092
1556
|
const min = Math.min(...data);
|
|
@@ -1123,7 +1587,7 @@ function Sparkline({
|
|
|
1123
1587
|
}
|
|
1124
1588
|
);
|
|
1125
1589
|
}
|
|
1126
|
-
const resolvedColor = color ??
|
|
1590
|
+
const resolvedColor = color ?? resolveColor("brand-primary");
|
|
1127
1591
|
const normalized = normalizeData(data, height);
|
|
1128
1592
|
const stepX = data.length > 1 ? width / (data.length - 1) : 0;
|
|
1129
1593
|
const dotSize = 3;
|
|
@@ -1163,14 +1627,19 @@ function Sparkline({
|
|
|
1163
1627
|
],
|
|
1164
1628
|
accessibilityElementsHidden: true,
|
|
1165
1629
|
testID: `sparkline-reference-${i}`,
|
|
1166
|
-
children: line.label &&
|
|
1167
|
-
|
|
1630
|
+
children: line.label && // `3xs` (9px) is the scale floor; the label was 7px, which is off it
|
|
1631
|
+
// entirely (TOKENS.md §4). The line box stays unpinned, as the raw
|
|
1632
|
+
// <Text> this replaced was, so the absolute offset still lands.
|
|
1633
|
+
/* @__PURE__ */ jsx(
|
|
1634
|
+
Typography,
|
|
1168
1635
|
{
|
|
1636
|
+
variant: "caption",
|
|
1637
|
+
color: "inherit",
|
|
1638
|
+
className: "text-3xs leading-[normal]",
|
|
1169
1639
|
style: {
|
|
1170
1640
|
position: "absolute",
|
|
1171
1641
|
right: 0,
|
|
1172
1642
|
top: -10,
|
|
1173
|
-
fontSize: 7,
|
|
1174
1643
|
color: line.color,
|
|
1175
1644
|
opacity: 1
|
|
1176
1645
|
},
|
|
@@ -1239,9 +1708,9 @@ function Sparkline({
|
|
|
1239
1708
|
}
|
|
1240
1709
|
|
|
1241
1710
|
// src/components/custom/Workout/BodyMapDetailPanel.tsx
|
|
1242
|
-
var
|
|
1243
|
-
var
|
|
1244
|
-
var VOLUME_GRADIENT = `linear-gradient(90deg, ${
|
|
1711
|
+
var t2 = getSemanticColors("dark");
|
|
1712
|
+
var BRAND_PRIMARY2 = t2["brand-primary"];
|
|
1713
|
+
var VOLUME_GRADIENT = `linear-gradient(90deg, ${t2["status-info"]} 0%, ${t2["status-success"]} 50%, ${t2["status-error"]} 100%)`;
|
|
1245
1714
|
var SLIDE_OFFSET = 400;
|
|
1246
1715
|
var BACKDROP_OPACITY = 0.4;
|
|
1247
1716
|
var STATUS_BADGE_COLOR = {
|
|
@@ -1306,7 +1775,14 @@ function BodyMapDetailPanel({
|
|
|
1306
1775
|
return /* @__PURE__ */ jsxs(
|
|
1307
1776
|
View,
|
|
1308
1777
|
{
|
|
1309
|
-
style: {
|
|
1778
|
+
style: {
|
|
1779
|
+
position: "absolute",
|
|
1780
|
+
top: 0,
|
|
1781
|
+
left: 0,
|
|
1782
|
+
right: 0,
|
|
1783
|
+
bottom: 0,
|
|
1784
|
+
justifyContent: "flex-end"
|
|
1785
|
+
},
|
|
1310
1786
|
testID: "body-map-detail-panel-root",
|
|
1311
1787
|
children: [
|
|
1312
1788
|
/* @__PURE__ */ jsx(
|
|
@@ -1318,7 +1794,7 @@ function BodyMapDetailPanel({
|
|
|
1318
1794
|
left: 0,
|
|
1319
1795
|
right: 0,
|
|
1320
1796
|
bottom: 0,
|
|
1321
|
-
backgroundColor:
|
|
1797
|
+
backgroundColor: primitiveColors.black,
|
|
1322
1798
|
opacity: backdrop
|
|
1323
1799
|
},
|
|
1324
1800
|
testID: "body-map-detail-panel-backdrop-anim",
|
|
@@ -1441,8 +1917,22 @@ function BodyMapDetailPanel({
|
|
|
1441
1917
|
style: { marginBottom: 6 },
|
|
1442
1918
|
accessibilityElementsHidden: true,
|
|
1443
1919
|
children: [
|
|
1444
|
-
/* @__PURE__ */ jsx(
|
|
1445
|
-
|
|
1920
|
+
/* @__PURE__ */ jsx(
|
|
1921
|
+
Text,
|
|
1922
|
+
{
|
|
1923
|
+
className: "text-text-tertiary",
|
|
1924
|
+
style: { fontSize: 10, fontFamily: "Inter, sans-serif", fontWeight: "600" },
|
|
1925
|
+
children: `MEV ${landmarks.mev}`
|
|
1926
|
+
}
|
|
1927
|
+
),
|
|
1928
|
+
/* @__PURE__ */ jsx(
|
|
1929
|
+
Text,
|
|
1930
|
+
{
|
|
1931
|
+
className: "text-text-tertiary",
|
|
1932
|
+
style: { fontSize: 10, fontFamily: "Inter, sans-serif", fontWeight: "600" },
|
|
1933
|
+
children: `MRV ${landmarks.mrv}`
|
|
1934
|
+
}
|
|
1935
|
+
)
|
|
1446
1936
|
]
|
|
1447
1937
|
}
|
|
1448
1938
|
),
|
|
@@ -1477,7 +1967,8 @@ function BodyMapDetailPanel({
|
|
|
1477
1967
|
height: 14,
|
|
1478
1968
|
borderRadius: 7,
|
|
1479
1969
|
borderWidth: 2,
|
|
1480
|
-
|
|
1970
|
+
// A knob resting on the volume bar: lift, with the ring as its edge.
|
|
1971
|
+
...liftStyle(1, "dark", { rim: 0 })
|
|
1481
1972
|
},
|
|
1482
1973
|
accessibilityElementsHidden: true,
|
|
1483
1974
|
testID: "body-map-detail-panel-volume-marker"
|
|
@@ -1560,7 +2051,12 @@ function BodyMapDetailPanel({
|
|
|
1560
2051
|
Text,
|
|
1561
2052
|
{
|
|
1562
2053
|
className: "text-text-primary",
|
|
1563
|
-
style: {
|
|
2054
|
+
style: {
|
|
2055
|
+
flex: 1,
|
|
2056
|
+
fontSize: 13,
|
|
2057
|
+
fontFamily: "Inter, sans-serif",
|
|
2058
|
+
fontWeight: "600"
|
|
2059
|
+
},
|
|
1564
2060
|
testID: `body-map-detail-panel-contributing-${index}-name`,
|
|
1565
2061
|
children: exercise.name
|
|
1566
2062
|
}
|
|
@@ -1604,7 +2100,12 @@ function BodyMapDetailPanel({
|
|
|
1604
2100
|
Text,
|
|
1605
2101
|
{
|
|
1606
2102
|
className: "text-text-primary",
|
|
1607
|
-
style: {
|
|
2103
|
+
style: {
|
|
2104
|
+
flex: 1,
|
|
2105
|
+
fontSize: 13,
|
|
2106
|
+
fontFamily: "Inter, sans-serif",
|
|
2107
|
+
fontWeight: "600"
|
|
2108
|
+
},
|
|
1608
2109
|
testID: `body-map-detail-panel-upcoming-${index}-name`,
|
|
1609
2110
|
children: exercise.name
|
|
1610
2111
|
}
|
|
@@ -1634,12 +2135,23 @@ function BodyMapDetailPanel({
|
|
|
1634
2135
|
paddingVertical: 10,
|
|
1635
2136
|
borderRadius: 8,
|
|
1636
2137
|
alignItems: "center",
|
|
1637
|
-
backgroundColor:
|
|
2138
|
+
backgroundColor: alpha(BRAND_PRIMARY2, 0.12),
|
|
1638
2139
|
borderWidth: 1,
|
|
1639
|
-
borderColor:
|
|
2140
|
+
borderColor: alpha(BRAND_PRIMARY2, 0.3)
|
|
1640
2141
|
},
|
|
1641
2142
|
testID: "body-map-detail-panel-view-exercises",
|
|
1642
|
-
children: /* @__PURE__ */ jsx(
|
|
2143
|
+
children: /* @__PURE__ */ jsx(
|
|
2144
|
+
Text,
|
|
2145
|
+
{
|
|
2146
|
+
style: {
|
|
2147
|
+
fontSize: 13,
|
|
2148
|
+
fontFamily: "Inter, sans-serif",
|
|
2149
|
+
fontWeight: "700",
|
|
2150
|
+
color: BRAND_PRIMARY2
|
|
2151
|
+
},
|
|
2152
|
+
children: "View exercises"
|
|
2153
|
+
}
|
|
2154
|
+
)
|
|
1643
2155
|
}
|
|
1644
2156
|
)
|
|
1645
2157
|
]
|
|
@@ -1652,439 +2164,81 @@ function BodyMapDetailPanel({
|
|
|
1652
2164
|
}
|
|
1653
2165
|
);
|
|
1654
2166
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
function
|
|
1658
|
-
|
|
1659
|
-
let r, g, b;
|
|
1660
|
-
if (cleaned.length === 3) {
|
|
1661
|
-
r = parseInt(cleaned[0] + cleaned[0], 16);
|
|
1662
|
-
g = parseInt(cleaned[1] + cleaned[1], 16);
|
|
1663
|
-
b = parseInt(cleaned[2] + cleaned[2], 16);
|
|
1664
|
-
} else if (cleaned.length === 6) {
|
|
1665
|
-
r = parseInt(cleaned.slice(0, 2), 16);
|
|
1666
|
-
g = parseInt(cleaned.slice(2, 4), 16);
|
|
1667
|
-
b = parseInt(cleaned.slice(4, 6), 16);
|
|
1668
|
-
} else {
|
|
1669
|
-
return null;
|
|
1670
|
-
}
|
|
1671
|
-
return { r, g, b };
|
|
1672
|
-
}
|
|
1673
|
-
function rgbToHsv(r, g, b) {
|
|
1674
|
-
const rNorm = r / 255;
|
|
1675
|
-
const gNorm = g / 255;
|
|
1676
|
-
const bNorm = b / 255;
|
|
1677
|
-
const max = Math.max(rNorm, gNorm, bNorm);
|
|
1678
|
-
const min = Math.min(rNorm, gNorm, bNorm);
|
|
1679
|
-
const delta = max - min;
|
|
1680
|
-
const v = max;
|
|
1681
|
-
const s = max === 0 ? 0 : delta / max;
|
|
1682
|
-
let h = 0;
|
|
1683
|
-
if (delta !== 0) {
|
|
1684
|
-
if (max === rNorm) {
|
|
1685
|
-
h = 60 * ((gNorm - bNorm) / delta % 6);
|
|
1686
|
-
} else if (max === gNorm) {
|
|
1687
|
-
h = 60 * ((bNorm - rNorm) / delta + 2);
|
|
1688
|
-
} else {
|
|
1689
|
-
h = 60 * ((rNorm - gNorm) / delta + 4);
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
if (h < 0) h += 360;
|
|
1693
|
-
return { h, s, v };
|
|
1694
|
-
}
|
|
1695
|
-
function hsvToRgb(h, s, v) {
|
|
1696
|
-
const c = v * s;
|
|
1697
|
-
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
1698
|
-
const m = v - c;
|
|
1699
|
-
let rPrime, gPrime, bPrime;
|
|
1700
|
-
if (h >= 0 && h < 60) {
|
|
1701
|
-
rPrime = c;
|
|
1702
|
-
gPrime = x;
|
|
1703
|
-
bPrime = 0;
|
|
1704
|
-
} else if (h >= 60 && h < 120) {
|
|
1705
|
-
rPrime = x;
|
|
1706
|
-
gPrime = c;
|
|
1707
|
-
bPrime = 0;
|
|
1708
|
-
} else if (h >= 120 && h < 180) {
|
|
1709
|
-
rPrime = 0;
|
|
1710
|
-
gPrime = c;
|
|
1711
|
-
bPrime = x;
|
|
1712
|
-
} else if (h >= 180 && h < 240) {
|
|
1713
|
-
rPrime = 0;
|
|
1714
|
-
gPrime = x;
|
|
1715
|
-
bPrime = c;
|
|
1716
|
-
} else if (h >= 240 && h < 300) {
|
|
1717
|
-
rPrime = x;
|
|
1718
|
-
gPrime = 0;
|
|
1719
|
-
bPrime = c;
|
|
1720
|
-
} else {
|
|
1721
|
-
rPrime = c;
|
|
1722
|
-
gPrime = 0;
|
|
1723
|
-
bPrime = x;
|
|
1724
|
-
}
|
|
1725
|
-
return {
|
|
1726
|
-
r: Math.round((rPrime + m) * 255),
|
|
1727
|
-
g: Math.round((gPrime + m) * 255),
|
|
1728
|
-
b: Math.round((bPrime + m) * 255)
|
|
1729
|
-
};
|
|
1730
|
-
}
|
|
1731
|
-
function rgbToHex(r, g, b) {
|
|
1732
|
-
const toHex = (n) => {
|
|
1733
|
-
const clamped = Math.max(0, Math.min(255, Math.round(n)));
|
|
1734
|
-
return clamped.toString(16).padStart(2, "0");
|
|
1735
|
-
};
|
|
1736
|
-
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
1737
|
-
}
|
|
1738
|
-
function lighten(hex, amount = 0.1) {
|
|
1739
|
-
const rgb = hexToRgb(hex);
|
|
1740
|
-
if (!rgb) return hex;
|
|
1741
|
-
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
1742
|
-
const newV = Math.min(1, hsv.v + amount);
|
|
1743
|
-
const newRgb = hsvToRgb(hsv.h, hsv.s, newV);
|
|
1744
|
-
return rgbToHex(newRgb.r, newRgb.g, newRgb.b);
|
|
1745
|
-
}
|
|
1746
|
-
var elevationSystem = {
|
|
1747
|
-
// Deep inset (recessed input fields, deeply pressed buttons)
|
|
1748
|
-
[-2]: {
|
|
1749
|
-
name: "deep-inset",
|
|
1750
|
-
colorAdjustment: 0,
|
|
1751
|
-
shadowIntensity: "strong",
|
|
1752
|
-
shadowStyle: "pressed",
|
|
1753
|
-
description: "Deeply recessed elements (e.g., input fields, deeply pressed buttons)"
|
|
1754
|
-
},
|
|
1755
|
-
// Shallow inset (pressed buttons, sunken panels)
|
|
1756
|
-
[-1]: {
|
|
1757
|
-
name: "inset",
|
|
1758
|
-
colorAdjustment: 0,
|
|
1759
|
-
shadowIntensity: "medium",
|
|
1760
|
-
shadowStyle: "pressed",
|
|
1761
|
-
description: "Shallow inset elements (e.g., pressed buttons, sunken panels within cards)"
|
|
1762
|
-
},
|
|
1763
|
-
// Base level (page background, default surface)
|
|
1764
|
-
[0]: {
|
|
1765
|
-
name: "base",
|
|
1766
|
-
colorAdjustment: 0,
|
|
1767
|
-
shadowIntensity: "subtle",
|
|
1768
|
-
shadowStyle: "raised",
|
|
1769
|
-
description: "Base surface level (page background, default containers)"
|
|
1770
|
-
},
|
|
1771
|
-
// Level 1: Subtle elevation (outline cards, subtle containers)
|
|
1772
|
-
[1]: {
|
|
1773
|
-
name: "subtle",
|
|
1774
|
-
// The whole ladder was re-spaced in TD-07.16. It used to run
|
|
1775
|
-
// 0.01/0.02/0.04/0.06/0.08, where the first step was ~2 RGB values — under
|
|
1776
|
-
// the perceptual floor, so level 1 existed in the type system and nowhere on
|
|
1777
|
-
// screen. With drop-shadow now gated off below FLOATING_ELEVATION_MIN, TONE
|
|
1778
|
-
// is the only thing separating 0-3, so every step has to actually land.
|
|
1779
|
-
// Even 0.025 spacing, verified in elevation.test.ts as ΔL* > 1 per step.
|
|
1780
|
-
colorAdjustment: 0.025,
|
|
1781
|
-
shadowIntensity: "subtle",
|
|
1782
|
-
shadowStyle: "raised",
|
|
1783
|
-
description: "Subtle elevation (outline cards, subtle containers)"
|
|
1784
|
-
},
|
|
1785
|
-
// Level 2: Standard elevation (default cards, buttons)
|
|
1786
|
-
[2]: {
|
|
1787
|
-
name: "standard",
|
|
1788
|
-
colorAdjustment: 0.05,
|
|
1789
|
-
shadowIntensity: "medium",
|
|
1790
|
-
shadowStyle: "raised",
|
|
1791
|
-
description: "Standard elevation (default cards, raised buttons)"
|
|
1792
|
-
},
|
|
1793
|
-
// Level 3: Prominent elevation (important cards, modals)
|
|
1794
|
-
[3]: {
|
|
1795
|
-
name: "prominent",
|
|
1796
|
-
colorAdjustment: 0.075,
|
|
1797
|
-
shadowIntensity: "strong",
|
|
1798
|
-
shadowStyle: "raised",
|
|
1799
|
-
description: "Prominent elevation (important cards, modals, dropdowns)"
|
|
1800
|
-
},
|
|
1801
|
-
// Level 4: High elevation (overlays, popovers)
|
|
1802
|
-
[4]: {
|
|
1803
|
-
name: "high",
|
|
1804
|
-
colorAdjustment: 0.1,
|
|
1805
|
-
shadowIntensity: "strong",
|
|
1806
|
-
shadowStyle: "raised",
|
|
1807
|
-
description: "High elevation (overlays, popovers, tooltips)"
|
|
1808
|
-
},
|
|
1809
|
-
// Level 5: Floating (toasts, floating action buttons)
|
|
1810
|
-
[5]: {
|
|
1811
|
-
name: "floating",
|
|
1812
|
-
colorAdjustment: 0.13,
|
|
1813
|
-
shadowIntensity: "strong",
|
|
1814
|
-
shadowStyle: "raised",
|
|
1815
|
-
description: "Floating elevation (toasts, floating action buttons, highest z-index)"
|
|
1816
|
-
}
|
|
1817
|
-
};
|
|
1818
|
-
function calculateRimLightColor(baseColor, level) {
|
|
1819
|
-
const rgb = hexToRgb(baseColor);
|
|
1820
|
-
if (!rgb) {
|
|
1821
|
-
return "rgba(255, 255, 255, 0.5)";
|
|
1822
|
-
}
|
|
1823
|
-
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
1824
|
-
const isLight = hsv.v > 0.6;
|
|
1825
|
-
const isSaturated = hsv.s > 0.3;
|
|
1826
|
-
const absLevel = Math.abs(level);
|
|
1827
|
-
const opacityBoost = Math.max(0, (absLevel - 1) * 0.05);
|
|
1828
|
-
if (isSaturated) {
|
|
1829
|
-
const rimLightValue = 0.95;
|
|
1830
|
-
const rimLightRgb = hsvToRgb(hsv.h, hsv.s * 0.3, rimLightValue);
|
|
1831
|
-
const baseOpacity = isLight ? 0.9 : 0.5;
|
|
1832
|
-
const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
|
|
1833
|
-
return `rgba(${rimLightRgb.r}, ${rimLightRgb.g}, ${rimLightRgb.b}, ${finalOpacity.toFixed(2)})`;
|
|
1834
|
-
} else {
|
|
1835
|
-
const baseOpacity = isLight ? 0.9 : 0.12;
|
|
1836
|
-
const finalOpacity = Math.min(1, baseOpacity + opacityBoost);
|
|
1837
|
-
return `rgba(255, 255, 255, ${finalOpacity.toFixed(2)})`;
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
function calculateDarkShadowColors(surfaceColor) {
|
|
1841
|
-
const rgb = hexToRgb(surfaceColor);
|
|
1842
|
-
if (!rgb) {
|
|
1843
|
-
return {
|
|
1844
|
-
dark: "rgba(0, 0, 0, 0.3)",
|
|
1845
|
-
darker: "rgba(0, 0, 0, 0.4)"
|
|
1846
|
-
};
|
|
1847
|
-
}
|
|
1848
|
-
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
1849
|
-
const isLight = hsv.v > 0.6;
|
|
1850
|
-
const isSaturated = hsv.s > 0.3;
|
|
1851
|
-
if (isSaturated) {
|
|
1852
|
-
const darkShadowValue = 0.15;
|
|
1853
|
-
const darkShadowRgb = hsvToRgb(hsv.h, hsv.s, darkShadowValue);
|
|
1854
|
-
if (isLight) {
|
|
1855
|
-
return {
|
|
1856
|
-
dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.3)`,
|
|
1857
|
-
darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.4)`
|
|
1858
|
-
};
|
|
1859
|
-
} else {
|
|
1860
|
-
return {
|
|
1861
|
-
dark: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.5)`,
|
|
1862
|
-
darker: `rgba(${darkShadowRgb.r}, ${darkShadowRgb.g}, ${darkShadowRgb.b}, 0.6)`
|
|
1863
|
-
};
|
|
1864
|
-
}
|
|
1865
|
-
} else {
|
|
1866
|
-
if (isLight) {
|
|
1867
|
-
return {
|
|
1868
|
-
dark: "rgba(0, 0, 0, 0.2)",
|
|
1869
|
-
darker: "rgba(0, 0, 0, 0.3)"
|
|
1870
|
-
};
|
|
1871
|
-
} else {
|
|
1872
|
-
return {
|
|
1873
|
-
dark: "rgba(0, 0, 0, 0.5)",
|
|
1874
|
-
darker: "rgba(0, 0, 0, 0.6)"
|
|
1875
|
-
};
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
function getRimLightConfig() {
|
|
1880
|
-
return {
|
|
1881
|
-
offset: 1,
|
|
1882
|
-
// Fixed 1px for crisp rim
|
|
1883
|
-
blur: 1
|
|
1884
|
-
// Tight blur for crisp edge
|
|
1885
|
-
};
|
|
1886
|
-
}
|
|
1887
|
-
var elevationSurfaceCache = /* @__PURE__ */ new Map();
|
|
1888
|
-
var MAX_CACHE_SIZE = 100;
|
|
1889
|
-
function getCacheKey(baseColor, level, theme) {
|
|
1890
|
-
return `${baseColor}-${level}-${theme}`;
|
|
2167
|
+
var DEFAULT_CONTEXT = { mode: "dark", level: "base" };
|
|
2168
|
+
var SurfaceContext = createContext(DEFAULT_CONTEXT);
|
|
2169
|
+
function useSurface() {
|
|
2170
|
+
return useContext(SurfaceContext);
|
|
1891
2171
|
}
|
|
1892
|
-
function
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
}
|
|
1897
|
-
if (level < 0) {
|
|
1898
|
-
return baseColor;
|
|
1899
|
-
}
|
|
1900
|
-
return lighten(baseColor, config.colorAdjustment);
|
|
1901
|
-
}
|
|
1902
|
-
function getElevationSurface(baseColor, level, theme) {
|
|
1903
|
-
const cacheKey = getCacheKey(baseColor, level, theme);
|
|
1904
|
-
if (elevationSurfaceCache.has(cacheKey)) {
|
|
1905
|
-
return elevationSurfaceCache.get(cacheKey);
|
|
1906
|
-
}
|
|
1907
|
-
const result = calculateElevationSurface(baseColor, level);
|
|
1908
|
-
if (elevationSurfaceCache.size >= MAX_CACHE_SIZE) {
|
|
1909
|
-
const firstKey = elevationSurfaceCache.keys().next().value;
|
|
1910
|
-
elevationSurfaceCache.delete(firstKey);
|
|
1911
|
-
}
|
|
1912
|
-
elevationSurfaceCache.set(cacheKey, result);
|
|
1913
|
-
return result;
|
|
1914
|
-
}
|
|
1915
|
-
var elevationShadowCache = /* @__PURE__ */ new Map();
|
|
1916
|
-
var MAX_SHADOW_CACHE_SIZE = 50;
|
|
1917
|
-
function getShadowCacheKey(baseColor, level, theme, isHovered) {
|
|
1918
|
-
return `${baseColor}-${level}-${theme}-${isHovered}`;
|
|
1919
|
-
}
|
|
1920
|
-
function calculateElevationShadow(baseColor, level, theme, isHovered = false) {
|
|
1921
|
-
const config = elevationSystem[level];
|
|
1922
|
-
if (level === 0) {
|
|
1923
|
-
return {};
|
|
1924
|
-
}
|
|
1925
|
-
const elevatedSurfaceColor = calculateElevationSurface(baseColor, level);
|
|
1926
|
-
const rimLightColor = calculateRimLightColor(baseColor, level);
|
|
1927
|
-
const darkShadowColors = calculateDarkShadowColors(elevatedSurfaceColor);
|
|
1928
|
-
const intensityConfig = {
|
|
1929
|
-
subtle: { offset: 1, blur: 2 },
|
|
1930
|
-
medium: { offset: 2, blur: 4 },
|
|
1931
|
-
strong: { offset: 2, blur: 5 }
|
|
1932
|
-
};
|
|
1933
|
-
const { offset, blur } = intensityConfig[config.shadowIntensity];
|
|
1934
|
-
const rimConfig = getRimLightConfig();
|
|
1935
|
-
if (config.shadowStyle === "pressed") {
|
|
1936
|
-
if (isHovered) {
|
|
1937
|
-
const hoverOffset = Math.max(1, Math.round(offset / 2));
|
|
1938
|
-
const hoverBlur = Math.max(1, Math.round(blur / 2));
|
|
1939
|
-
return Platform.select({
|
|
1940
|
-
web: {
|
|
1941
|
-
boxShadow: `inset ${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
1942
|
-
},
|
|
1943
|
-
default: {
|
|
1944
|
-
shadowOpacity: 0,
|
|
1945
|
-
elevation: 0
|
|
1946
|
-
}
|
|
1947
|
-
});
|
|
1948
|
-
}
|
|
1949
|
-
return Platform.select({
|
|
1950
|
-
web: {
|
|
1951
|
-
boxShadow: `inset ${offset}px ${offset}px ${blur}px ${darkShadowColors.darker}, inset -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
1952
|
-
},
|
|
1953
|
-
default: {
|
|
1954
|
-
shadowOpacity: 0,
|
|
1955
|
-
elevation: 0
|
|
1956
|
-
}
|
|
1957
|
-
});
|
|
1958
|
-
} else {
|
|
1959
|
-
if (isHovered) {
|
|
1960
|
-
const hoverOffset = Math.max(1, Math.round(offset / 2));
|
|
1961
|
-
const hoverBlur = Math.max(1, Math.round(blur / 2));
|
|
1962
|
-
return Platform.select({
|
|
1963
|
-
web: {
|
|
1964
|
-
boxShadow: `${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
1965
|
-
},
|
|
1966
|
-
default: {
|
|
1967
|
-
shadowColor: "#000",
|
|
1968
|
-
shadowOffset: { width: hoverOffset, height: hoverOffset },
|
|
1969
|
-
shadowOpacity: 0.2,
|
|
1970
|
-
shadowRadius: hoverBlur / 2,
|
|
1971
|
-
elevation: hoverOffset
|
|
1972
|
-
}
|
|
1973
|
-
});
|
|
1974
|
-
}
|
|
1975
|
-
return Platform.select({
|
|
1976
|
-
web: {
|
|
1977
|
-
boxShadow: `${offset}px ${offset}px ${blur}px ${darkShadowColors.dark}, -${rimConfig.offset}px -${rimConfig.offset}px ${rimConfig.blur}px ${rimLightColor}`
|
|
1978
|
-
},
|
|
1979
|
-
default: {
|
|
1980
|
-
shadowColor: "#000",
|
|
1981
|
-
shadowOffset: { width: offset, height: offset },
|
|
1982
|
-
shadowOpacity: 0.3,
|
|
1983
|
-
shadowRadius: blur / 2,
|
|
1984
|
-
elevation: offset
|
|
1985
|
-
}
|
|
1986
|
-
});
|
|
1987
|
-
}
|
|
2172
|
+
function recessDepth(inherited, planesDown, mode) {
|
|
2173
|
+
let plane = inherited.level;
|
|
2174
|
+
for (let i = 0; i < planesDown; i++) plane = pressedLevel(plane);
|
|
2175
|
+
const backgroundColor = surfaceBackground(plane, mode);
|
|
2176
|
+
return { plane, backgroundColor, depthStyle: getPressedRecessShadow(backgroundColor, mode) };
|
|
1988
2177
|
}
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
const
|
|
1992
|
-
if (
|
|
1993
|
-
|
|
2178
|
+
function resolveSurfaceDepth(inherited, props) {
|
|
2179
|
+
const mode = props.theme ?? inherited.mode;
|
|
2180
|
+
const elevation = props.elevation ?? 0;
|
|
2181
|
+
if (props.pressed || elevation < 0) {
|
|
2182
|
+
const down = props.pressed ? 1 : -elevation;
|
|
2183
|
+
return { mode, step: 0, lifted: false, ...recessDepth(inherited, down, mode) };
|
|
1994
2184
|
}
|
|
1995
|
-
const
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
return
|
|
2002
|
-
}
|
|
2003
|
-
function getBaseSurfaceColor(theme) {
|
|
2004
|
-
return theme === "light" ? semanticColorsLight["surface-raised"] : semanticColorsDark["surface-elevated"];
|
|
2185
|
+
const step = props.level != null ? 0 : props.raise ?? elevation;
|
|
2186
|
+
const floating = step >= FLOATING_ELEVATION_MIN;
|
|
2187
|
+
const plane = props.level ?? (floating ? "overlay" : raisedLevel(inherited.level, step));
|
|
2188
|
+
const lifted = props.lift ?? step > 0;
|
|
2189
|
+
const liftStep = Math.max(1, Math.min(5, step));
|
|
2190
|
+
const depthStyle = lifted ? liftStyle(liftStep, mode, props.liftOptions) : {};
|
|
2191
|
+
return { mode, plane, backgroundColor: surfaceBackground(plane, mode), depthStyle, step, lifted };
|
|
2005
2192
|
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
},
|
|
2021
|
-
overlay: {
|
|
2022
|
-
allowed: [4, 5],
|
|
2023
|
-
default: 4
|
|
2024
|
-
}
|
|
2025
|
-
};
|
|
2026
|
-
function getValidatedElevation(component, requested) {
|
|
2027
|
-
const range = componentElevationRanges[component];
|
|
2028
|
-
if (range.allowed.includes(requested)) {
|
|
2029
|
-
return requested;
|
|
2030
|
-
}
|
|
2031
|
-
const sorted = [...range.allowed].sort((a, b) => a - b);
|
|
2032
|
-
if (requested < sorted[0]) return sorted[0];
|
|
2033
|
-
if (requested > sorted[sorted.length - 1]) return sorted[sorted.length - 1];
|
|
2034
|
-
return sorted.reduce(
|
|
2035
|
-
(prev, curr) => Math.abs(curr - requested) < Math.abs(prev - requested) ? curr : prev
|
|
2193
|
+
function useResolvedSurface(props) {
|
|
2194
|
+
const inherited = useSurface();
|
|
2195
|
+
const { level, raise, elevation, pressed, lift, liftOptions, theme } = props;
|
|
2196
|
+
return useMemo(
|
|
2197
|
+
() => resolveSurfaceDepth(inherited, {
|
|
2198
|
+
level,
|
|
2199
|
+
raise,
|
|
2200
|
+
elevation,
|
|
2201
|
+
pressed,
|
|
2202
|
+
lift,
|
|
2203
|
+
liftOptions,
|
|
2204
|
+
theme
|
|
2205
|
+
}),
|
|
2206
|
+
[inherited, level, raise, elevation, pressed, lift, liftOptions, theme]
|
|
2036
2207
|
);
|
|
2037
2208
|
}
|
|
2038
|
-
function getTheme() {
|
|
2039
|
-
if (typeof document === "undefined") return "dark";
|
|
2040
|
-
return document.documentElement.classList.contains("light") ? "light" : "dark";
|
|
2041
|
-
}
|
|
2042
|
-
var listeners = [];
|
|
2043
|
-
function subscribe(listener) {
|
|
2044
|
-
listeners = [...listeners, listener];
|
|
2045
|
-
if (typeof document !== "undefined" && listeners.length === 1) {
|
|
2046
|
-
const observer = new MutationObserver((mutations) => {
|
|
2047
|
-
for (const mutation of mutations) {
|
|
2048
|
-
if (mutation.type === "attributes" && mutation.attributeName === "class") {
|
|
2049
|
-
listeners.forEach((l) => l());
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
});
|
|
2053
|
-
observer.observe(document.documentElement, {
|
|
2054
|
-
attributes: true,
|
|
2055
|
-
attributeFilter: ["class"]
|
|
2056
|
-
});
|
|
2057
|
-
subscribe._observer = observer;
|
|
2058
|
-
}
|
|
2059
|
-
return () => {
|
|
2060
|
-
listeners = listeners.filter((l) => l !== listener);
|
|
2061
|
-
if (listeners.length === 0 && subscribe._observer) {
|
|
2062
|
-
subscribe._observer.disconnect();
|
|
2063
|
-
subscribe._observer = null;
|
|
2064
|
-
}
|
|
2065
|
-
};
|
|
2066
|
-
}
|
|
2067
|
-
function getSnapshot() {
|
|
2068
|
-
return getTheme();
|
|
2069
|
-
}
|
|
2070
|
-
function getServerSnapshot() {
|
|
2071
|
-
return "dark";
|
|
2072
|
-
}
|
|
2073
|
-
function useTheme() {
|
|
2074
|
-
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
2075
|
-
}
|
|
2076
2209
|
|
|
2077
2210
|
// src/components/ui/card/Card.tsx
|
|
2078
|
-
var
|
|
2211
|
+
var EDGE_CLASS = {
|
|
2079
2212
|
elevated: "",
|
|
2080
|
-
|
|
2081
|
-
outline: "border-2 border-hairline-strong",
|
|
2082
|
-
// Thicker border with stronger contrast
|
|
2213
|
+
accent: "",
|
|
2083
2214
|
filled: "",
|
|
2084
|
-
|
|
2085
|
-
accent: "border border-hairline",
|
|
2215
|
+
outline: "border border-hairline-strong",
|
|
2086
2216
|
subtle: "border border-hairline-subtle"
|
|
2087
2217
|
};
|
|
2218
|
+
var LIFTED = {
|
|
2219
|
+
elevated: true,
|
|
2220
|
+
accent: true,
|
|
2221
|
+
filled: false,
|
|
2222
|
+
outline: false,
|
|
2223
|
+
subtle: false
|
|
2224
|
+
};
|
|
2225
|
+
var STAYS_ON_HOST = {
|
|
2226
|
+
elevated: false,
|
|
2227
|
+
accent: false,
|
|
2228
|
+
filled: false,
|
|
2229
|
+
outline: true,
|
|
2230
|
+
subtle: true
|
|
2231
|
+
};
|
|
2232
|
+
function useCardDepth(variant, elevation, hovered) {
|
|
2233
|
+
const raise = STAYS_ON_HOST[variant] ? void 0 : elevation;
|
|
2234
|
+
const resolved = useResolvedSurface({ raise, lift: LIFTED[variant] });
|
|
2235
|
+
const depthStyle = useMemo(() => {
|
|
2236
|
+
if (!hovered || !LIFTED[variant]) return resolved.depthStyle;
|
|
2237
|
+
const hoverStep = Math.min(3, resolved.step + 1);
|
|
2238
|
+
return liftStyle(hoverStep, resolved.mode);
|
|
2239
|
+
}, [hovered, variant, resolved]);
|
|
2240
|
+
return { ...resolved, depthStyle };
|
|
2241
|
+
}
|
|
2088
2242
|
function Card({
|
|
2089
2243
|
variant = "elevated",
|
|
2090
2244
|
elevation = 2,
|
|
@@ -2105,89 +2259,54 @@ function Card({
|
|
|
2105
2259
|
}) {
|
|
2106
2260
|
const isClickable = isInteractive || !!onPress;
|
|
2107
2261
|
const [isHovered, setIsHovered] = useState(false);
|
|
2108
|
-
const
|
|
2109
|
-
const elevationLevel = useMemo(() => {
|
|
2110
|
-
const validated = getValidatedElevation("card", elevation);
|
|
2111
|
-
if (variant === "outline" || variant === "accent" || variant === "subtle") {
|
|
2112
|
-
return 1;
|
|
2113
|
-
}
|
|
2114
|
-
return validated;
|
|
2115
|
-
}, [variant, elevation]);
|
|
2116
|
-
const baseColor = useMemo(() => getBaseSurfaceColor(theme), [theme]);
|
|
2117
|
-
const surfaceColor = useMemo(() => {
|
|
2118
|
-
if ((variant === "outline" || variant === "accent") && theme === "light") {
|
|
2119
|
-
return "#FAFAFA";
|
|
2120
|
-
}
|
|
2121
|
-
if (variant === "subtle") {
|
|
2122
|
-
return getElevationSurface(baseColor, 0, theme);
|
|
2123
|
-
}
|
|
2124
|
-
return getElevationSurface(baseColor, elevationLevel, theme);
|
|
2125
|
-
}, [baseColor, elevationLevel, theme, variant]);
|
|
2126
|
-
const shadowStyle = useMemo(() => {
|
|
2127
|
-
const shouldHover = isHovered && isClickable;
|
|
2128
|
-
return getElevationShadow(baseColor, elevationLevel, theme, shouldHover);
|
|
2129
|
-
}, [baseColor, elevationLevel, theme, isHovered, isClickable]);
|
|
2130
|
-
const cardContent = isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2131
|
-
skeletonHasHeader && /* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
2132
|
-
/* @__PURE__ */ jsx(View, { className: "h-5 w-1/3 bg-interactive-disabled rounded" }),
|
|
2133
|
-
/* @__PURE__ */ jsx(View, { className: "mt-2 h-4 w-2/3 bg-interactive-disabled rounded" })
|
|
2134
|
-
] }),
|
|
2135
|
-
/* @__PURE__ */ jsx(CardContent, { children: Array.from({ length: skeletonContentLines }).map((_, i) => /* @__PURE__ */ jsx(
|
|
2136
|
-
View,
|
|
2137
|
-
{
|
|
2138
|
-
className: cn(
|
|
2139
|
-
"h-4 bg-interactive-disabled rounded",
|
|
2140
|
-
i < skeletonContentLines - 1 ? "mb-2 w-full" : "w-4/5"
|
|
2141
|
-
)
|
|
2142
|
-
},
|
|
2143
|
-
i
|
|
2144
|
-
)) }),
|
|
2145
|
-
skeletonHasFooter && /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(View, { className: "h-9 w-24 bg-interactive-disabled rounded" }) })
|
|
2146
|
-
] }) : children;
|
|
2262
|
+
const depth = useCardDepth(variant, elevation, isHovered && isClickable);
|
|
2147
2263
|
const baseClassName = cn(
|
|
2148
2264
|
"rounded-lg overflow-hidden relative",
|
|
2149
|
-
|
|
2150
|
-
variant === "outline" ? borderColor ? "border-2" : variantStyles[variant] : variantStyles[variant],
|
|
2151
|
-
// Remove Tailwind shadow classes - we're using elevation shadows via style prop
|
|
2265
|
+
borderColor ? "border" : EDGE_CLASS[variant],
|
|
2152
2266
|
isClickable && "web:cursor-pointer web:transition-all web:duration-150",
|
|
2153
2267
|
isClickable && "web:hover:-translate-y-0.5 active:scale-[0.99]",
|
|
2154
2268
|
isLoading && "pointer-events-none animate-pulse",
|
|
2155
2269
|
className
|
|
2156
2270
|
);
|
|
2157
|
-
const accentStyle = useMemo(() => variant === "accent" ? {
|
|
2158
|
-
borderLeftWidth: accentWidth ?? 3,
|
|
2159
|
-
borderLeftColor: accentColor ?? "var(--color-brand-primary)"
|
|
2160
|
-
} : {}, [variant, accentWidth, accentColor]);
|
|
2161
2271
|
const mergedStyle = useMemo(() => {
|
|
2162
|
-
const
|
|
2163
|
-
backgroundColor: bgColor ||
|
|
2272
|
+
const own = {
|
|
2273
|
+
backgroundColor: bgColor || depth.backgroundColor,
|
|
2164
2274
|
borderRadius: 8,
|
|
2165
2275
|
overflow: "hidden",
|
|
2166
|
-
...
|
|
2167
|
-
...accentStyle
|
|
2276
|
+
...depth.depthStyle
|
|
2168
2277
|
};
|
|
2169
|
-
if (
|
|
2170
|
-
|
|
2278
|
+
if (variant === "accent") {
|
|
2279
|
+
own.borderLeftWidth = accentWidth ?? 3;
|
|
2280
|
+
own.borderLeftColor = accentColor ?? "var(--color-brand-primary)";
|
|
2171
2281
|
}
|
|
2172
|
-
if (
|
|
2173
|
-
return [
|
|
2174
|
-
}, [style,
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2282
|
+
if (borderColor) own.borderColor = borderColor;
|
|
2283
|
+
return style ? [own, style] : own;
|
|
2284
|
+
}, [style, depth, bgColor, borderColor, variant, accentWidth, accentColor]);
|
|
2285
|
+
const context = useMemo(
|
|
2286
|
+
() => ({ mode: depth.mode, level: depth.plane }),
|
|
2287
|
+
[depth.mode, depth.plane]
|
|
2288
|
+
);
|
|
2289
|
+
const content = isLoading ? /* @__PURE__ */ jsx(
|
|
2290
|
+
SkeletonBody,
|
|
2291
|
+
{
|
|
2292
|
+
hasHeader: skeletonHasHeader,
|
|
2293
|
+
hasFooter: skeletonHasFooter,
|
|
2294
|
+
contentLines: skeletonContentLines
|
|
2295
|
+
}
|
|
2296
|
+
) : children;
|
|
2297
|
+
return /* @__PURE__ */ jsx(SurfaceContext.Provider, { value: context, children: isClickable ? /* @__PURE__ */ jsx(
|
|
2298
|
+
Pressable,
|
|
2299
|
+
{
|
|
2300
|
+
onPress,
|
|
2301
|
+
onHoverIn: () => setIsHovered(true),
|
|
2302
|
+
onHoverOut: () => setIsHovered(false),
|
|
2303
|
+
accessibilityRole: "button",
|
|
2304
|
+
className: baseClassName,
|
|
2305
|
+
style: mergedStyle,
|
|
2306
|
+
...props,
|
|
2307
|
+
children: content
|
|
2308
|
+
}
|
|
2309
|
+
) : /* @__PURE__ */ jsx(View, { className: baseClassName, style: mergedStyle, ...props, children: content }) });
|
|
2191
2310
|
}
|
|
2192
2311
|
function CardHeader({ children, className }) {
|
|
2193
2312
|
return /* @__PURE__ */ jsx(View, { className: cn("px-6 py-6", className), children });
|
|
@@ -2198,60 +2317,88 @@ function CardContent({ children, className }) {
|
|
|
2198
2317
|
function CardFooter({ children, className }) {
|
|
2199
2318
|
return /* @__PURE__ */ jsx(View, { className: cn("px-6 py-4 flex-row items-center gap-2", className), children });
|
|
2200
2319
|
}
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2320
|
+
function SkeletonBody({ hasHeader, hasFooter, contentLines }) {
|
|
2321
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2322
|
+
hasHeader && /* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
2323
|
+
/* @__PURE__ */ jsx(View, { className: "h-5 w-1/3 bg-interactive-disabled rounded" }),
|
|
2324
|
+
/* @__PURE__ */ jsx(View, { className: "mt-2 h-4 w-2/3 bg-interactive-disabled rounded" })
|
|
2325
|
+
] }),
|
|
2326
|
+
/* @__PURE__ */ jsx(CardContent, { children: Array.from({ length: contentLines }).map((_, i) => /* @__PURE__ */ jsx(
|
|
2327
|
+
View,
|
|
2328
|
+
{
|
|
2329
|
+
className: cn(
|
|
2330
|
+
"h-4 bg-interactive-disabled rounded",
|
|
2331
|
+
i < contentLines - 1 ? "mb-2 w-full" : "w-4/5"
|
|
2332
|
+
)
|
|
2333
|
+
},
|
|
2334
|
+
i
|
|
2335
|
+
)) }),
|
|
2336
|
+
hasFooter && /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(View, { className: "h-9 w-24 bg-interactive-disabled rounded" }) })
|
|
2337
|
+
] });
|
|
2338
|
+
}
|
|
2339
|
+
var solidFillToken = {
|
|
2340
|
+
success: "status-success",
|
|
2341
|
+
warning: "status-warning",
|
|
2342
|
+
error: "status-error",
|
|
2343
|
+
neutral: "text-tertiary"
|
|
2207
2344
|
};
|
|
2208
|
-
var
|
|
2209
|
-
"on-track": {
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
borderStyle: "dashed",
|
|
2223
|
-
borderColor: "rgba(107,114,128,0.2)"
|
|
2224
|
-
}
|
|
2345
|
+
var ringWashToken = {
|
|
2346
|
+
"on-track": { fill: "status-success-subtle", border: "status-success-muted" },
|
|
2347
|
+
deviation: { fill: "status-warning-subtle", border: "status-warning-muted" }
|
|
2348
|
+
};
|
|
2349
|
+
var FUTURE_FILL = alpha(greyRamp[500], 0.1);
|
|
2350
|
+
var FUTURE_BORDER = alpha(greyRamp[500], 0.2);
|
|
2351
|
+
var glyphToken = {
|
|
2352
|
+
success: "text-inverse",
|
|
2353
|
+
warning: "text-inverse",
|
|
2354
|
+
error: "text-inverse",
|
|
2355
|
+
neutral: "text-inverse",
|
|
2356
|
+
"on-track": "status-success",
|
|
2357
|
+
deviation: "status-warning",
|
|
2358
|
+
future: "text-tertiary"
|
|
2225
2359
|
};
|
|
2226
|
-
var
|
|
2227
|
-
success:
|
|
2228
|
-
warning:
|
|
2229
|
-
error:
|
|
2230
|
-
neutral:
|
|
2231
|
-
"on-track":
|
|
2232
|
-
deviation:
|
|
2233
|
-
future:
|
|
2360
|
+
var glowColors2 = {
|
|
2361
|
+
success: semanticColorsDark["status-success"],
|
|
2362
|
+
warning: semanticColorsDark["status-warning"],
|
|
2363
|
+
error: semanticColorsDark["status-error"],
|
|
2364
|
+
neutral: greyRamp[500],
|
|
2365
|
+
"on-track": semanticColorsDark["status-success"],
|
|
2366
|
+
deviation: semanticColorsDark["status-warning"],
|
|
2367
|
+
future: greyRamp[500]
|
|
2234
2368
|
};
|
|
2369
|
+
var glowStyles = Object.fromEntries(
|
|
2370
|
+
Object.entries(glowColors2).map(([variant, color]) => [variant, getGlowShadow(color, "subtle")])
|
|
2371
|
+
);
|
|
2235
2372
|
var iconChars = {
|
|
2236
2373
|
check: "\u2713",
|
|
2237
2374
|
exclamation: "!",
|
|
2238
2375
|
dash: "\u2014"
|
|
2239
2376
|
};
|
|
2240
|
-
var iconColors = {
|
|
2241
|
-
success: "#0A5C52",
|
|
2242
|
-
warning: "#6B4000",
|
|
2243
|
-
error: "#5C1A1A",
|
|
2244
|
-
neutral: greyRamp[200],
|
|
2245
|
-
"on-track": t2["status-success"],
|
|
2246
|
-
deviation: t2["status-warning"],
|
|
2247
|
-
future: greyRamp[500]
|
|
2248
|
-
};
|
|
2249
2377
|
var sizeDimensions = {
|
|
2250
2378
|
sm: { size: 8, showIcon: false },
|
|
2251
2379
|
md: { size: 18, showIcon: true }
|
|
2252
2380
|
};
|
|
2253
2381
|
function isSolidVariant(variant) {
|
|
2254
|
-
return variant in
|
|
2382
|
+
return variant in solidFillToken;
|
|
2383
|
+
}
|
|
2384
|
+
function ringStyle(variant) {
|
|
2385
|
+
if (variant === "future") {
|
|
2386
|
+
return {
|
|
2387
|
+
backgroundColor: FUTURE_FILL,
|
|
2388
|
+
borderWidth: 1,
|
|
2389
|
+
borderStyle: "dashed",
|
|
2390
|
+
borderColor: FUTURE_BORDER
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
if (variant === "on-track" || variant === "deviation") {
|
|
2394
|
+
const tokens = ringWashToken[variant];
|
|
2395
|
+
return {
|
|
2396
|
+
backgroundColor: resolveColor(tokens.fill),
|
|
2397
|
+
borderWidth: 1,
|
|
2398
|
+
borderColor: resolveColor(tokens.border)
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
return void 0;
|
|
2255
2402
|
}
|
|
2256
2403
|
function StatusDot({
|
|
2257
2404
|
variant,
|
|
@@ -2264,7 +2411,7 @@ function StatusDot({
|
|
|
2264
2411
|
}) {
|
|
2265
2412
|
const config = sizeDimensions[size];
|
|
2266
2413
|
const solid = isSolidVariant(variant);
|
|
2267
|
-
const ring =
|
|
2414
|
+
const ring = ringStyle(variant);
|
|
2268
2415
|
const glowStyle = glow ? glowStyles[variant] : null;
|
|
2269
2416
|
const dot = /* @__PURE__ */ jsx(
|
|
2270
2417
|
View,
|
|
@@ -2278,22 +2425,22 @@ function StatusDot({
|
|
|
2278
2425
|
justifyContent: "center",
|
|
2279
2426
|
flexShrink: 0
|
|
2280
2427
|
},
|
|
2281
|
-
solid ? { backgroundColor:
|
|
2282
|
-
ring
|
|
2428
|
+
solid ? { backgroundColor: resolveColor(solidFillToken[variant]) } : void 0,
|
|
2429
|
+
ring,
|
|
2283
2430
|
glowStyle ? glowStyle : void 0
|
|
2284
2431
|
],
|
|
2285
2432
|
accessibilityRole: "image",
|
|
2286
2433
|
accessibilityLabel: `${variant} status`,
|
|
2287
2434
|
testID: "status-dot",
|
|
2288
|
-
children: config.showIcon && icon &&
|
|
2289
|
-
|
|
2435
|
+
children: config.showIcon && icon && // The glyph was 11px/900, off the type scale (TOKENS.md §4); `boldLabel` is
|
|
2436
|
+
// the 12px sans label step and `font-black` keeps the original weight.
|
|
2437
|
+
/* @__PURE__ */ jsx(
|
|
2438
|
+
Typography,
|
|
2290
2439
|
{
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
color: iconColors[variant]
|
|
2296
|
-
},
|
|
2440
|
+
variant: "boldLabel",
|
|
2441
|
+
color: "inherit",
|
|
2442
|
+
className: "font-black leading-none",
|
|
2443
|
+
style: { color: resolveColor(glyphToken[variant]) },
|
|
2297
2444
|
accessibilityElementsHidden: true,
|
|
2298
2445
|
children: iconChars[icon]
|
|
2299
2446
|
}
|
|
@@ -2311,9 +2458,11 @@ function StatusDot({
|
|
|
2311
2458
|
children: [
|
|
2312
2459
|
/* @__PURE__ */ jsx(View, { accessibilityElementsHidden: true, children: dot }),
|
|
2313
2460
|
/* @__PURE__ */ jsx(
|
|
2314
|
-
|
|
2461
|
+
Typography,
|
|
2315
2462
|
{
|
|
2316
|
-
|
|
2463
|
+
variant: "caption",
|
|
2464
|
+
color: "secondary",
|
|
2465
|
+
className: "leading-4",
|
|
2317
2466
|
accessibilityElementsHidden: true,
|
|
2318
2467
|
children: label
|
|
2319
2468
|
}
|
|
@@ -2329,19 +2478,19 @@ var MESO_ACCENT_GRADIENT_LIGHT = primitiveRamps.orange[300];
|
|
|
2329
2478
|
|
|
2330
2479
|
// src/components/custom/Workout/MesoStatusCard.tsx
|
|
2331
2480
|
var t3 = getSemanticColors("dark");
|
|
2332
|
-
var
|
|
2481
|
+
var BRAND_PRIMARY3 = t3["brand-primary"];
|
|
2333
2482
|
var BRAND_PRIMARY_DARK = MESO_ACCENT_GRADIENT_DARK;
|
|
2334
2483
|
var BRAND_PRIMARY_LIGHT = MESO_ACCENT_GRADIENT_LIGHT;
|
|
2335
2484
|
var SUCCESS = t3["status-success"];
|
|
2336
2485
|
var WARNING = t3["status-warning"];
|
|
2337
2486
|
var ERROR = t3["status-error"];
|
|
2338
|
-
var ACCENT_STOPS = [BRAND_PRIMARY_DARK,
|
|
2487
|
+
var ACCENT_STOPS = [BRAND_PRIMARY_DARK, BRAND_PRIMARY3, BRAND_PRIMARY_LIGHT];
|
|
2339
2488
|
var CARD_GRADIENT = `linear-gradient(135deg, ${resolveColor("surface-elevated")} 0%, ${resolveColor("surface-raised")} 100%)`;
|
|
2340
|
-
var GAUGE_GRADIENT =
|
|
2489
|
+
var GAUGE_GRADIENT = `linear-gradient(90deg, ${alpha(SUCCESS, 0.25)} 0%, ${alpha(WARNING, 0.25)} 50%, ${alpha(ERROR, 0.25)} 100%)`;
|
|
2341
2490
|
var STATUS_VARIANTS = {
|
|
2342
|
-
success: { bg:
|
|
2343
|
-
warning: { bg:
|
|
2344
|
-
error: { bg:
|
|
2491
|
+
success: { bg: alpha(SUCCESS, 0.15), border: alpha(SUCCESS, 0.3), text: SUCCESS },
|
|
2492
|
+
warning: { bg: alpha(WARNING, 0.15), border: alpha(WARNING, 0.3), text: WARNING },
|
|
2493
|
+
error: { bg: alpha(ERROR, 0.15), border: alpha(ERROR, 0.25), text: ERROR }
|
|
2345
2494
|
};
|
|
2346
2495
|
function clamp012(value) {
|
|
2347
2496
|
if (!Number.isFinite(value)) return 0;
|
|
@@ -2360,15 +2509,7 @@ function renderCoachingText(text, highlights) {
|
|
|
2360
2509
|
if (escaped.length === 0) return text;
|
|
2361
2510
|
const regex = new RegExp(`(${escaped.join("|")})`, "g");
|
|
2362
2511
|
return text.split(regex).map(
|
|
2363
|
-
(part, index) => highlights.includes(part) ? /* @__PURE__ */ jsx(
|
|
2364
|
-
Text,
|
|
2365
|
-
{
|
|
2366
|
-
className: "text-text-primary",
|
|
2367
|
-
style: { fontWeight: "700" },
|
|
2368
|
-
children: part
|
|
2369
|
-
},
|
|
2370
|
-
`${part}-${index}`
|
|
2371
|
-
) : /* @__PURE__ */ jsx(Fragment$1, { children: part }, `t-${index}`)
|
|
2512
|
+
(part, index) => highlights.includes(part) ? /* @__PURE__ */ jsx(Text, { className: "text-text-primary", style: { fontWeight: "700" }, children: part }, `${part}-${index}`) : /* @__PURE__ */ jsx(Fragment, { children: part }, `t-${index}`)
|
|
2372
2513
|
);
|
|
2373
2514
|
}
|
|
2374
2515
|
function StatusPill({ badge }) {
|
|
@@ -2453,41 +2594,34 @@ function Gauge({ gauge }) {
|
|
|
2453
2594
|
"aria-valuemax": 100,
|
|
2454
2595
|
testID: "meso-status-card-gauge",
|
|
2455
2596
|
children: [
|
|
2456
|
-
/* @__PURE__ */ jsxs(
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
},
|
|
2485
|
-
children: gauge.sublabel
|
|
2486
|
-
}
|
|
2487
|
-
)
|
|
2488
|
-
]
|
|
2489
|
-
}
|
|
2490
|
-
),
|
|
2597
|
+
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center justify-between", accessibilityElementsHidden: true, children: [
|
|
2598
|
+
/* @__PURE__ */ jsx(
|
|
2599
|
+
Text,
|
|
2600
|
+
{
|
|
2601
|
+
className: "text-text-secondary",
|
|
2602
|
+
style: {
|
|
2603
|
+
fontSize: 10,
|
|
2604
|
+
fontFamily: "Inter, sans-serif",
|
|
2605
|
+
fontWeight: "500",
|
|
2606
|
+
letterSpacing: 0.5,
|
|
2607
|
+
textTransform: "uppercase"
|
|
2608
|
+
},
|
|
2609
|
+
children: gauge.label
|
|
2610
|
+
}
|
|
2611
|
+
),
|
|
2612
|
+
gauge.sublabel != null && /* @__PURE__ */ jsx(
|
|
2613
|
+
Text,
|
|
2614
|
+
{
|
|
2615
|
+
className: "text-text-tertiary",
|
|
2616
|
+
style: {
|
|
2617
|
+
fontSize: 10,
|
|
2618
|
+
fontFamily: "Inter, sans-serif",
|
|
2619
|
+
fontWeight: "500"
|
|
2620
|
+
},
|
|
2621
|
+
children: gauge.sublabel
|
|
2622
|
+
}
|
|
2623
|
+
)
|
|
2624
|
+
] }),
|
|
2491
2625
|
/* @__PURE__ */ jsxs(
|
|
2492
2626
|
View,
|
|
2493
2627
|
{
|
|
@@ -2509,7 +2643,7 @@ function Gauge({ gauge }) {
|
|
|
2509
2643
|
bottom: 0,
|
|
2510
2644
|
width: 1,
|
|
2511
2645
|
marginLeft: -0.5,
|
|
2512
|
-
backgroundColor:
|
|
2646
|
+
backgroundColor: alpha(primitiveColors.white, 0.3)
|
|
2513
2647
|
},
|
|
2514
2648
|
testID: "meso-status-card-gauge-center"
|
|
2515
2649
|
}
|
|
@@ -2528,7 +2662,8 @@ function Gauge({ gauge }) {
|
|
|
2528
2662
|
borderRadius: 9999,
|
|
2529
2663
|
borderWidth: 2,
|
|
2530
2664
|
backgroundColor: markerColor,
|
|
2531
|
-
|
|
2665
|
+
// A knob resting on the gauge: lift, with the ring as its edge.
|
|
2666
|
+
...liftStyle(1, "dark", { rim: 0 })
|
|
2532
2667
|
},
|
|
2533
2668
|
testID: "meso-status-card-gauge-marker"
|
|
2534
2669
|
}
|
|
@@ -2580,30 +2715,23 @@ function MesoStatusCard({
|
|
|
2580
2715
|
),
|
|
2581
2716
|
/* @__PURE__ */ jsxs(View, { style: { padding: 14, gap: 14 }, testID: "meso-status-card-body", children: [
|
|
2582
2717
|
/* @__PURE__ */ jsxs(View, { testID: "meso-status-card-header", children: [
|
|
2583
|
-
/* @__PURE__ */ jsxs(
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
children: mesoName
|
|
2601
|
-
}
|
|
2602
|
-
),
|
|
2603
|
-
/* @__PURE__ */ jsx(StatusPill, { badge: statusBadge })
|
|
2604
|
-
]
|
|
2605
|
-
}
|
|
2606
|
-
),
|
|
2718
|
+
/* @__PURE__ */ jsxs(View, { className: "flex-row items-center justify-between", style: { gap: 8 }, children: [
|
|
2719
|
+
/* @__PURE__ */ jsx(
|
|
2720
|
+
Text,
|
|
2721
|
+
{
|
|
2722
|
+
className: "text-text-primary",
|
|
2723
|
+
style: {
|
|
2724
|
+
flexShrink: 1,
|
|
2725
|
+
fontSize: 15,
|
|
2726
|
+
fontFamily: '"Space Grotesk", sans-serif',
|
|
2727
|
+
fontWeight: "700"
|
|
2728
|
+
},
|
|
2729
|
+
testID: "meso-status-card-name",
|
|
2730
|
+
children: mesoName
|
|
2731
|
+
}
|
|
2732
|
+
),
|
|
2733
|
+
/* @__PURE__ */ jsx(StatusPill, { badge: statusBadge })
|
|
2734
|
+
] }),
|
|
2607
2735
|
/* @__PURE__ */ jsx(
|
|
2608
2736
|
Text,
|
|
2609
2737
|
{
|
|
@@ -2618,23 +2746,15 @@ function MesoStatusCard({
|
|
|
2618
2746
|
}
|
|
2619
2747
|
)
|
|
2620
2748
|
] }),
|
|
2621
|
-
metrics.length > 0 && /* @__PURE__ */ jsx(
|
|
2622
|
-
View,
|
|
2623
|
-
{
|
|
2624
|
-
className: "flex-row flex-wrap",
|
|
2625
|
-
style: { gap: 8 },
|
|
2626
|
-
testID: "meso-status-card-metrics",
|
|
2627
|
-
children: metrics.map((metric, index) => /* @__PURE__ */ jsx(MetricCell, { metric }, `${metric.label}-${index}`))
|
|
2628
|
-
}
|
|
2629
|
-
),
|
|
2749
|
+
metrics.length > 0 && /* @__PURE__ */ jsx(View, { className: "flex-row flex-wrap", style: { gap: 8 }, testID: "meso-status-card-metrics", children: metrics.map((metric, index) => /* @__PURE__ */ jsx(MetricCell, { metric }, `${metric.label}-${index}`)) }),
|
|
2630
2750
|
gauges.length > 0 && /* @__PURE__ */ jsx(View, { style: { gap: 12 }, testID: "meso-status-card-gauges", children: gauges.map((gauge, index) => /* @__PURE__ */ jsx(Gauge, { gauge }, `${gauge.label}-${index}`)) }),
|
|
2631
2751
|
coaching != null && /* @__PURE__ */ jsx(
|
|
2632
2752
|
View,
|
|
2633
2753
|
{
|
|
2634
2754
|
style: {
|
|
2635
|
-
backgroundColor:
|
|
2755
|
+
backgroundColor: alpha(WARNING, 0.06),
|
|
2636
2756
|
borderWidth: 1,
|
|
2637
|
-
borderColor:
|
|
2757
|
+
borderColor: alpha(WARNING, 0.15),
|
|
2638
2758
|
borderRadius: 8,
|
|
2639
2759
|
paddingVertical: 10,
|
|
2640
2760
|
paddingHorizontal: 12
|
|
@@ -2660,9 +2780,9 @@ function MesoStatusCard({
|
|
|
2660
2780
|
className: "flex-row items-center",
|
|
2661
2781
|
style: {
|
|
2662
2782
|
gap: 8,
|
|
2663
|
-
backgroundColor:
|
|
2783
|
+
backgroundColor: alpha(SUCCESS, 0.06),
|
|
2664
2784
|
borderWidth: 1,
|
|
2665
|
-
borderColor:
|
|
2785
|
+
borderColor: alpha(SUCCESS, 0.2),
|
|
2666
2786
|
borderRadius: 8,
|
|
2667
2787
|
paddingVertical: 10,
|
|
2668
2788
|
paddingHorizontal: 12
|