@titan-design/react-ui 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -47
- package/dist/bodymap.js +768 -701
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +770 -703
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +1319 -216
- package/dist/index.d.ts +1319 -216
- package/dist/index.js +5996 -4498
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5773 -4357
- package/dist/index.mjs.map +1 -1
- package/dist/{pages-CvsFqNtx.d.mts → pages-CpW3OB3g.d.mts} +21 -3
- package/dist/{pages-B1hqnGIC.d.ts → pages-_3Ajpiqu.d.ts} +21 -3
- package/dist/pages.d.mts +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +1435 -1428
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +1443 -1436
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +195 -134
- package/dist/theme/index.d.ts +195 -134
- package/dist/theme/index.js +215 -300
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +202 -296
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +62 -5
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +62 -5
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/dist/theme/tokens.d.mts +73 -5
- package/dist/theme/tokens.d.ts +73 -5
- package/dist/theme/tokens.js +55 -7
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme/tokens.mjs +55 -8
- package/dist/theme/tokens.mjs.map +1 -1
- package/docs/audits/2026-09-08-critique-addenda.md +51 -0
- package/docs/audits/2026-09-08-library-critique.md +212 -0
- package/docs/library-roadmap.md +99 -0
- package/package.json +1 -1
- package/src/arch/arch-graph.freshness.test.ts +52 -0
- package/src/arch/arch-graph.json +5021 -1617
- package/src/components/custom/ActiveWork/CoChangeChip.stories.tsx +44 -0
- package/src/components/custom/ActiveWork/CoChangeChip.test.tsx +29 -0
- package/src/components/custom/ActiveWork/CoChangeChip.tsx +48 -0
- package/src/components/custom/ActiveWork/Eyebrow.stories.tsx +25 -0
- package/src/components/custom/ActiveWork/Eyebrow.test.tsx +16 -0
- package/src/components/custom/ActiveWork/Eyebrow.tsx +26 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.stories.tsx +50 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.test.tsx +66 -0
- package/src/components/custom/ActiveWork/FileActivityDetail.tsx +202 -0
- package/src/components/custom/ActiveWork/FileActivityRow.stories.tsx +70 -0
- package/src/components/custom/ActiveWork/FileActivityRow.test.tsx +67 -0
- package/src/components/custom/ActiveWork/FileActivityRow.tsx +130 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.stories.tsx +84 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.test.tsx +99 -0
- package/src/components/custom/ActiveWork/FileHistoryExplorer.tsx +138 -0
- package/src/components/custom/ActiveWork/FilePathLabel.stories.tsx +39 -0
- package/src/components/custom/ActiveWork/FilePathLabel.test.tsx +53 -0
- package/src/components/custom/ActiveWork/FilePathLabel.tsx +63 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.stories.tsx +50 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.test.tsx +62 -0
- package/src/components/custom/ActiveWork/InitiativeBrief.tsx +181 -0
- package/src/components/custom/ActiveWork/InitiativeCard.stories.tsx +73 -0
- package/src/components/custom/ActiveWork/InitiativeCard.test.tsx +68 -0
- package/src/components/custom/ActiveWork/InitiativeCard.tsx +136 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.stories.tsx +59 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.test.tsx +40 -0
- package/src/components/custom/ActiveWork/InitiativeHeader.tsx +73 -0
- package/src/components/custom/ActiveWork/InitiativeReader.stories.tsx +145 -0
- package/src/components/custom/ActiveWork/OpenLoops.stories.tsx +58 -0
- package/src/components/custom/ActiveWork/OpenLoops.test.tsx +61 -0
- package/src/components/custom/ActiveWork/OpenLoops.tsx +107 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.stories.tsx +101 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.test.tsx +81 -0
- package/src/components/custom/ActiveWork/PortfolioOverview.tsx +83 -0
- package/src/components/custom/ActiveWork/README.md +305 -0
- package/src/components/custom/ActiveWork/SessionDetail.stories.tsx +71 -0
- package/src/components/custom/ActiveWork/SessionDetail.test.tsx +84 -0
- package/src/components/custom/ActiveWork/SessionDetail.tsx +180 -0
- package/src/components/custom/ActiveWork/SessionList.stories.tsx +69 -0
- package/src/components/custom/ActiveWork/SessionList.test.tsx +78 -0
- package/src/components/custom/ActiveWork/SessionList.tsx +103 -0
- package/src/components/custom/ActiveWork/SessionListItem.stories.tsx +64 -0
- package/src/components/custom/ActiveWork/SessionListItem.test.tsx +62 -0
- package/src/components/custom/ActiveWork/SessionListItem.tsx +152 -0
- package/src/components/custom/ActiveWork/SessionReader.stories.tsx +113 -0
- package/src/components/custom/ActiveWork/SeverityLabel.stories.tsx +51 -0
- package/src/components/custom/ActiveWork/SeverityLabel.test.tsx +68 -0
- package/src/components/custom/ActiveWork/SeverityLabel.tsx +97 -0
- package/src/components/custom/ActiveWork/TaskRow.stories.tsx +63 -0
- package/src/components/custom/ActiveWork/TaskRow.test.tsx +112 -0
- package/src/components/custom/ActiveWork/TaskRow.tsx +176 -0
- package/src/components/custom/ActiveWork/TaskTable.stories.tsx +123 -0
- package/src/components/custom/ActiveWork/TaskTable.test.tsx +233 -0
- package/src/components/custom/ActiveWork/TaskTable.tsx +321 -0
- package/src/components/custom/ActiveWork/active-work-depth.test.tsx +102 -0
- package/src/components/custom/ActiveWork/file-history-fixture.ts +91 -0
- package/src/components/custom/ActiveWork/format-time.test.ts +23 -0
- package/src/components/custom/ActiveWork/format-time.ts +32 -0
- package/src/components/custom/ActiveWork/index.ts +19 -0
- package/src/components/custom/ActiveWork/initiative-fixture.ts +104 -0
- package/src/components/custom/ActiveWork/session-fixture.ts +267 -0
- package/src/components/custom/ActiveWork/session-linkers.ts +56 -0
- package/src/components/custom/ActiveWork/task-list-fixture.ts +97 -0
- package/src/components/custom/CircularTimer/CircularTimer.stories.tsx +4 -3
- package/src/components/custom/DateTime/DateTime.stories.tsx +2 -1
- package/src/components/custom/DateTime/DateTime.test.tsx +3 -1
- package/src/components/custom/EmptyState/EmptyState.stories.tsx +22 -9
- package/src/components/custom/EmptyState/EmptyState.test.tsx +7 -13
- package/src/components/custom/EmptyState/EmptyState.tsx +4 -18
- package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +4 -3
- package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
- package/src/components/custom/Fatigue/GhostSpark.stories.tsx +4 -3
- package/src/components/custom/Fatigue/LiveFatigueCard.stories.tsx +2 -2
- package/src/components/custom/Fatigue/LiveFatigueCard.tsx +8 -4
- package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +116 -6
- package/src/components/custom/Fatigue/LiveFatiguePanel.test.tsx +134 -0
- package/src/components/custom/Fatigue/LiveFatiguePanel.tsx +54 -83
- package/src/components/custom/Fatigue/README.md +40 -3
- package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
- package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +2 -1
- package/src/components/custom/Fatigue/VelocityHero.stories.tsx +4 -3
- package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
- package/src/components/custom/Fatigue/fatigue-mock.test.ts +0 -5
- package/src/components/custom/Fatigue/fatigue-mock.ts +2 -10
- package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -0
- package/src/components/custom/Fatigue/index.ts +17 -5
- package/src/components/custom/Fatigue/panel-layout.test.ts +149 -0
- package/src/components/custom/Fatigue/panel-layout.ts +185 -0
- package/src/components/custom/Gauge/Gauge.stories.tsx +2 -2
- package/src/components/custom/Gauge/Gauge.test.tsx +1 -1
- package/src/components/custom/Gauge/Gauge.tsx +4 -1
- package/src/components/custom/Metric/Metric.stories.tsx +10 -1
- package/src/components/custom/Metric/Metric.test.tsx +1 -3
- package/src/components/custom/Metric/Metric.tsx +5 -20
- package/src/components/custom/Prose/MarkdownProse.stories.tsx +88 -0
- package/src/components/custom/Prose/MarkdownProse.test.tsx +87 -0
- package/src/components/custom/Prose/MarkdownProse.tsx +201 -0
- package/src/components/custom/Prose/README.md +58 -0
- package/src/components/custom/Prose/index.ts +1 -0
- package/src/components/custom/Scatter/Scatter.stories.tsx +46 -8
- package/src/components/custom/Scatter/Scatter.test.tsx +2 -2
- package/src/components/custom/Scatter/Scatter.tsx +116 -14
- package/src/components/custom/Sidebar/Sidebar.stories.tsx +40 -7
- package/src/components/custom/Sidebar/Sidebar.test.tsx +5 -1
- package/src/components/custom/Sidebar/Sidebar.tsx +16 -33
- package/src/components/custom/Table/Table.stories.tsx +98 -15
- package/src/components/custom/Table/Table.test.tsx +273 -86
- package/src/components/custom/Table/Table.tsx +159 -67
- package/src/components/custom/Table/column-fit.test.ts +75 -0
- package/src/components/custom/Table/column-fit.ts +116 -0
- package/src/components/custom/Table/index.ts +9 -0
- package/src/components/custom/TimerReadout/TimerReadout.stories.tsx +8 -6
- package/src/components/custom/Treemap/Treemap.stories.tsx +2 -2
- package/src/components/custom/Treemap/Treemap.test.tsx +1 -1
- package/src/components/custom/Treemap/Treemap.tsx +7 -2
- package/src/components/custom/Typography/Typography.stories.tsx +28 -1
- package/src/components/custom/Typography/Typography.test.tsx +34 -0
- package/src/components/custom/Typography/Typography.tsx +6 -0
- package/src/components/custom/Typography/index.ts +1 -8
- package/src/components/custom/Workout/ActiveWorkoutPage.stories.tsx +9 -1
- package/src/components/custom/Workout/BaseBadge.stories.tsx +19 -7
- package/src/components/custom/Workout/BaseBadge.test.tsx +31 -11
- package/src/components/custom/Workout/BaseBadge.tsx +3 -0
- package/src/components/custom/Workout/BodyMap.stories.tsx +4 -1
- package/src/components/custom/Workout/BodyMap.tsx +3 -1
- package/src/components/custom/Workout/BodyMapDetailPanel.stories.tsx +16 -4
- package/src/components/custom/Workout/BodyMapDetailPanel.test.tsx +11 -15
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +45 -9
- package/src/components/custom/Workout/CapacityBandChart.stories.tsx +10 -8
- package/src/components/custom/Workout/CapacityBandChart.test.tsx +24 -51
- package/src/components/custom/Workout/CapacityBandChart.tsx +139 -108
- package/src/components/custom/Workout/DeviationBar.stories.tsx +1 -1
- package/src/components/custom/Workout/DeviationBar.test.tsx +5 -2
- package/src/components/custom/Workout/DeviationBar.tsx +21 -16
- package/src/components/custom/Workout/DualVelocityStrip.stories.tsx +182 -0
- package/src/components/custom/Workout/DualVelocityStrip.test.tsx +3 -2
- package/src/components/custom/Workout/ExerciseCard.stories.tsx +8 -7
- package/src/components/custom/Workout/ExerciseCard.test.tsx +13 -3
- package/src/components/custom/Workout/ExerciseCard.tsx +42 -51
- package/src/components/custom/Workout/ExerciseCardHeading.stories.tsx +7 -7
- package/src/components/custom/Workout/ExerciseDetailPage.stories.tsx +9 -1
- package/src/components/custom/Workout/ExerciseHeading.stories.tsx +8 -8
- package/src/components/custom/Workout/ExerciseHeading.tsx +8 -5
- package/src/components/custom/Workout/ExerciseIndicator.stories.tsx +6 -4
- package/src/components/custom/Workout/ExerciseIndicator.test.tsx +27 -11
- package/src/components/custom/Workout/ExerciseIndicator.tsx +14 -15
- package/src/components/custom/Workout/FatigueMeter.stories.tsx +5 -5
- package/src/components/custom/Workout/InputBar.stories.tsx +4 -5
- package/src/components/custom/Workout/IntensityBar.stories.tsx +1 -1
- package/src/components/custom/Workout/IntensityBar.test.tsx +5 -1
- package/src/components/custom/Workout/IntensityBar.tsx +4 -2
- package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +5 -4
- package/src/components/custom/Workout/MesoCard.stories.tsx +4 -1
- package/src/components/custom/Workout/MesoCard.test.tsx +7 -18
- package/src/components/custom/Workout/MesoCard.tsx +12 -9
- package/src/components/custom/Workout/MesoProgressBar.stories.tsx +1 -1
- package/src/components/custom/Workout/MesoProgressBar.test.tsx +18 -11
- package/src/components/custom/Workout/MesoProgressBar.tsx +15 -13
- package/src/components/custom/Workout/MesoStatusCard.stories.tsx +2 -1
- package/src/components/custom/Workout/MesoStatusCard.test.tsx +14 -44
- package/src/components/custom/Workout/MesoStatusCard.tsx +9 -23
- package/src/components/custom/Workout/MetricTiles.stories.tsx +3 -2
- package/src/components/custom/Workout/MuscleGroupChip.stories.tsx +2 -8
- package/src/components/custom/Workout/MuscleGroupChip.test.tsx +23 -31
- package/src/components/custom/Workout/MuscleGroupChip.tsx +28 -67
- package/src/components/custom/Workout/PlaceholderStrip.stories.tsx +1 -1
- package/src/components/custom/Workout/PlaceholderStrip.test.tsx +17 -10
- package/src/components/custom/Workout/PlaceholderStrip.tsx +9 -8
- package/src/components/custom/Workout/PrBadge.stories.tsx +2 -1
- package/src/components/custom/Workout/PrBadge.test.tsx +3 -9
- package/src/components/custom/Workout/PrBadge.tsx +13 -17
- package/src/components/custom/Workout/PrHistoryModal.stories.tsx +4 -1
- package/src/components/custom/Workout/PrHistoryModal.test.tsx +13 -36
- package/src/components/custom/Workout/PrHistoryModal.tsx +8 -4
- package/src/components/custom/Workout/ProgramPlanningPage.stories.tsx +6 -1
- package/src/components/custom/Workout/README.md +11 -6
- package/src/components/custom/Workout/ReadinessCheck.stories.tsx +3 -2
- package/src/components/custom/Workout/ReadinessCheck.test.tsx +12 -18
- package/src/components/custom/Workout/ReadinessCheck.tsx +19 -3
- package/src/components/custom/Workout/RestTimer.stories.tsx +3 -2
- package/src/components/custom/Workout/ScheduleTiles.stories.tsx +3 -2
- package/src/components/custom/Workout/ScheduleTiles.test.tsx +3 -4
- package/src/components/custom/Workout/ScheduleTiles.tsx +4 -7
- package/src/components/custom/Workout/SegmentedBar.stories.tsx +5 -5
- package/src/components/custom/Workout/SegmentedBar.tsx +6 -2
- package/src/components/custom/Workout/SegmentedProgressBar.stories.tsx +5 -5
- package/src/components/custom/Workout/SessionHeader.stories.tsx +6 -6
- package/src/components/custom/Workout/SessionHeader.tsx +12 -12
- package/src/components/custom/Workout/SessionRail.stories.tsx +12 -11
- package/src/components/custom/Workout/SessionRail.tsx +7 -9
- package/src/components/custom/Workout/SetBar.stories.tsx +10 -6
- package/src/components/custom/Workout/SetBar.test.tsx +49 -4
- package/src/components/custom/Workout/SetBar.tsx +38 -12
- package/src/components/custom/Workout/SetRow.stories.tsx +3 -2
- package/src/components/custom/Workout/SetRow.test.tsx +16 -2
- package/src/components/custom/Workout/SetRow.tsx +61 -23
- package/src/components/custom/Workout/SetStrip.stories.tsx +60 -5
- package/src/components/custom/Workout/SetStrip.test.tsx +25 -0
- package/src/components/custom/Workout/SetStrip.tsx +24 -4
- package/src/components/custom/Workout/SetTableHeader.stories.tsx +6 -6
- package/src/components/custom/Workout/SetTableHeader.tsx +9 -12
- package/src/components/custom/Workout/SetsRepsLoad.stories.tsx +7 -7
- package/src/components/custom/Workout/SetsRepsLoad.tsx +3 -5
- package/src/components/custom/Workout/Sparkline.stories.tsx +1 -1
- package/src/components/custom/Workout/Sparkline.test.tsx +37 -19
- package/src/components/custom/Workout/Sparkline.tsx +14 -18
- package/src/components/custom/Workout/StatusDot.stories.tsx +1 -1
- package/src/components/custom/Workout/StatusDot.test.tsx +44 -5
- package/src/components/custom/Workout/StatusDot.tsx +93 -63
- package/src/components/custom/Workout/StatusPill.stories.tsx +1 -1
- package/src/components/custom/Workout/StatusPill.test.tsx +6 -15
- package/src/components/custom/Workout/StatusPill.tsx +27 -38
- package/src/components/custom/Workout/StrengthTrendChart.stories.tsx +9 -3
- package/src/components/custom/Workout/StrengthTrendChart.test.tsx +15 -37
- package/src/components/custom/Workout/StrengthTrendChart.tsx +31 -30
- package/src/components/custom/Workout/SupersetWrapper.stories.tsx +27 -64
- package/src/components/custom/Workout/SupersetWrapper.test.tsx +16 -14
- package/src/components/custom/Workout/SupersetWrapper.tsx +17 -21
- package/src/components/custom/Workout/TempoDisplay.stories.tsx +22 -7
- package/src/components/custom/Workout/TempoDisplay.test.tsx +18 -4
- package/src/components/custom/Workout/TrainingStatusPage.stories.tsx +9 -1
- package/src/components/custom/Workout/VelocityStrip.compact.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.dual.stories.tsx +7 -4
- package/src/components/custom/Workout/VelocityStrip.expanded.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.hero.stories.tsx +4 -1
- package/src/components/custom/Workout/VelocityStrip.stories.tsx +12 -6
- package/src/components/custom/Workout/VelocityStrip.tsx +3 -0
- package/src/components/custom/Workout/VolumeLandmarkBar.stories.tsx +6 -7
- package/src/components/custom/Workout/VolumeLandmarkBar.tsx +15 -6
- package/src/components/custom/Workout/WeekRow.stories.tsx +4 -1
- package/src/components/custom/Workout/WeekRow.test.tsx +18 -15
- package/src/components/custom/Workout/WeekRow.tsx +23 -16
- package/src/components/custom/Workout/WeightBadge.stories.tsx +2 -1
- package/src/components/custom/Workout/WeightBadge.test.tsx +50 -19
- package/src/components/custom/Workout/WeightBadge.tsx +28 -27
- package/src/components/custom/Workout/WorkoutCard.stories.tsx +6 -1
- package/src/components/custom/Workout/WorkoutCard.test.tsx +18 -0
- package/src/components/custom/Workout/WorkoutCard.tsx +35 -57
- package/src/components/custom/Workout/WorkoutPill.stories.tsx +5 -2
- package/src/components/custom/Workout/WorkoutPill.test.tsx +39 -7
- package/src/components/custom/Workout/WorkoutPill.tsx +88 -57
- package/src/components/custom/Workout/ZoneTrack.stories.tsx +7 -6
- package/src/components/custom/Workout/ZoneTrack.tsx +10 -9
- package/src/components/custom/Workout/index.ts +5 -0
- package/src/components/custom/Workout/metricText.stories.tsx +6 -5
- package/src/components/custom/Workout/metricText.tsx +4 -0
- package/src/components/custom/Workout/setHeadingKit.tsx +207 -26
- package/src/components/custom/charts/README.md +61 -0
- package/src/components/custom/charts/SetBarChart.test.tsx +30 -1
- package/src/components/custom/charts/SetBarChart.tsx +42 -4
- package/src/components/custom/charts/SparkBars.stories.tsx +55 -0
- package/src/components/custom/charts/SparkBars.test.tsx +69 -0
- package/src/components/custom/charts/SparkBars.tsx +85 -0
- package/src/components/custom/charts/index.ts +3 -0
- package/src/components/custom/index.ts +3 -0
- package/src/components/custom/stepper/Stepper.stories.tsx +13 -10
- package/src/components/custom/stepper/Stepper.test.tsx +1 -7
- package/src/components/custom/stepper/Stepper.tsx +13 -28
- package/src/components/icons/icons.stories.tsx +1 -1
- package/src/components/icons/icons.tsx +51 -0
- package/src/components/shell/AppShell.stories.tsx +150 -0
- package/src/components/shell/AppShell.test.tsx +70 -0
- package/src/components/shell/AppShell.tsx +90 -0
- package/src/components/shell/BrandLockup.stories.tsx +66 -5
- package/src/components/shell/BrandLockup.test.tsx +34 -1
- package/src/components/shell/BrandLockup.tsx +27 -11
- package/src/components/shell/NavItem.stories.tsx +4 -4
- package/src/components/shell/NavItem.test.tsx +17 -0
- package/src/components/shell/NavItem.tsx +17 -5
- package/src/components/shell/README.md +89 -26
- package/src/components/shell/SideNav.stories.tsx +38 -7
- package/src/components/shell/SideNav.test.tsx +16 -8
- package/src/components/shell/SideNav.tsx +17 -17
- package/src/components/shell/TopBar.stories.tsx +44 -19
- package/src/components/shell/TopBar.test.tsx +34 -12
- package/src/components/shell/TopBar.tsx +61 -40
- package/src/components/shell/brands.tsx +66 -0
- package/src/components/shell/index.ts +9 -8
- package/src/components/shell/{DeviceIndicator.stories.tsx → workout/DeviceIndicator.stories.tsx} +2 -2
- package/src/components/shell/{DeviceIndicator.tsx → workout/DeviceIndicator.tsx} +2 -2
- package/src/components/shell/{DeviceMenu.stories.tsx → workout/DeviceMenu.stories.tsx} +2 -2
- package/src/components/shell/{DeviceMenu.tsx → workout/DeviceMenu.tsx} +3 -3
- package/src/components/shell/{DeviceRow.stories.tsx → workout/DeviceRow.stories.tsx} +2 -2
- package/src/components/shell/{DeviceRow.tsx → workout/DeviceRow.tsx} +3 -3
- package/src/components/shell/{SessionStatePill.stories.tsx → workout/SessionStatePill.stories.tsx} +2 -2
- package/src/components/shell/{SessionStatePill.tsx → workout/SessionStatePill.tsx} +5 -3
- package/src/components/shell/workout/WorkoutShell.stories.tsx +71 -0
- package/src/components/shell/{DashboardShell.test.tsx → workout/WorkoutShell.test.tsx} +19 -8
- package/src/components/shell/workout/WorkoutShell.tsx +77 -0
- package/src/components/shell/workout/WorkoutTopBar.stories.tsx +58 -0
- package/src/components/shell/workout/WorkoutTopBar.test.tsx +39 -0
- package/src/components/shell/workout/WorkoutTopBar.tsx +52 -0
- package/src/components/shell/workout/index.ts +9 -0
- package/src/components/shell/workout/workoutNavItems.tsx +16 -0
- package/src/components/ui/README.md +110 -0
- package/src/components/ui/alert/Alert.stories.tsx +1 -1
- package/src/components/ui/autocomplete/Autocomplete.stories.tsx +11 -13
- package/src/components/ui/autocomplete/Autocomplete.test.tsx +7 -25
- package/src/components/ui/autocomplete/Autocomplete.tsx +21 -28
- package/src/components/ui/avatar/Avatar.stories.tsx +1 -1
- package/src/components/ui/avatar/Avatar.tsx +2 -10
- package/src/components/ui/badge/Badge.stories.tsx +83 -28
- package/src/components/ui/badge/Badge.test.tsx +19 -3
- package/src/components/ui/badge/Badge.tsx +48 -55
- package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +1 -1
- package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +4 -16
- package/src/components/ui/button/Button.stories.tsx +46 -12
- package/src/components/ui/button/Button.tsx +32 -25
- package/src/components/ui/card/Card.stories.tsx +90 -94
- package/src/components/ui/card/Card.test.tsx +80 -6
- package/src/components/ui/card/Card.tsx +150 -203
- package/src/components/ui/checkbox/Checkbox.stories.tsx +1 -1
- package/src/components/ui/checkbox/Checkbox.tsx +6 -26
- package/src/components/ui/chip/Chip.stories.tsx +37 -13
- package/src/components/ui/chip/Chip.test.tsx +10 -6
- package/src/components/ui/chip/Chip.tsx +76 -91
- package/src/components/ui/collapse/Collapse.stories.tsx +23 -23
- package/src/components/ui/collapse/Collapse.tsx +6 -11
- package/src/components/ui/data-row/DataRow.stories.tsx +9 -2
- package/src/components/ui/data-row/DataRow.test.tsx +5 -15
- package/src/components/ui/data-row/DataRow.tsx +18 -7
- package/src/components/ui/divider/Divider.stories.tsx +1 -1
- package/src/components/ui/divider/Divider.tsx +1 -5
- package/src/components/ui/drawer/Drawer.stories.tsx +5 -16
- package/src/components/ui/drawer/Drawer.tsx +13 -30
- package/src/components/ui/floating-overlay-depth.test.tsx +143 -0
- package/src/components/ui/form-field/FormField.stories.tsx +6 -20
- package/src/components/ui/form-field/FormField.test.tsx +1 -5
- package/src/components/ui/form-field/FormField.tsx +10 -46
- package/src/components/ui/help-tip/HelpTip.stories.tsx +8 -19
- package/src/components/ui/help-tip/HelpTip.test.tsx +1 -3
- package/src/components/ui/help-tip/HelpTip.tsx +21 -22
- package/src/components/ui/help-tip/index.ts +7 -1
- package/src/components/ui/icon-box/IconBox.stories.tsx +1 -1
- package/src/components/ui/icon-box/IconBox.test.tsx +1 -7
- package/src/components/ui/icon-box/IconBox.tsx +2 -12
- package/src/components/ui/indicator/Indicator.stories.tsx +1 -1
- package/src/components/ui/indicator/Indicator.tsx +20 -14
- package/src/components/ui/input/Input.stories.tsx +3 -11
- package/src/components/ui/input/Input.test.tsx +2 -10
- package/src/components/ui/input/Input.tsx +10 -25
- package/src/components/ui/input/index.ts +7 -1
- package/src/components/ui/link/Link.stories.tsx +19 -7
- package/src/components/ui/list-item/ListItem.stories.tsx +11 -2
- package/src/components/ui/list-item/ListItem.tsx +2 -9
- package/src/components/ui/menu/Menu.stories.tsx +21 -15
- package/src/components/ui/menu/Menu.test.tsx +2 -11
- package/src/components/ui/menu/Menu.tsx +12 -14
- package/src/components/ui/menu/index.ts +8 -1
- package/src/components/ui/modal/Modal.stories.tsx +2 -2
- package/src/components/ui/modal/Modal.tsx +29 -19
- package/src/components/ui/pill/Pill.stories.tsx +58 -23
- package/src/components/ui/pill/Pill.test.tsx +101 -3
- package/src/components/ui/pill/Pill.tsx +164 -49
- package/src/components/ui/pill/index.ts +1 -1
- package/src/components/ui/popover/Popover.stories.tsx +5 -7
- package/src/components/ui/popover/Popover.test.tsx +1 -6
- package/src/components/ui/popover/Popover.tsx +20 -15
- package/src/components/ui/popover/index.ts +7 -1
- package/src/components/ui/progress/Progress.stories.tsx +3 -12
- package/src/components/ui/progress/Progress.test.tsx +1 -5
- package/src/components/ui/radio/Radio.stories.tsx +42 -21
- package/src/components/ui/radio/Radio.test.tsx +6 -2
- package/src/components/ui/radio/Radio.tsx +23 -22
- package/src/components/ui/section/Section.stories.tsx +5 -14
- package/src/components/ui/section/Section.test.tsx +1 -6
- package/src/components/ui/section/Section.tsx +1 -3
- package/src/components/ui/section/index.ts +1 -5
- package/src/components/ui/select/Select.stories.tsx +3 -13
- package/src/components/ui/select/Select.test.tsx +2 -11
- package/src/components/ui/select/Select.tsx +14 -14
- package/src/components/ui/skeleton/Skeleton.stories.tsx +3 -11
- package/src/components/ui/skeleton/Skeleton.tsx +3 -14
- package/src/components/ui/skeleton/index.ts +1 -7
- package/src/components/ui/spinner/Spinner.stories.tsx +1 -1
- package/src/components/ui/spinner/Spinner.tsx +1 -4
- package/src/components/ui/stack/Stack.stories.tsx +1 -1
- package/src/components/ui/stack/Stack.tsx +1 -1
- package/src/components/ui/surface/Surface.stories.tsx +17 -5
- package/src/components/ui/surface/Surface.test.tsx +88 -28
- package/src/components/ui/surface/Surface.tsx +37 -87
- package/src/components/ui/surface/SurfaceContext.ts +22 -62
- package/src/components/ui/surface/index.ts +8 -0
- package/src/components/ui/surface/resolveSurface.ts +98 -0
- package/src/components/ui/surface/surface.contract.test.ts +6 -1
- package/src/components/ui/switch/Switch.stories.tsx +1 -1
- package/src/components/ui/switch/Switch.tsx +7 -6
- package/src/components/ui/tabs/Tabs.stories.tsx +1 -1
- package/src/components/ui/tabs/Tabs.tsx +7 -22
- package/src/components/ui/tabs/index.ts +1 -7
- package/src/components/ui/tile/Tile.stories.tsx +1 -1
- package/src/components/ui/tile/Tile.tsx +3 -0
- package/src/components/ui/toast/Toast.stories.tsx +1 -1
- package/src/components/ui/toast/Toast.test.tsx +2 -8
- package/src/components/ui/toast/Toast.tsx +43 -53
- package/src/components/ui/toast/index.ts +0 -1
- package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +92 -71
- package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +3 -18
- package/src/components/ui/toolbar-button/ToolbarButton.tsx +25 -43
- package/src/components/ui/tooltip/Tooltip.stories.tsx +12 -3
- package/src/components/ui/tooltip/Tooltip.test.tsx +21 -3
- package/src/components/ui/tooltip/Tooltip.tsx +55 -36
- package/src/components/ui/tooltip/index.ts +1 -1
- package/src/components/ui/trigger/TriggerSurface.test.tsx +215 -0
- package/src/components/ui/trigger/TriggerSurface.tsx +81 -0
- package/src/components/ui/trigger/index.ts +2 -0
- package/src/stories/PresetShowcase.stories.tsx +100 -47
- package/src/test/no-device-internals.test.ts +3 -3
- package/src/theme/ChoosingTokens.stories.tsx +48 -0
- package/src/theme/ColorPalettes.stories.tsx +62 -45
- package/src/theme/ColorPrimitives.stories.tsx +35 -35
- package/src/theme/Depth.stories.tsx +132 -65
- package/src/theme/DepthCalibration.stories.tsx +23 -21
- package/src/theme/ThemeProvider.test.tsx +4 -4
- package/src/theme/barrel.ts +7 -6
- package/src/theme/color-stories.coverage.test.ts +1 -1
- package/src/theme/color-utils.ts +41 -29
- package/src/theme/config.completeness.test.ts +1 -1
- package/src/theme/config.ts +28 -0
- package/src/theme/elevation.test.ts +82 -56
- package/src/theme/elevation.ts +77 -561
- package/src/theme/global.css +30 -2
- package/src/theme/grey-ramp.test.ts +24 -8
- package/src/theme/lift.test.ts +39 -0
- package/src/theme/lift.ts +102 -0
- package/src/theme/materials.test.ts +5 -2
- package/src/theme/materials.ts +38 -4
- package/src/theme/native-theming-guard.test.ts +5 -5
- package/src/theme/presets/apply.ts +4 -0
- package/src/theme/presets/audiobook.ts +5 -2
- package/src/theme/presets/default.ts +4 -0
- package/src/theme/presets/index.ts +14 -1
- package/src/theme/presets/types.ts +1 -1
- package/src/theme/semantic-contrast.test.ts +13 -4
- package/src/theme/status-distinctness.test.ts +66 -0
- package/src/theme/surface-planes.test.ts +37 -0
- package/src/theme/surface-planes.ts +68 -0
- package/src/theme/token-export-guard.test.ts +1 -3
- package/src/theme/tokens/primitives.test.ts +15 -7
- package/src/theme/tokens/primitives.ts +65 -33
- package/src/theme/tokens/semantic.ts +71 -37
- package/src/theme/wash-ladder.test.ts +58 -0
- package/src/theme/workout-tokens.ts +1 -7
- package/src/types/jest-axe.d.ts +2 -6
- package/src/types/raw-md.d.ts +5 -0
- package/src/utils/colors.ts +4 -4
- package/src/utils/form.ts +1 -3
- package/src/utils/index.ts +2 -7
- package/src/utils/number-format.ts +17 -0
- package/src/utils/workout-format.ts +15 -6
- package/src/web-jsx/jsx-runtime.ts +1 -5
- package/tailwind.config.js +5 -0
- package/src/components/custom/Workout/ExerciseCardUnified.stories.tsx +0 -151
- package/src/components/custom/Workout/RowInventory.stories.tsx +0 -408
- package/src/components/custom/Workout/S3FullRail.stories.tsx +0 -46
- package/src/components/custom/Workout/S3SessionPace.stories.tsx +0 -95
- package/src/components/custom/Workout/S3SessionRailHeading.stories.tsx +0 -61
- package/src/components/custom/Workout/S3SetTypes.stories.tsx +0 -176
- package/src/components/custom/Workout/S3WorkoutExpansion.stories.tsx +0 -240
- package/src/components/shell/DashboardShell.stories.tsx +0 -65
- package/src/components/shell/DashboardShell.tsx +0 -75
- package/src/components/shell/SessionRailSpecimen.stories.tsx +0 -753
- package/src/theme/elevation.stories.tsx +0 -346
- package/src/utils/useTheme.ts +0 -72
- /package/src/components/shell/{DeviceIndicator.test.tsx → workout/DeviceIndicator.test.tsx} +0 -0
- /package/src/components/shell/{DeviceMenu.test.tsx → workout/DeviceMenu.test.tsx} +0 -0
- /package/src/components/shell/{DeviceRow.test.tsx → workout/DeviceRow.test.tsx} +0 -0
- /package/src/components/shell/{SessionStatePill.test.tsx → workout/SessionStatePill.test.tsx} +0 -0
|
@@ -66,7 +66,9 @@ const PLANE_BY_STEP: Record<number, string> = Object.fromEntries(
|
|
|
66
66
|
/** Steps whose value is byte-identical to what shipped in v0.10.0. */
|
|
67
67
|
const ANCHOR_STEPS = new Set<number>(Object.values(SURFACE_PLANE_STEPS))
|
|
68
68
|
|
|
69
|
-
const GREY_STEPS = Object.keys(greyRamp)
|
|
69
|
+
const GREY_STEPS = Object.keys(greyRamp)
|
|
70
|
+
.map(Number)
|
|
71
|
+
.sort((a, b) => a - b)
|
|
70
72
|
|
|
71
73
|
/**
|
|
72
74
|
* The grey ramp, rendered as a numbered scale with its plane aliases.
|
|
@@ -92,7 +94,10 @@ function GreyRampRow() {
|
|
|
92
94
|
borderColor: ANCHOR_STEPS.has(step) ? '#FF7900' : SWATCH_BORDER,
|
|
93
95
|
}}
|
|
94
96
|
/>
|
|
95
|
-
<Text
|
|
97
|
+
<Text
|
|
98
|
+
className="text-text-primary"
|
|
99
|
+
style={{ fontSize: 10, fontWeight: '600', marginTop: 3 }}
|
|
100
|
+
>
|
|
96
101
|
{step}
|
|
97
102
|
{ANCHOR_STEPS.has(step) ? ' ★' : ''}
|
|
98
103
|
</Text>
|
|
@@ -115,11 +120,10 @@ export const Ramps: StoryObj = {
|
|
|
115
120
|
<View style={{ padding: 24 }}>
|
|
116
121
|
<Text className="text-2xl font-bold text-text-primary mb-2">Ramps</Text>
|
|
117
122
|
<SectionIntro>
|
|
118
|
-
Every raw colour value titan ships, as ordered scales. Nothing here carries meaning — a
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
this page is current and safe to pick.
|
|
123
|
+
Every raw colour value titan ships, as ordered scales. Nothing here carries meaning — a ramp
|
|
124
|
+
step becomes a border or a status only when a semantic token or a palette references it,
|
|
125
|
+
which is what <Text className="font-semibold">Foundations/Color/Palettes</Text> documents.
|
|
126
|
+
Everything on this page is current and safe to pick.
|
|
123
127
|
</SectionIntro>
|
|
124
128
|
|
|
125
129
|
<Text className="text-text-tertiary text-xs mb-6">
|
|
@@ -127,21 +131,20 @@ export const Ramps: StoryObj = {
|
|
|
127
131
|
<Text className="font-semibold">neutral</Text>,{' '}
|
|
128
132
|
<Text className="font-semibold">redVivid</Text> or the support{' '}
|
|
129
133
|
<Text className="font-semibold">blue</Text>/<Text className="font-semibold">red</Text>{' '}
|
|
130
|
-
scales? All five were DELETED in TD-07.14, not shelved. The two grey scales folded into
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
sources/design/foundations/warm-grey-ramp/.
|
|
134
|
+
scales? All five were DELETED in TD-07.14, not shelved. The two grey scales folded into the
|
|
135
|
+
warm ramp below — they were cold (neutral ran R−B down to −26) while the surfaces had been
|
|
136
|
+
warm since v0.10.0, and nothing ever reconciled the two. The chromatics moved to the OKLCH
|
|
137
|
+
ramps above. Spec and generator: sources/design/foundations/warm-grey-ramp/.
|
|
135
138
|
</Text>
|
|
136
139
|
|
|
137
140
|
<SectionTitle>Chromatic — OKLCH tonal ramps</SectionTitle>
|
|
138
141
|
<Text className="text-text-secondary text-xs mb-4">
|
|
139
|
-
Seven OKLCH-generated hue ramps, 11 perceptual steps each (50 → 950), built with
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
Seven OKLCH-generated hue ramps, 11 perceptual steps each (50 → 950), built with hue-torsion
|
|
143
|
+
and a chroma arc anchored through the brand/semantic hexes. These are the source of truth
|
|
144
|
+
for chromatic hexes: the categorical, diverging, effort and fatigue palettes are all
|
|
145
|
+
references into these steps rather than duplicated values, so re-tuning a ramp moves them
|
|
146
|
+
together. Amber absorbs the former yellow (lemon → warm body) and cyan absorbs the former
|
|
147
|
+
steel.
|
|
145
148
|
</Text>
|
|
146
149
|
{CHROMATIC_RAMPS.map(([key, name]) => (
|
|
147
150
|
<ScaleRow key={key} name={name} scale={primitiveRamps[key]} />
|
|
@@ -157,16 +160,15 @@ export const Ramps: StoryObj = {
|
|
|
157
160
|
set of names.
|
|
158
161
|
</Text>
|
|
159
162
|
<Text className="text-text-secondary text-xs mb-4">
|
|
160
|
-
Two things about the numbering, both deliberate.{' '}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
<Text className="font-semibold">
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
pressed></Text> kept collapsing into it.
|
|
163
|
+
Two things about the numbering, both deliberate. <Text className="font-semibold">975</Text>{' '}
|
|
164
|
+
sits past the end of the shared grid: the canonical L* ladder — the median of the seven
|
|
165
|
+
chromatic ramps — stops at L*10.3, which is step 950, and the bezel is L*3.8. There was no
|
|
166
|
+
number left for it. <Text className="font-semibold">850</Text> and{' '}
|
|
167
|
+
<Text className="font-semibold">875</Text> are quarter-steps because overlay, raised and
|
|
168
|
+
elevated sit only ~2.7 L* apart and all three collide on 900 at normal resolution. There is
|
|
169
|
+
deliberately no <Text className="font-semibold">inset</Text>: at ΔE 1.10 from the frame it
|
|
170
|
+
was an imperceptible duplicate, which is why{' '}
|
|
171
|
+
<Text className="font-semibold"><Surface pressed></Text> kept collapsing into it.
|
|
170
172
|
</Text>
|
|
171
173
|
<GreyRampRow />
|
|
172
174
|
<Text className="text-text-tertiary text-xs mb-4">
|
|
@@ -258,8 +260,8 @@ export const Accessibility: StoryObj = {
|
|
|
258
260
|
<SectionIntro>
|
|
259
261
|
How the raw material behaves for viewers who cannot separate the hues, and under text.
|
|
260
262
|
Dichromacy is simulated with the Machado-2009 matrices at severity 1.0. Converging strips
|
|
261
|
-
across two swatches mean those two are the same colour to that viewer — which is a
|
|
262
|
-
|
|
263
|
+
across two swatches mean those two are the same colour to that viewer — which is a problem
|
|
264
|
+
only where hue is carrying the meaning on its own.
|
|
263
265
|
</SectionIntro>
|
|
264
266
|
|
|
265
267
|
<SectionTitle>Ramp mid-steps (500)</SectionTitle>
|
|
@@ -269,9 +271,7 @@ export const Accessibility: StoryObj = {
|
|
|
269
271
|
below fans its picks across lightness instead of taking all seven at 500, and why the
|
|
270
272
|
ordered scales in Palettes encode magnitude in lightness rather than hue.
|
|
271
273
|
</Text>
|
|
272
|
-
<View
|
|
273
|
-
style={{ flexDirection: 'row', gap: 6, marginBottom: 6, paddingLeft: CVD_LABEL_WIDTH }}
|
|
274
|
-
>
|
|
274
|
+
<View style={{ flexDirection: 'row', gap: 6, marginBottom: 6, paddingLeft: CVD_LABEL_WIDTH }}>
|
|
275
275
|
{RAMP_MIDS.map(({ name, hex }) => (
|
|
276
276
|
<View key={name} style={{ alignItems: 'center' }}>
|
|
277
277
|
<View
|
|
@@ -297,8 +297,8 @@ export const Accessibility: StoryObj = {
|
|
|
297
297
|
<SectionTitle>Categorical series — in-place text contrast</SectionTitle>
|
|
298
298
|
<Text className="text-text-secondary text-xs mb-3">
|
|
299
299
|
The palette that has to survive this test in production. All pairs hold ΔE ≥ 8 through the
|
|
300
|
-
first {CATEGORICAL_CVD_SAFE_MAX}; the 7th is extended and wants a legend. The palette
|
|
301
|
-
|
|
300
|
+
first {CATEGORICAL_CVD_SAFE_MAX}; the 7th is extended and wants a legend. The palette itself
|
|
301
|
+
is documented in Palettes — this is the validation of it.
|
|
302
302
|
</Text>
|
|
303
303
|
{(['default', 'dark'] as const).map((variant) => {
|
|
304
304
|
const colors = categoricalPalette[variant]
|
|
@@ -3,12 +3,13 @@ import { View, Text } from 'react-native'
|
|
|
3
3
|
import { greyRamp } from './tokens/primitives'
|
|
4
4
|
import { getSemanticColors } from './tokens/semantic'
|
|
5
5
|
import {
|
|
6
|
+
ELEVATION_PLANE,
|
|
7
|
+
FLOATING_ELEVATION_MIN,
|
|
6
8
|
getElevationSurface,
|
|
7
9
|
getElevationShadow,
|
|
8
|
-
getBaseSurfaceColor,
|
|
9
|
-
FLOATING_ELEVATION_MIN,
|
|
10
10
|
type ElevationLevel,
|
|
11
11
|
} from './elevation'
|
|
12
|
+
import { liftStyle, LIFT_RIM_ALPHA } from './lift'
|
|
12
13
|
import { paperSheet, insetWell, barPaper } from './materials'
|
|
13
14
|
import { SectionIntro, SectionTitle } from './color-story-kit'
|
|
14
15
|
|
|
@@ -17,15 +18,19 @@ const t = getSemanticColors('dark')
|
|
|
17
18
|
/**
|
|
18
19
|
* Foundations/Depth — how a surface says how far away it is.
|
|
19
20
|
*
|
|
20
|
-
*
|
|
21
|
+
* Four mechanisms, and which one applies is not a taste call:
|
|
21
22
|
*
|
|
22
|
-
* TONE
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* TONE which plane a surface sits on — the grey ramp
|
|
24
|
+
* LIFT that it rests ON the plane below — rim-light + ambient shadow
|
|
25
|
+
* HAIRLINE where one plane ends — alpha, self-normalising
|
|
26
|
+
* MATERIAL what a plane is made of — paper, well
|
|
25
27
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
* Tone and lift travel together: every lifted plane wears both. This page
|
|
29
|
+
* previously taught that levels 0–3 separate by tone alone and that drop-shadow
|
|
30
|
+
* belongs to floating overlays only (TD-07.16). That was reversed on 2026-09-08:
|
|
31
|
+
* the upper ramp steps are ΔL* 2.5–3 apart, too tight for tone to carry the
|
|
32
|
+
* separation on its own, and a soft ambient shadow is not inert on a dark plane
|
|
33
|
+
* once a rim-light gives the edge something to fall from.
|
|
29
34
|
*/
|
|
30
35
|
const meta: Meta = {
|
|
31
36
|
title: 'Foundations/Depth',
|
|
@@ -35,7 +40,6 @@ export default meta
|
|
|
35
40
|
|
|
36
41
|
const CONTENT_LEVELS: ElevationLevel[] = [0, 1, 2, 3]
|
|
37
42
|
const FLOATING_LEVELS: ElevationLevel[] = [4, 5]
|
|
38
|
-
const base = getBaseSurfaceColor('dark')
|
|
39
43
|
|
|
40
44
|
function Swatch({
|
|
41
45
|
label,
|
|
@@ -69,21 +73,21 @@ function Swatch({
|
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
export const Mechanisms: StoryObj = {
|
|
72
|
-
name: '1. The
|
|
76
|
+
name: '1. The four mechanisms',
|
|
73
77
|
render: () => (
|
|
74
|
-
<View style={{ padding: 24, backgroundColor: greyRamp[
|
|
78
|
+
<View style={{ padding: 24, backgroundColor: greyRamp[925] }}>
|
|
75
79
|
<Text className="text-2xl font-bold text-text-primary mb-2">Depth</Text>
|
|
76
80
|
<SectionIntro>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
physical takes a MATERIAL.
|
|
80
|
-
|
|
81
|
+
Four mechanisms, in the order you should reach for them. A surface that sits higher takes a
|
|
82
|
+
TONE and, with it, a LIFT; one that only needs an edge takes a HAIRLINE; one that needs to
|
|
83
|
+
feel physical takes a MATERIAL. Tone is the only cue that works identically on web and
|
|
84
|
+
native, so it is never optional; the others sit on top of it.
|
|
81
85
|
</SectionIntro>
|
|
82
86
|
|
|
83
87
|
<SectionTitle>Tone — the grey ramp</SectionTitle>
|
|
84
88
|
<Text className="text-text-secondary text-xs mb-3">
|
|
85
|
-
|
|
86
|
-
a
|
|
89
|
+
Every plane is a ramp step. Nothing derives a colour between two steps: the elevation levels
|
|
90
|
+
in section 2 index this list, they do not lighten a base.
|
|
87
91
|
</Text>
|
|
88
92
|
<View style={{ flexDirection: 'row', gap: 10, marginBottom: 22 }}>
|
|
89
93
|
{[975, 950, 925, 900, 875, 850].map((step) => (
|
|
@@ -96,12 +100,43 @@ export const Mechanisms: StoryObj = {
|
|
|
96
100
|
))}
|
|
97
101
|
</View>
|
|
98
102
|
|
|
103
|
+
<SectionTitle>Lift — resting on the plane below</SectionTitle>
|
|
104
|
+
<Text className="text-text-secondary text-xs mb-3">
|
|
105
|
+
A crisp 1px top rim-light at {LIFT_RIM_ALPHA.dark} (one grade under paperSheet's 0.20
|
|
106
|
+
hero rim, chosen side by side in Lab/Depth) plus a soft ambient shadow that grows with the
|
|
107
|
+
planes crossed. Both are lit from above. This is what separates a card from the page when
|
|
108
|
+
the tone step alone is ΔL* 3. It is not a hairline ring: a ring is an edge, and stays the
|
|
109
|
+
divider's job.
|
|
110
|
+
</Text>
|
|
111
|
+
<View style={{ flexDirection: 'row', gap: 10, marginBottom: 22 }}>
|
|
112
|
+
<Swatch
|
|
113
|
+
label="tone only"
|
|
114
|
+
note="grey-875 on grey-925: the step is there, but the card is not resting on anything."
|
|
115
|
+
style={{ backgroundColor: greyRamp[875] }}
|
|
116
|
+
/>
|
|
117
|
+
<Swatch
|
|
118
|
+
label="tone + rim"
|
|
119
|
+
note="the rim gives the top edge a lit lip."
|
|
120
|
+
style={{
|
|
121
|
+
backgroundColor: greyRamp[875],
|
|
122
|
+
boxShadow: `inset 0 1px 0 rgba(255,255,255,${LIFT_RIM_ALPHA.dark})`,
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
<Swatch
|
|
126
|
+
label="tone + rim + shadow"
|
|
127
|
+
note="the default for any lifted plane: liftStyle(2)."
|
|
128
|
+
style={{
|
|
129
|
+
backgroundColor: greyRamp[875],
|
|
130
|
+
...(liftStyle(2, 'dark') as Record<string, unknown>),
|
|
131
|
+
}}
|
|
132
|
+
/>
|
|
133
|
+
</View>
|
|
134
|
+
|
|
99
135
|
<SectionTitle>Hairline — where a plane ends</SectionTitle>
|
|
100
136
|
<Text className="text-text-secondary text-xs mb-3">
|
|
101
|
-
Alpha-white, so it composites toward white by the same amount on any background and holds
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
tokens.
|
|
137
|
+
Alpha-white, so it composites toward white by the same amount on any background and holds a
|
|
138
|
+
near-constant ΔL* wherever it lands. It is the divider, the table rule, and the opt-in edge
|
|
139
|
+
of an `outline` card. It is not the default edge of a lifted card.
|
|
105
140
|
</Text>
|
|
106
141
|
<View style={{ flexDirection: 'row', gap: 10, marginBottom: 22 }}>
|
|
107
142
|
{(['hairline-subtle', 'hairline-default', 'hairline-strong'] as const).map((token) => (
|
|
@@ -120,87 +155,118 @@ export const Mechanisms: StoryObj = {
|
|
|
120
155
|
|
|
121
156
|
<SectionTitle>Material — what a plane is made of</SectionTitle>
|
|
122
157
|
<Text className="text-text-secondary text-xs mb-3">
|
|
123
|
-
Used sparingly. Paper is for HERO surfaces only and takes muted tones only
|
|
124
|
-
|
|
125
|
-
the
|
|
158
|
+
Used sparingly. Paper is for HERO surfaces only and takes muted tones only; vivid colour is
|
|
159
|
+
ink ON paper, never the paper itself. There are no levels of paper. The lift above is
|
|
160
|
+
paper's rim and contact shadow without the grain: the same light, one grade quieter.
|
|
126
161
|
</Text>
|
|
127
162
|
<View style={{ flexDirection: 'row', gap: 10, marginBottom: 8 }}>
|
|
128
163
|
<Swatch
|
|
129
164
|
label="paperSheet"
|
|
130
|
-
note="
|
|
165
|
+
note="grain + rim + contact shadow. Hero surfaces."
|
|
131
166
|
style={paperSheet(greyRamp[875]) as Record<string, unknown>}
|
|
132
167
|
/>
|
|
133
168
|
<Swatch
|
|
134
169
|
label="insetWell"
|
|
135
|
-
note="inner top cut + a light line on the floor.
|
|
170
|
+
note="inner top cut + a light line on the floor. Also the recess of every pressed surface."
|
|
136
171
|
style={insetWell(greyRamp[950]) as Record<string, unknown>}
|
|
137
172
|
/>
|
|
138
173
|
<Swatch
|
|
139
174
|
label="barPaper"
|
|
140
175
|
note="the same grain curve, tuned for a small saturated element."
|
|
141
|
-
style={{
|
|
176
|
+
style={{
|
|
177
|
+
...(barPaper(t['status-info']) as Record<string, unknown>),
|
|
178
|
+
backgroundColor: t['status-info'],
|
|
179
|
+
}}
|
|
142
180
|
/>
|
|
143
181
|
</View>
|
|
144
182
|
<Text className="text-text-tertiary text-xs">
|
|
145
|
-
|
|
146
|
-
native. Every
|
|
147
|
-
depends on one, and a
|
|
183
|
+
Lift and materials are web/RNW only — `backgroundImage` and multi-layer `boxShadow` are
|
|
184
|
+
ignored on native, which gets one shadow. Every treatment keeps a solid `backgroundColor`
|
|
185
|
+
underneath, so a surface never depends on one, and a treatment is never the only thing
|
|
186
|
+
carrying meaning.
|
|
148
187
|
</Text>
|
|
149
188
|
</View>
|
|
150
189
|
),
|
|
151
190
|
}
|
|
152
191
|
|
|
153
192
|
export const Elevation: StoryObj = {
|
|
154
|
-
name: '2. Elevation —
|
|
193
|
+
name: '2. Elevation — planes on the ramp, lifted',
|
|
155
194
|
render: () => (
|
|
156
|
-
<View style={{ padding: 24, backgroundColor: greyRamp[
|
|
195
|
+
<View style={{ padding: 24, backgroundColor: greyRamp[925] }}>
|
|
157
196
|
<Text className="text-2xl font-bold text-text-primary mb-2">Elevation</Text>
|
|
158
197
|
<SectionIntro>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
198
|
+
A level is a ramp plane plus the lift that plane wears. Level 0 is the page. Levels 1–3
|
|
199
|
+
climb one plane each and lift; from {FLOATING_ELEVATION_MIN} up the element is floating over
|
|
200
|
+
a backdrop, so it stays on the overlay plane and the shadow does the separating. In a
|
|
201
|
+
component the numbers are RELATIVE to the enclosing Surface, clamped at overlay, so a card
|
|
202
|
+
inside a card cannot leave the ramp.
|
|
164
203
|
</SectionIntro>
|
|
204
|
+
<Text className="text-text-secondary text-xs mb-4">
|
|
205
|
+
Lift sparingly, and only over something much larger. A card lifts off the page; a small card
|
|
206
|
+
lifted off a small card reads as clutter, not depth. Inside a lifted surface, organise with
|
|
207
|
+
an inset well (`CardInset`, `Surface pressed`), a tone-only `filled` tile, or a hairline
|
|
208
|
+
divider, and save a second lift for a surface that genuinely floats over the first.
|
|
209
|
+
</Text>
|
|
165
210
|
|
|
166
|
-
<SectionTitle>Content levels — tone
|
|
211
|
+
<SectionTitle>Content levels — tone + lift</SectionTitle>
|
|
167
212
|
<View style={{ flexDirection: 'row', gap: 10, marginBottom: 22 }}>
|
|
168
213
|
{CONTENT_LEVELS.map((lv) => (
|
|
169
214
|
<Swatch
|
|
170
215
|
key={lv}
|
|
171
216
|
label={`elevation ${lv}`}
|
|
172
|
-
note={`${getElevationSurface(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
217
|
+
note={`${ELEVATION_PLANE[lv]} · ${getElevationSurface(lv, 'dark')}${lv > 0 ? ` · liftStyle(${lv})` : ' · the page'}`}
|
|
218
|
+
// Level 0 IS the page, so a solid swatch on the page would be an
|
|
219
|
+
// invisible rectangle. A dashed outline gives the row a fourth slot
|
|
220
|
+
// and says why it has nothing to draw.
|
|
221
|
+
style={
|
|
222
|
+
lv === 0
|
|
223
|
+
? {
|
|
224
|
+
borderWidth: 1,
|
|
225
|
+
borderStyle: 'dashed',
|
|
226
|
+
borderColor: t['hairline-default'],
|
|
227
|
+
}
|
|
228
|
+
: {
|
|
229
|
+
backgroundColor: getElevationSurface(lv, 'dark'),
|
|
230
|
+
...(getElevationShadow(lv, 'dark') as Record<string, unknown>),
|
|
231
|
+
}
|
|
232
|
+
}
|
|
179
233
|
/>
|
|
180
234
|
))}
|
|
181
235
|
</View>
|
|
182
236
|
|
|
183
|
-
<SectionTitle>Floating levels —
|
|
237
|
+
<SectionTitle>Floating levels — overlay plane, larger shadow, no ring</SectionTitle>
|
|
184
238
|
<View style={{ flexDirection: 'row', gap: 24, marginBottom: 8 }}>
|
|
185
239
|
{FLOATING_LEVELS.map((lv) => (
|
|
186
240
|
<Swatch
|
|
187
241
|
key={lv}
|
|
188
242
|
label={`elevation ${lv}`}
|
|
189
|
-
note={`${getElevationSurface(
|
|
243
|
+
note={`${ELEVATION_PLANE[lv]} · ${getElevationSurface(lv, 'dark')} · three ambient layers`}
|
|
190
244
|
style={{
|
|
191
|
-
backgroundColor: getElevationSurface(
|
|
192
|
-
|
|
193
|
-
borderColor: t['hairline-strong'],
|
|
194
|
-
...(getElevationShadow(base, lv, 'dark') as Record<string, unknown>),
|
|
245
|
+
backgroundColor: getElevationSurface(lv, 'dark'),
|
|
246
|
+
...(getElevationShadow(lv, 'dark') as Record<string, unknown>),
|
|
195
247
|
}}
|
|
196
248
|
/>
|
|
197
249
|
))}
|
|
198
250
|
</View>
|
|
199
251
|
<Text className="text-text-tertiary text-xs">
|
|
200
|
-
A floating surface
|
|
201
|
-
|
|
202
|
-
washed out by glare.
|
|
252
|
+
A floating surface carries the same rim as a card, not a hairline ring. The rim is the edge
|
|
253
|
+
that survives glare; a ring on top of it would be a second edge saying the same thing.
|
|
203
254
|
</Text>
|
|
255
|
+
|
|
256
|
+
<SectionTitle>Recessed levels — one and two planes down</SectionTitle>
|
|
257
|
+
<View style={{ flexDirection: 'row', gap: 10, marginBottom: 8 }}>
|
|
258
|
+
{([-1, -2] as ElevationLevel[]).map((lv) => (
|
|
259
|
+
<Swatch
|
|
260
|
+
key={lv}
|
|
261
|
+
label={`elevation ${lv}`}
|
|
262
|
+
note={`${ELEVATION_PLANE[lv]} · ${getElevationSurface(lv, 'dark')} · insetWell recess`}
|
|
263
|
+
style={{
|
|
264
|
+
backgroundColor: getElevationSurface(lv, 'dark'),
|
|
265
|
+
...(getElevationShadow(lv, 'dark') as Record<string, unknown>),
|
|
266
|
+
}}
|
|
267
|
+
/>
|
|
268
|
+
))}
|
|
269
|
+
</View>
|
|
204
270
|
</View>
|
|
205
271
|
),
|
|
206
272
|
}
|
|
@@ -208,19 +274,21 @@ export const Elevation: StoryObj = {
|
|
|
208
274
|
export const WhyNotNeumorphism: StoryObj = {
|
|
209
275
|
name: '3. Why not neumorphism',
|
|
210
276
|
render: () => (
|
|
211
|
-
<View style={{ padding: 24, backgroundColor: greyRamp[
|
|
277
|
+
<View style={{ padding: 24, backgroundColor: greyRamp[925] }}>
|
|
212
278
|
<Text className="text-2xl font-bold text-text-primary mb-2">Why not neumorphism</Text>
|
|
213
279
|
<SectionIntro>
|
|
214
280
|
The system used to ship a neumorphic builder — a dark shadow bottom-right paired with a
|
|
215
|
-
light rim top-left. It was removed rather than retuned, and the reason is a lightness
|
|
216
|
-
|
|
281
|
+
light rim top-left. It was removed rather than retuned, and the reason is a lightness budget
|
|
282
|
+
rather than a preference, so it is worth being able to see.
|
|
217
283
|
</SectionIntro>
|
|
218
284
|
|
|
219
285
|
<Text className="text-text-secondary text-xs mb-4">
|
|
220
286
|
Neumorphism needs a MID-TONE ground (roughly 75–90% lightness) so the dark half has
|
|
221
|
-
somewhere to fall and the light half has somewhere to rise. Our surfaces sit near 10%.
|
|
222
|
-
|
|
223
|
-
|
|
287
|
+
somewhere to fall and the light half has somewhere to rise. Our surfaces sit near 10%. Below
|
|
288
|
+
them there is almost nothing left — so the dark half disappears and the treatment collapses
|
|
289
|
+
to a one-sided rim, which reads as a smudge rather than as depth. The lift keeps the one
|
|
290
|
+
half that works (the top rim) and moves the shadow to where there IS room: straight down,
|
|
291
|
+
onto the plane below.
|
|
224
292
|
</Text>
|
|
225
293
|
|
|
226
294
|
<View style={{ flexDirection: 'row', gap: 24 }}>
|
|
@@ -294,9 +362,8 @@ export const WhyNotNeumorphism: StoryObj = {
|
|
|
294
362
|
width: 110,
|
|
295
363
|
height: 66,
|
|
296
364
|
borderRadius: 10,
|
|
297
|
-
backgroundColor: greyRamp[
|
|
298
|
-
|
|
299
|
-
borderColor: t['hairline-default'],
|
|
365
|
+
backgroundColor: greyRamp[875],
|
|
366
|
+
...(liftStyle(2, 'dark') as Record<string, unknown>),
|
|
300
367
|
}}
|
|
301
368
|
/>
|
|
302
369
|
</View>
|
|
@@ -305,7 +372,7 @@ export const WhyNotNeumorphism: StoryObj = {
|
|
|
305
372
|
|
|
306
373
|
<Text className="text-text-tertiary text-xs mt-4">
|
|
307
374
|
Same treatment, same offsets, different ground. The middle panel is the one that shipped.
|
|
308
|
-
The right panel is
|
|
375
|
+
The right panel is two ramp steps plus the lift: the rim from above, the shadow below.
|
|
309
376
|
</Text>
|
|
310
377
|
</View>
|
|
311
378
|
),
|
|
@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
|
3
3
|
import { View, Text, Pressable } from 'react-native'
|
|
4
4
|
import { greyRamp } from './tokens/primitives'
|
|
5
5
|
import { getSemanticColors } from './tokens/semantic'
|
|
6
|
-
import {
|
|
6
|
+
import { getElevationSurface, type ElevationLevel } from './elevation'
|
|
7
7
|
import { grainForTone, paperSheet } from './materials'
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -19,8 +19,9 @@ import { grainForTone, paperSheet } from './materials'
|
|
|
19
19
|
* north-star doc set its floors explicitly "to survive glare + a mediocre
|
|
20
20
|
* panel", and none of them have been looked at on the panel. That matters more
|
|
21
21
|
* than the numbers suggest: solid dark borders were DELETED, so if the hairlines
|
|
22
|
-
* wash out there is no fallback
|
|
23
|
-
*
|
|
22
|
+
* wash out there is no fallback. Elevation levels now resolve to the ramp planes
|
|
23
|
+
* themselves and wear a lift (rim + shadow) on top; C2 measures the tone half of
|
|
24
|
+
* that pairing on its own, because the lift must never be the only cue.
|
|
24
25
|
*
|
|
25
26
|
* WHY FORCED-CHOICE. "Does this look OK?" is close to unfalsifiable at
|
|
26
27
|
* threshold — you are asking someone to report the absence of a faint thing they
|
|
@@ -45,7 +46,6 @@ const meta: Meta = {
|
|
|
45
46
|
export default meta
|
|
46
47
|
|
|
47
48
|
const t = getSemanticColors('dark')
|
|
48
|
-
const base = getBaseSurfaceColor('dark')
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* The rig's ground sits BELOW the ramp, at true black.
|
|
@@ -105,7 +105,7 @@ function Panel({
|
|
|
105
105
|
borderRadius: 8,
|
|
106
106
|
borderWidth: 1,
|
|
107
107
|
borderColor: t['hairline-strong'],
|
|
108
|
-
backgroundColor: getElevationSurface(
|
|
108
|
+
backgroundColor: getElevationSurface(2, 'dark'),
|
|
109
109
|
}}
|
|
110
110
|
>
|
|
111
111
|
<Text className="text-text-primary" style={{ fontSize: 14, fontWeight: '600' }}>
|
|
@@ -233,7 +233,9 @@ export const Hairlines: StoryObj = {
|
|
|
233
233
|
|
|
234
234
|
// ── C2 · tone steps ─────────────────────────────────────────────────────────
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
// Levels 4 and 5 share the overlay plane by design (past the ramp the shadow
|
|
237
|
+
// separates), so the staircase stops at the last distinct tone.
|
|
238
|
+
const STAIRCASE: ElevationLevel[] = [-2, -1, 0, 1, 2, 3]
|
|
237
239
|
|
|
238
240
|
/**
|
|
239
241
|
* Adjacent-step pairs, with the lighter side pre-assigned to a fixed side and
|
|
@@ -244,13 +246,13 @@ const STEP_PAIRS: { left: ElevationLevel; right: ElevationLevel; label: string }
|
|
|
244
246
|
{ left: 1, right: 0, label: '1' },
|
|
245
247
|
{ left: 2, right: 3, label: '2' },
|
|
246
248
|
{ left: 2, right: 2, label: '3' },
|
|
247
|
-
{ left:
|
|
249
|
+
{ left: -1, right: 0, label: '4' },
|
|
248
250
|
{ left: 1, right: 2, label: '5' },
|
|
249
|
-
{ left:
|
|
251
|
+
{ left: -2, right: -1, label: '6' },
|
|
250
252
|
]
|
|
251
253
|
|
|
252
254
|
export const ToneSteps: StoryObj = {
|
|
253
|
-
name: 'C2 · Tone steps —
|
|
255
|
+
name: 'C2 · Tone steps — the ramp with the lift stripped off',
|
|
254
256
|
render: () => (
|
|
255
257
|
<Panel
|
|
256
258
|
title="C2 · Tone steps"
|
|
@@ -266,13 +268,13 @@ export const ToneSteps: StoryObj = {
|
|
|
266
268
|
{STAIRCASE.map((lv) => (
|
|
267
269
|
<View
|
|
268
270
|
key={lv}
|
|
269
|
-
style={{ flex: 1, backgroundColor: getElevationSurface(
|
|
271
|
+
style={{ flex: 1, backgroundColor: getElevationSurface(lv, 'dark') }}
|
|
270
272
|
/>
|
|
271
273
|
))}
|
|
272
274
|
</View>
|
|
273
275
|
<Text className="text-text-tertiary" style={{ fontSize: 13, marginTop: 8 }}>
|
|
274
276
|
{revealed
|
|
275
|
-
? `6 bands / 5 edges — elevation
|
|
277
|
+
? `6 bands / 5 edges — elevation -2…3 = frame · background · base · elevated · raised · overlay`
|
|
276
278
|
: 'Edges visible: ______'}
|
|
277
279
|
</Text>
|
|
278
280
|
|
|
@@ -285,13 +287,13 @@ export const ToneSteps: StoryObj = {
|
|
|
285
287
|
<View
|
|
286
288
|
style={{
|
|
287
289
|
flex: 1,
|
|
288
|
-
backgroundColor: getElevationSurface(
|
|
290
|
+
backgroundColor: getElevationSurface(pair.left, 'dark'),
|
|
289
291
|
}}
|
|
290
292
|
/>
|
|
291
293
|
<View
|
|
292
294
|
style={{
|
|
293
295
|
flex: 1,
|
|
294
|
-
backgroundColor: getElevationSurface(
|
|
296
|
+
backgroundColor: getElevationSurface(pair.right, 'dark'),
|
|
295
297
|
}}
|
|
296
298
|
/>
|
|
297
299
|
</View>
|
|
@@ -310,18 +312,18 @@ export const ToneSteps: StoryObj = {
|
|
|
310
312
|
{revealed ? (
|
|
311
313
|
<View style={{ marginTop: 14, maxWidth: 1000 }}>
|
|
312
314
|
<KeyLine>
|
|
313
|
-
{'Pair
|
|
314
|
-
'
|
|
315
|
+
{'Pair 2 is the one that matters: raised → overlay is the tightest step on the ' +
|
|
316
|
+
'ramp (ΔL* 2.5) and the one a card inside a card lands on. Pair 3 is the decoy.'}
|
|
315
317
|
</KeyLine>
|
|
316
318
|
<KeyLine>
|
|
317
319
|
{'PASS: all five edges counted on the staircase, pairs 1/2/4/5/6 called correctly, ' +
|
|
318
|
-
'pair 3 called SAME.
|
|
319
|
-
'
|
|
320
|
+
'pair 3 called SAME. In production every lifted plane also wears a rim + shadow, ' +
|
|
321
|
+
'but the tone must carry on its own — native has no multi-layer shadow at all.'}
|
|
320
322
|
</KeyLine>
|
|
321
323
|
<KeyLine>
|
|
322
|
-
{'Retune lever:
|
|
323
|
-
'
|
|
324
|
-
'
|
|
324
|
+
{'Retune lever: the ramp itself (tokens/primitives.ts, greyRamp 850–975). The ' +
|
|
325
|
+
'elevation ladder no longer has values of its own to widen — it reads the ramp — ' +
|
|
326
|
+
'so a missed step is a ramp finding, and re-spacing goes through the generator.'}
|
|
325
327
|
</KeyLine>
|
|
326
328
|
</View>
|
|
327
329
|
) : null}
|
|
@@ -578,7 +580,7 @@ const BAND_FIELDS: { key: string; answer: string; style: Record<string, unknown>
|
|
|
578
580
|
style: {
|
|
579
581
|
backgroundImage: `linear-gradient(180deg, ${BAND_STEPS.map(
|
|
580
582
|
(hex, i) =>
|
|
581
|
-
`${hex} ${(i / BAND_STEPS.length) * 100}%, ${hex} ${((i + 1) / BAND_STEPS.length) * 100}
|
|
583
|
+
`${hex} ${(i / BAND_STEPS.length) * 100}%, ${hex} ${((i + 1) / BAND_STEPS.length) * 100}%`
|
|
582
584
|
).join(', ')})`,
|
|
583
585
|
},
|
|
584
586
|
},
|
|
@@ -14,7 +14,7 @@ describe('ThemeProvider', () => {
|
|
|
14
14
|
render(
|
|
15
15
|
<ThemeProvider>
|
|
16
16
|
<Text>inside</Text>
|
|
17
|
-
</ThemeProvider
|
|
17
|
+
</ThemeProvider>
|
|
18
18
|
)
|
|
19
19
|
expect(screen.getByText('inside')).toBeInTheDocument()
|
|
20
20
|
})
|
|
@@ -23,7 +23,7 @@ describe('ThemeProvider', () => {
|
|
|
23
23
|
render(
|
|
24
24
|
<ThemeProvider mode="light">
|
|
25
25
|
<Text>light</Text>
|
|
26
|
-
</ThemeProvider
|
|
26
|
+
</ThemeProvider>
|
|
27
27
|
)
|
|
28
28
|
expect(screen.getByText('light')).toBeInTheDocument()
|
|
29
29
|
})
|
|
@@ -32,7 +32,7 @@ describe('ThemeProvider', () => {
|
|
|
32
32
|
render(
|
|
33
33
|
<ThemeProvider mode="light">
|
|
34
34
|
<ModeProbe />
|
|
35
|
-
</ThemeProvider
|
|
35
|
+
</ThemeProvider>
|
|
36
36
|
)
|
|
37
37
|
expect(screen.getByText('light')).toBeInTheDocument()
|
|
38
38
|
})
|
|
@@ -41,7 +41,7 @@ describe('ThemeProvider', () => {
|
|
|
41
41
|
render(
|
|
42
42
|
<ThemeProvider mode="system">
|
|
43
43
|
<ModeProbe />
|
|
44
|
-
</ThemeProvider
|
|
44
|
+
</ThemeProvider>
|
|
45
45
|
)
|
|
46
46
|
expect(screen.getByText('dark')).toBeInTheDocument()
|
|
47
47
|
})
|