@titan-design/react-ui 0.12.0 → 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 +1320 -215
- package/dist/index.d.ts +1320 -215
- 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 +202 -1042
- package/dist/theme/index.d.ts +202 -1042
- 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 +972 -0
- package/dist/theme/tokens.d.ts +972 -0
- package/dist/theme/tokens.js +904 -0
- package/dist/theme/tokens.js.map +1 -0
- package/dist/theme/tokens.mjs +880 -0
- package/dist/theme/tokens.mjs.map +1 -0
- 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 +7 -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 +12 -7
- 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 +90 -27
- 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 +24 -22
- 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 +102 -0
- package/src/theme/tokens/primitives.test.ts +15 -7
- package/src/theme/tokens/primitives.ts +67 -35
- 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
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The surface planes: the grey-ramp steps a container can sit on, darkest first.
|
|
3
|
+
*
|
|
4
|
+
* Every background a `<Surface>` or `<Card>` paints resolves through this list,
|
|
5
|
+
* so a container can only ever land ON the ramp. Stepping up (a lifted card) or
|
|
6
|
+
* down (a pressed well) is indexing `PLANE_ORDER`, clamped at both ends.
|
|
7
|
+
*
|
|
8
|
+
* `frame` is the bezel the ramp sits inside and the floor a pressed surface
|
|
9
|
+
* clamps at. It replaced a separate `inset` level in TD-07.14: at ΔE 1.10 from
|
|
10
|
+
* the frame that level was an imperceptible duplicate.
|
|
11
|
+
*/
|
|
12
|
+
import { getSemanticColors, type ThemeMode } from './tokens/semantic'
|
|
13
|
+
|
|
14
|
+
type ColorToken = keyof ReturnType<typeof getSemanticColors>
|
|
15
|
+
|
|
16
|
+
export type SurfaceLevel = 'frame' | 'background' | 'base' | 'elevated' | 'raised' | 'overlay'
|
|
17
|
+
|
|
18
|
+
// Which semantic token backs each plane. Values live in `semantic.ts` and stay
|
|
19
|
+
// in sync with the grey ramp; this map never carries literal hexes.
|
|
20
|
+
export const SURFACE_LEVEL_TOKEN = {
|
|
21
|
+
frame: 'background-frame',
|
|
22
|
+
background: 'background-base',
|
|
23
|
+
base: 'surface-base',
|
|
24
|
+
elevated: 'surface-elevated',
|
|
25
|
+
raised: 'surface-raised',
|
|
26
|
+
overlay: 'surface-overlay',
|
|
27
|
+
} as const satisfies Record<SurfaceLevel, ColorToken>
|
|
28
|
+
|
|
29
|
+
/** Darkest → lightest. Kept in lockstep with the grey ramp and surface.contract.test. */
|
|
30
|
+
export const PLANE_ORDER = [
|
|
31
|
+
'frame',
|
|
32
|
+
'background',
|
|
33
|
+
'base',
|
|
34
|
+
'elevated',
|
|
35
|
+
'raised',
|
|
36
|
+
'overlay',
|
|
37
|
+
] as const satisfies readonly SurfaceLevel[]
|
|
38
|
+
|
|
39
|
+
/** The background hex for a plane under a theme mode (literal hex, never a var()). */
|
|
40
|
+
export function surfaceBackground(level: SurfaceLevel, mode: ThemeMode): string {
|
|
41
|
+
return getSemanticColors(mode)[SURFACE_LEVEL_TOKEN[level]]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function stepPlane(from: SurfaceLevel, delta: number): SurfaceLevel {
|
|
45
|
+
const index = PLANE_ORDER.indexOf(from)
|
|
46
|
+
const clamped = Math.min(PLANE_ORDER.length - 1, Math.max(0, index + delta))
|
|
47
|
+
return PLANE_ORDER[clamped]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The plane a `<Surface pressed>` resolves to: its parent's plane stepped one
|
|
52
|
+
* index DOWN the ramp, clamped at the `frame` floor.
|
|
53
|
+
* overlay→raised, raised→elevated, elevated→base, base→background,
|
|
54
|
+
* background→frame, frame→frame (clamped).
|
|
55
|
+
*/
|
|
56
|
+
export function pressedLevel(parent: SurfaceLevel): SurfaceLevel {
|
|
57
|
+
return stepPlane(parent, -1)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The plane a lifted surface resolves to: its parent's plane stepped `steps`
|
|
62
|
+
* UP the ramp, clamped at `overlay`. The clamp is what makes raised-on-raised
|
|
63
|
+
* unrepresentable: a card inside an overlay stays on the overlay and relies on
|
|
64
|
+
* its lift treatment, never on a lighter grey that is not on the ramp.
|
|
65
|
+
*/
|
|
66
|
+
export function raisedLevel(parent: SurfaceLevel, steps: number): SurfaceLevel {
|
|
67
|
+
return stepPlane(parent, Math.max(0, steps))
|
|
68
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Token-export guard (TP-16).
|
|
8
|
+
*
|
|
9
|
+
* `@titan-design/react-ui/theme/tokens` is the token-only subpath for consumers
|
|
10
|
+
* that are NOT react-native apps — plain web builds that want `getSemanticColors`
|
|
11
|
+
* and the primitive/semantic token maps and nothing else.
|
|
12
|
+
*
|
|
13
|
+
* The bug this guards: before TP-16 the only subpath carrying `getSemanticColors`
|
|
14
|
+
* was `./theme`, whose entry re-exports the `ThemeProvider` VALUE. That drags in
|
|
15
|
+
* nativewind -> react-native-css-interop, which ships raw JSX in a `.js` file that
|
|
16
|
+
* neither plain Node ESM nor a Vite/rollup build can parse — a web consumer just
|
|
17
|
+
* got a build failure at `react-native-css-interop/dist/doctor.js`. A type-check
|
|
18
|
+
* would never catch it, so this guard is static and structural instead.
|
|
19
|
+
*
|
|
20
|
+
* It walks the SOURCE import graph rooted at the subpath entry and asserts nothing
|
|
21
|
+
* reachable imports react, react-native, nativewind, or gluestack. Source-level
|
|
22
|
+
* (not dist-level) so it runs in the fast project with no build step.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const themeDir = path.dirname(fileURLToPath(import.meta.url))
|
|
26
|
+
const uiRoot = path.resolve(themeDir, '..', '..')
|
|
27
|
+
|
|
28
|
+
const TOKEN_ENTRY = path.join(themeDir, 'tokens', 'index.ts')
|
|
29
|
+
const FORBIDDEN = ['react', 'react-dom', 'react-native', 'react-native-web', 'nativewind']
|
|
30
|
+
|
|
31
|
+
function resolveRelative(fromFile: string, specifier: string): string | null {
|
|
32
|
+
const base = path.resolve(path.dirname(fromFile), specifier)
|
|
33
|
+
for (const candidate of [`${base}.ts`, `${base}.tsx`, path.join(base, 'index.ts')]) {
|
|
34
|
+
if (fs.existsSync(candidate)) return candidate
|
|
35
|
+
}
|
|
36
|
+
return null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Every `from '...'` specifier in a module, ignoring type-only imports (erased at build). */
|
|
40
|
+
function importSpecifiers(source: string): string[] {
|
|
41
|
+
const stripped = source.replace(/^\s*(import|export)\s+type\s[^;]*;?$/gm, '')
|
|
42
|
+
const matches = stripped.matchAll(/(?:import|export)[^'"]*?from\s*['"]([^'"]+)['"]/g)
|
|
43
|
+
return [...matches].map((m) => m[1])
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Walk the source import graph from `entry`, returning every reachable file + bare specifier. */
|
|
47
|
+
function collectGraph(entry: string): { files: string[]; bare: string[] } {
|
|
48
|
+
const seen = new Set<string>()
|
|
49
|
+
const bare = new Set<string>()
|
|
50
|
+
const queue = [entry]
|
|
51
|
+
while (queue.length > 0) {
|
|
52
|
+
const file = queue.pop()!
|
|
53
|
+
if (seen.has(file)) continue
|
|
54
|
+
seen.add(file)
|
|
55
|
+
for (const specifier of importSpecifiers(fs.readFileSync(file, 'utf8'))) {
|
|
56
|
+
if (!specifier.startsWith('.')) {
|
|
57
|
+
bare.add(specifier)
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
const resolved = resolveRelative(file, specifier)
|
|
61
|
+
if (resolved) queue.push(resolved)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { files: [...seen], bare: [...bare] }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
describe('token-only subpath export (TP-16)', () => {
|
|
68
|
+
it('is declared in the package exports map', () => {
|
|
69
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(uiRoot, 'package.json'), 'utf8'))
|
|
70
|
+
expect(pkg.exports['./theme/tokens']).toEqual({
|
|
71
|
+
'react-native': './src/theme/tokens/index.ts',
|
|
72
|
+
types: './dist/theme/tokens.d.ts',
|
|
73
|
+
import: './dist/theme/tokens.mjs',
|
|
74
|
+
require: './dist/theme/tokens.js',
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('has a matching tsup build entry so the dist files actually exist', () => {
|
|
79
|
+
const tsupConfig = fs.readFileSync(path.join(uiRoot, 'tsup.config.ts'), 'utf8')
|
|
80
|
+
expect(tsupConfig).toContain(`'theme/tokens': 'src/theme/tokens/index.ts'`)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('reaches no react / react-native / nativewind module in its import graph', () => {
|
|
84
|
+
const { bare } = collectGraph(TOKEN_ENTRY)
|
|
85
|
+
const leaked = bare.filter((s) => FORBIDDEN.some((f) => s === f || s.startsWith(`${f}/`)))
|
|
86
|
+
expect(leaked).toEqual([])
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('reaches no gluestack module in its import graph', () => {
|
|
90
|
+
const { bare } = collectGraph(TOKEN_ENTRY)
|
|
91
|
+
expect(bare.filter((s) => s.includes('gluestack'))).toEqual([])
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('exports getSemanticColors returning real token values in both modes', async () => {
|
|
95
|
+
const tokens = await import('./tokens/index')
|
|
96
|
+
for (const mode of ['dark', 'light'] as const) {
|
|
97
|
+
const colors = tokens.getSemanticColors(mode)
|
|
98
|
+
expect(Object.keys(colors).length).toBeGreaterThan(0)
|
|
99
|
+
expect(colors['brand-primary']).toMatch(/^#|^rgba?\(/)
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
})
|
|
@@ -34,15 +34,17 @@ const mul = (M: number[], v: number[]) => [
|
|
|
34
34
|
// Machado-2009 dichromacy simulation matrices, severity 1.0. The palette solver
|
|
35
35
|
// optimizes worst-case deuteranopia/protanopia (red-green is the binding case) —
|
|
36
36
|
// match that 2-way metric here, not a stricter 3-way including tritan.
|
|
37
|
-
const DEUT = [
|
|
38
|
-
|
|
37
|
+
const DEUT = [
|
|
38
|
+
0.367322, 0.860646, -0.227968, 0.280085, 0.672501, 0.047413, -0.01182, 0.04294, 0.968881,
|
|
39
|
+
]
|
|
40
|
+
const PROT = [
|
|
41
|
+
0.152286, 1.052583, -0.204868, 0.114503, 0.786281, 0.099216, -0.003882, -0.048116, 1.051998,
|
|
42
|
+
]
|
|
39
43
|
const dist = (a: number[], b: number[]) => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]) * 100
|
|
40
44
|
// worst-case perceived ΔE across deuteranopia and protanopia
|
|
41
45
|
const cvdDelta = (x: string, y: string) => {
|
|
42
46
|
const sim = (M: number[], hex: string) => toOklab(mul(M, hexToRgb(hex).map(lin)))
|
|
43
|
-
return Math.min(
|
|
44
|
-
...[DEUT, PROT].map((M) => dist(sim(M, x), sim(M, y))),
|
|
45
|
-
)
|
|
47
|
+
return Math.min(...[DEUT, PROT].map((M) => dist(sim(M, x), sim(M, y))))
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
const HEX6 = /^#[0-9A-F]{6}$/
|
|
@@ -115,7 +117,10 @@ describe('categoricalPalette', () => {
|
|
|
115
117
|
worst = Math.min(worst, cvdDelta(colors[i], colors[j]))
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
|
-
expect(
|
|
120
|
+
expect(
|
|
121
|
+
worst,
|
|
122
|
+
`${variant} min CVD deltaE (first ${CATEGORICAL_CVD_SAFE_MAX})`
|
|
123
|
+
).toBeGreaterThanOrEqual(8)
|
|
119
124
|
}
|
|
120
125
|
})
|
|
121
126
|
|
|
@@ -212,7 +217,10 @@ describe('sequentialEffort', () => {
|
|
|
212
217
|
|
|
213
218
|
it('keeps adjacent stops distinguishable', () => {
|
|
214
219
|
for (let i = 0; i < sequentialEffort.length - 1; i++) {
|
|
215
|
-
expect(
|
|
220
|
+
expect(
|
|
221
|
+
cvdDelta(sequentialEffort[i], sequentialEffort[i + 1]),
|
|
222
|
+
`stop ${i}->${i + 1}`
|
|
223
|
+
).toBeGreaterThanOrEqual(4.5)
|
|
216
224
|
}
|
|
217
225
|
})
|
|
218
226
|
|
|
@@ -19,6 +19,18 @@ export const primitiveColors = {
|
|
|
19
19
|
transparent: 'transparent',
|
|
20
20
|
} as const
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* The vivid alert red: the one chromatic anchor outside the OKLCH ramps.
|
|
24
|
+
*
|
|
25
|
+
* It survived the TD-07.14 fold of the old `redVivid` scale only as the
|
|
26
|
+
* `-rgb`, `-subtle` and glow encodings of `status-error-vivid`, while the token
|
|
27
|
+
* itself was pinned to `red[600]` and collapsed onto `status-error`. Owning it
|
|
28
|
+
* here means the semantic layer references a primitive instead of carrying a
|
|
29
|
+
* literal. The red ramp has no step this saturated, and adding one means
|
|
30
|
+
* regenerating the ramp, so it stays a pin.
|
|
31
|
+
*/
|
|
32
|
+
export const alertRedVivid = '#FF4757' as const
|
|
33
|
+
|
|
22
34
|
/**
|
|
23
35
|
* Unified warm-neutral grey ramp (TD-07.14)
|
|
24
36
|
*
|
|
@@ -48,7 +60,7 @@ export const primitiveColors = {
|
|
|
48
60
|
* (surface − 1) kept collapsing into it. `975` is the floor.
|
|
49
61
|
*
|
|
50
62
|
* Spec, generator and the rejected v1/v2 cuts:
|
|
51
|
-
*
|
|
63
|
+
* sources/design/foundations/warm-grey-ramp/
|
|
52
64
|
*/
|
|
53
65
|
export const greyRamp = {
|
|
54
66
|
50: '#F9F6F3', // L*97.0 W6
|
|
@@ -90,7 +102,7 @@ export const SURFACE_PLANE_STEPS = {
|
|
|
90
102
|
* hexes. `pin` marks the step each ramp flows through its anchor.
|
|
91
103
|
* This is the single source of truth for chromatic hexes — the categorical palette
|
|
92
104
|
* below references these steps rather than duplicating values.
|
|
93
|
-
* See
|
|
105
|
+
* See sources/design/foundations.
|
|
94
106
|
*/
|
|
95
107
|
export const primitiveRamps = {
|
|
96
108
|
red: {
|
|
@@ -244,7 +256,10 @@ export type CategoricalVariant = keyof typeof categoricalPalette
|
|
|
244
256
|
* @param variant - `default` (black-text / light surfaces) or `dark` (white text)
|
|
245
257
|
* @returns The hex color string
|
|
246
258
|
*/
|
|
247
|
-
export function getCategoricalColor(
|
|
259
|
+
export function getCategoricalColor(
|
|
260
|
+
index: number,
|
|
261
|
+
variant: CategoricalVariant = 'default'
|
|
262
|
+
): string {
|
|
248
263
|
const palette = categoricalPalette[variant]
|
|
249
264
|
index = Math.max(0, Math.floor(index))
|
|
250
265
|
return palette[index % palette.length]
|
|
@@ -387,21 +402,38 @@ export function getDiscreteRainbowColor(index: number, size: number): string {
|
|
|
387
402
|
|
|
388
403
|
export const primitiveTypography = {
|
|
389
404
|
fontFamilies: {
|
|
390
|
-
sans: [
|
|
405
|
+
sans: [
|
|
406
|
+
'Inter',
|
|
407
|
+
'-apple-system',
|
|
408
|
+
'BlinkMacSystemFont',
|
|
409
|
+
'Segoe UI',
|
|
410
|
+
'Helvetica',
|
|
411
|
+
'Arial',
|
|
412
|
+
'sans-serif',
|
|
413
|
+
],
|
|
391
414
|
body: ['Nunito Sans', 'sans-serif'],
|
|
392
415
|
heading: ['Space Grotesk', 'sans-serif'],
|
|
393
|
-
mono: [
|
|
416
|
+
mono: [
|
|
417
|
+
'SF Mono',
|
|
418
|
+
'Monaco',
|
|
419
|
+
'Inconsolata',
|
|
420
|
+
'Fira Mono',
|
|
421
|
+
'Droid Sans Mono',
|
|
422
|
+
'Source Code Pro',
|
|
423
|
+
'monospace',
|
|
424
|
+
],
|
|
394
425
|
},
|
|
395
426
|
fontSizes: {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
427
|
+
'2xs': '0.625rem', // 10px
|
|
428
|
+
xs: '0.75rem', // 12px
|
|
429
|
+
sm: '0.875rem', // 14px
|
|
430
|
+
base: '1rem', // 16px
|
|
431
|
+
lg: '1.125rem', // 18px
|
|
432
|
+
xl: '1.5rem', // 24px
|
|
433
|
+
'2xl': '2rem', // 32px
|
|
402
434
|
'3xl': '2.25rem', // 36px
|
|
403
|
-
'4xl': '3rem',
|
|
404
|
-
'5xl': '3.5rem',
|
|
435
|
+
'4xl': '3rem', // 48px
|
|
436
|
+
'5xl': '3.5rem', // 56px
|
|
405
437
|
},
|
|
406
438
|
fontWeights: {
|
|
407
439
|
normal: 400,
|
|
@@ -430,28 +462,28 @@ export const primitiveTypography = {
|
|
|
430
462
|
export const primitiveSpacing = {
|
|
431
463
|
0: '0',
|
|
432
464
|
px: '1px',
|
|
433
|
-
0.5: '0.125rem',
|
|
434
|
-
1: '0.25rem',
|
|
435
|
-
1.5: '0.375rem',
|
|
436
|
-
2: '0.5rem',
|
|
437
|
-
2.5: '0.625rem',
|
|
438
|
-
3: '0.75rem',
|
|
439
|
-
3.5: '0.875rem',
|
|
440
|
-
4: '1rem',
|
|
441
|
-
5: '1.25rem',
|
|
442
|
-
6: '1.5rem',
|
|
443
|
-
7: '1.75rem',
|
|
444
|
-
8: '2rem',
|
|
445
|
-
9: '2.25rem',
|
|
446
|
-
10: '2.5rem',
|
|
447
|
-
11: '2.75rem',
|
|
448
|
-
12: '3rem',
|
|
449
|
-
14: '3.5rem',
|
|
450
|
-
16: '4rem',
|
|
451
|
-
20: '5rem',
|
|
452
|
-
24: '6rem',
|
|
453
|
-
28: '7rem',
|
|
454
|
-
32: '8rem',
|
|
465
|
+
0.5: '0.125rem', // 2px
|
|
466
|
+
1: '0.25rem', // 4px
|
|
467
|
+
1.5: '0.375rem', // 6px
|
|
468
|
+
2: '0.5rem', // 8px
|
|
469
|
+
2.5: '0.625rem', // 10px
|
|
470
|
+
3: '0.75rem', // 12px
|
|
471
|
+
3.5: '0.875rem', // 14px
|
|
472
|
+
4: '1rem', // 16px
|
|
473
|
+
5: '1.25rem', // 20px
|
|
474
|
+
6: '1.5rem', // 24px
|
|
475
|
+
7: '1.75rem', // 28px
|
|
476
|
+
8: '2rem', // 32px
|
|
477
|
+
9: '2.25rem', // 36px
|
|
478
|
+
10: '2.5rem', // 40px
|
|
479
|
+
11: '2.75rem', // 44px
|
|
480
|
+
12: '3rem', // 48px
|
|
481
|
+
14: '3.5rem', // 56px
|
|
482
|
+
16: '4rem', // 64px
|
|
483
|
+
20: '5rem', // 80px
|
|
484
|
+
24: '6rem', // 96px
|
|
485
|
+
28: '7rem', // 112px
|
|
486
|
+
32: '8rem', // 128px
|
|
455
487
|
} as const
|
|
456
488
|
|
|
457
489
|
export const primitiveBorderRadius = {
|
|
@@ -17,7 +17,13 @@
|
|
|
17
17
|
* - interactive-* : Hover/focus/active/disabled states
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
primitiveColors as p,
|
|
22
|
+
primitiveRamps as ramp,
|
|
23
|
+
greyRamp,
|
|
24
|
+
discreteRainbow,
|
|
25
|
+
alertRedVivid,
|
|
26
|
+
} from './primitives'
|
|
21
27
|
|
|
22
28
|
/**
|
|
23
29
|
* GREY MAPPING (TD-07.14) — how the old cool scales resolved onto `greyRamp`.
|
|
@@ -53,6 +59,8 @@ export const semanticColorsLight = {
|
|
|
53
59
|
'brand-primary-light': ramp.orange[300],
|
|
54
60
|
'brand-primary-dark': ramp.orange[500],
|
|
55
61
|
'brand-primary-subtle': 'rgba(255, 121, 0, 0.08)',
|
|
62
|
+
'brand-primary-muted': 'rgba(255, 121, 0, 0.30)',
|
|
63
|
+
'brand-primary-strong': 'rgba(255, 121, 0, 0.50)',
|
|
56
64
|
'brand-primary-hover': ramp.orange[500],
|
|
57
65
|
'brand-primary-active': ramp.orange[600],
|
|
58
66
|
|
|
@@ -60,6 +68,8 @@ export const semanticColorsLight = {
|
|
|
60
68
|
'brand-secondary-light': ramp.cyan[500],
|
|
61
69
|
'brand-secondary-dark': ramp.cyan[700],
|
|
62
70
|
'brand-secondary-subtle': 'rgba(48, 123, 155, 0.08)',
|
|
71
|
+
'brand-secondary-muted': 'rgba(48, 123, 155, 0.30)',
|
|
72
|
+
'brand-secondary-strong': 'rgba(48, 123, 155, 0.50)',
|
|
63
73
|
'brand-secondary-hover': ramp.cyan[700],
|
|
64
74
|
'brand-secondary-active': ramp.cyan[800],
|
|
65
75
|
|
|
@@ -72,6 +82,8 @@ export const semanticColorsLight = {
|
|
|
72
82
|
'status-success-light': ramp.green[200],
|
|
73
83
|
'status-success-dark': ramp.green[600],
|
|
74
84
|
'status-success-subtle': ramp.green[50],
|
|
85
|
+
'status-success-muted': 'rgba(46, 213, 115, 0.30)',
|
|
86
|
+
'status-success-strong': 'rgba(46, 213, 115, 0.50)',
|
|
75
87
|
|
|
76
88
|
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
77
89
|
'status-live': ramp.green[300],
|
|
@@ -81,21 +93,29 @@ export const semanticColorsLight = {
|
|
|
81
93
|
'status-error-light': ramp.red[500],
|
|
82
94
|
'status-error-dark': ramp.red[700],
|
|
83
95
|
'status-error-subtle': ramp.red[50],
|
|
96
|
+
'status-error-muted': 'rgba(209, 67, 67, 0.30)',
|
|
97
|
+
'status-error-strong': 'rgba(209, 67, 67, 0.50)',
|
|
84
98
|
|
|
85
|
-
'status-error-vivid':
|
|
99
|
+
'status-error-vivid': alertRedVivid, // NOT red[600], that is status-error
|
|
86
100
|
'status-error-vivid-light': ramp.red[500],
|
|
87
101
|
'status-error-vivid-dark': ramp.red[700],
|
|
88
102
|
'status-error-vivid-subtle': 'rgba(255, 71, 87, 0.12)',
|
|
103
|
+
'status-error-vivid-muted': 'rgba(255, 71, 87, 0.30)',
|
|
104
|
+
'status-error-vivid-strong': 'rgba(255, 71, 87, 0.50)',
|
|
89
105
|
|
|
90
106
|
'status-warning': ramp.amber[300],
|
|
91
107
|
'status-warning-light': ramp.amber[200],
|
|
92
108
|
'status-warning-dark': ramp.amber[500],
|
|
93
109
|
'status-warning-subtle': ramp.amber[50],
|
|
110
|
+
'status-warning-muted': 'rgba(249, 180, 21, 0.30)',
|
|
111
|
+
'status-warning-strong': 'rgba(249, 180, 21, 0.50)',
|
|
94
112
|
|
|
95
113
|
'status-info': ramp.blue[500],
|
|
96
114
|
'status-info-light': ramp.blue[300],
|
|
97
115
|
'status-info-dark': ramp.blue[600],
|
|
98
116
|
'status-info-subtle': ramp.blue[50],
|
|
117
|
+
'status-info-muted': 'rgba(33, 150, 243, 0.30)',
|
|
118
|
+
'status-info-strong': 'rgba(33, 150, 243, 0.50)',
|
|
99
119
|
|
|
100
120
|
// Text on status backgrounds (on-status-*)
|
|
101
121
|
'on-status-success': p.white,
|
|
@@ -104,15 +124,15 @@ export const semanticColorsLight = {
|
|
|
104
124
|
'on-status-info': p.white,
|
|
105
125
|
|
|
106
126
|
// Result/outcome indicators (result-*)
|
|
107
|
-
'result-improve': '#4caf50',
|
|
127
|
+
'result-improve': '#4caf50', // Green - positive outcome
|
|
108
128
|
'result-improve-light': 'rgba(76, 175, 80, 0.12)',
|
|
109
129
|
'result-improve-dark': '#248a24',
|
|
110
|
-
'result-degrade': '#ef5350',
|
|
130
|
+
'result-degrade': '#ef5350', // Red - negative outcome
|
|
111
131
|
'result-degrade-light': 'rgba(239, 83, 80, 0.12)',
|
|
112
132
|
'result-degrade-dark': '#b30000',
|
|
113
|
-
'result-inconclusive': '#9E9A97',
|
|
133
|
+
'result-inconclusive': '#9E9A97', // Gray - no clear result
|
|
114
134
|
'result-inconclusive-light': 'rgba(158, 154, 151, 0.12)',
|
|
115
|
-
'result-neutral': greyRamp[600],
|
|
135
|
+
'result-neutral': greyRamp[600], // Neutral baseline
|
|
116
136
|
|
|
117
137
|
// Text on result backgrounds (on-result-*)
|
|
118
138
|
'on-result-improve': p.white,
|
|
@@ -121,16 +141,16 @@ export const semanticColorsLight = {
|
|
|
121
141
|
|
|
122
142
|
// Data visualization colors (data-*)
|
|
123
143
|
// First 10 colors from discrete rainbow optimized for charts
|
|
124
|
-
'data-1': discreteRainbow[9],
|
|
125
|
-
'data-2': discreteRainbow[14],
|
|
126
|
-
'data-3': discreteRainbow[17],
|
|
127
|
-
'data-4': discreteRainbow[25],
|
|
128
|
-
'data-5': discreteRainbow[8],
|
|
129
|
-
'data-6': discreteRainbow[20],
|
|
130
|
-
'data-7': discreteRainbow[13],
|
|
131
|
-
'data-8': discreteRainbow[15],
|
|
132
|
-
'data-9': discreteRainbow[3],
|
|
133
|
-
'data-10': discreteRainbow[22],
|
|
144
|
+
'data-1': discreteRainbow[9], // Blue
|
|
145
|
+
'data-2': discreteRainbow[14], // Green
|
|
146
|
+
'data-3': discreteRainbow[17], // Yellow
|
|
147
|
+
'data-4': discreteRainbow[25], // Red
|
|
148
|
+
'data-5': discreteRainbow[8], // Purple
|
|
149
|
+
'data-6': discreteRainbow[20], // Orange
|
|
150
|
+
'data-7': discreteRainbow[13], // Light Blue
|
|
151
|
+
'data-8': discreteRainbow[15], // Light Green
|
|
152
|
+
'data-9': discreteRainbow[3], // Lavender
|
|
153
|
+
'data-10': discreteRainbow[22], // Dark Orange
|
|
134
154
|
|
|
135
155
|
// Text colors (text-*)
|
|
136
156
|
'text-primary': '#121828',
|
|
@@ -143,10 +163,10 @@ export const semanticColorsLight = {
|
|
|
143
163
|
|
|
144
164
|
// Surface colors (surface-*) - for elevated containers
|
|
145
165
|
'surface-base': p.white,
|
|
146
|
-
'surface-elevated': greyRamp[50],
|
|
147
|
-
'surface-raised': greyRamp[100],
|
|
166
|
+
'surface-elevated': greyRamp[50], // slightly off-white for elevated cards
|
|
167
|
+
'surface-raised': greyRamp[100], // light gray for raised cards
|
|
148
168
|
'surface-overlay': p.white,
|
|
149
|
-
'surface-input': greyRamp[50],
|
|
169
|
+
'surface-input': greyRamp[50], // Input field background (filled variant)
|
|
150
170
|
|
|
151
171
|
// Background colors (background-*)
|
|
152
172
|
'background-base': '#EBEBEB',
|
|
@@ -157,12 +177,12 @@ export const semanticColorsLight = {
|
|
|
157
177
|
'background-frame': greyRamp[400],
|
|
158
178
|
|
|
159
179
|
// Border colors (border-*)
|
|
160
|
-
'border-prominent': greyRamp[400],
|
|
180
|
+
'border-prominent': greyRamp[400], // high-visibility divider
|
|
161
181
|
'border-focus': ramp.blue[600],
|
|
162
|
-
'border-input': greyRamp[200],
|
|
163
|
-
'border-input-hover': greyRamp[400],
|
|
164
|
-
'border-input-focus': ramp.blue[600],
|
|
165
|
-
'border-input-error': ramp.red[600],
|
|
182
|
+
'border-input': greyRamp[200], // Input field border
|
|
183
|
+
'border-input-hover': greyRamp[400], // Input field border on hover
|
|
184
|
+
'border-input-focus': ramp.blue[600], // Input field border on focus
|
|
185
|
+
'border-input-error': ramp.red[600], // Input field border on error
|
|
166
186
|
|
|
167
187
|
// Alpha hairline separators (surface-independent — composite toward black on
|
|
168
188
|
// light surfaces, mirroring the dark-mode white-alpha family). See §4/S-2.
|
|
@@ -179,7 +199,7 @@ export const semanticColorsLight = {
|
|
|
179
199
|
'interactive-disabled-text': 'rgba(55, 65, 81, 0.26)',
|
|
180
200
|
|
|
181
201
|
// Divider
|
|
182
|
-
|
|
202
|
+
divider: '#E8E9EB',
|
|
183
203
|
|
|
184
204
|
// Avatar default
|
|
185
205
|
'avatar-background': greyRamp[600],
|
|
@@ -193,6 +213,8 @@ export const semanticColorsDark = {
|
|
|
193
213
|
'brand-primary-light': ramp.orange[300],
|
|
194
214
|
'brand-primary-dark': ramp.orange[500],
|
|
195
215
|
'brand-primary-subtle': 'rgba(255, 121, 0, 0.12)',
|
|
216
|
+
'brand-primary-muted': 'rgba(255, 121, 0, 0.30)',
|
|
217
|
+
'brand-primary-strong': 'rgba(255, 121, 0, 0.50)',
|
|
196
218
|
'brand-primary-hover': ramp.orange[300],
|
|
197
219
|
'brand-primary-active': ramp.orange[200],
|
|
198
220
|
|
|
@@ -200,6 +222,8 @@ export const semanticColorsDark = {
|
|
|
200
222
|
'brand-secondary-light': ramp.cyan[500],
|
|
201
223
|
'brand-secondary-dark': ramp.cyan[700],
|
|
202
224
|
'brand-secondary-subtle': 'rgba(48, 123, 155, 0.12)',
|
|
225
|
+
'brand-secondary-muted': 'rgba(48, 123, 155, 0.30)',
|
|
226
|
+
'brand-secondary-strong': 'rgba(48, 123, 155, 0.50)',
|
|
203
227
|
'brand-secondary-hover': ramp.cyan[500],
|
|
204
228
|
'brand-secondary-active': ramp.cyan[400],
|
|
205
229
|
|
|
@@ -212,6 +236,8 @@ export const semanticColorsDark = {
|
|
|
212
236
|
'status-success-light': ramp.green[200],
|
|
213
237
|
'status-success-dark': ramp.green[600],
|
|
214
238
|
'status-success-subtle': 'rgba(46, 213, 115, 0.12)',
|
|
239
|
+
'status-success-muted': 'rgba(46, 213, 115, 0.30)',
|
|
240
|
+
'status-success-strong': 'rgba(46, 213, 115, 0.50)',
|
|
215
241
|
|
|
216
242
|
// Live-session accent — its OWN role, decoupled from success so the two can diverge
|
|
217
243
|
'status-live': ramp.green[300],
|
|
@@ -221,21 +247,29 @@ export const semanticColorsDark = {
|
|
|
221
247
|
'status-error-light': ramp.red[500],
|
|
222
248
|
'status-error-dark': ramp.red[700],
|
|
223
249
|
'status-error-subtle': 'rgba(209, 67, 67, 0.12)',
|
|
250
|
+
'status-error-muted': 'rgba(209, 67, 67, 0.30)',
|
|
251
|
+
'status-error-strong': 'rgba(209, 67, 67, 0.50)',
|
|
224
252
|
|
|
225
|
-
'status-error-vivid':
|
|
253
|
+
'status-error-vivid': alertRedVivid,
|
|
226
254
|
'status-error-vivid-light': ramp.red[500],
|
|
227
255
|
'status-error-vivid-dark': ramp.red[700],
|
|
228
256
|
'status-error-vivid-subtle': 'rgba(255, 71, 87, 0.12)',
|
|
257
|
+
'status-error-vivid-muted': 'rgba(255, 71, 87, 0.30)',
|
|
258
|
+
'status-error-vivid-strong': 'rgba(255, 71, 87, 0.50)',
|
|
229
259
|
|
|
230
260
|
'status-warning': ramp.amber[300],
|
|
231
261
|
'status-warning-light': ramp.amber[200],
|
|
232
262
|
'status-warning-dark': ramp.amber[500],
|
|
233
263
|
'status-warning-subtle': 'rgba(249, 180, 21, 0.12)',
|
|
264
|
+
'status-warning-muted': 'rgba(249, 180, 21, 0.30)',
|
|
265
|
+
'status-warning-strong': 'rgba(249, 180, 21, 0.50)',
|
|
234
266
|
|
|
235
267
|
'status-info': ramp.blue[500],
|
|
236
268
|
'status-info-light': ramp.blue[300],
|
|
237
269
|
'status-info-dark': ramp.blue[600],
|
|
238
270
|
'status-info-subtle': 'rgba(33, 150, 243, 0.12)',
|
|
271
|
+
'status-info-muted': 'rgba(33, 150, 243, 0.30)',
|
|
272
|
+
'status-info-strong': 'rgba(33, 150, 243, 0.50)',
|
|
239
273
|
|
|
240
274
|
// Text on status backgrounds
|
|
241
275
|
'on-status-success': p.white,
|
|
@@ -295,20 +329,20 @@ export const semanticColorsDark = {
|
|
|
295
329
|
// `background-base` backs `Surface level="background"` (SurfaceContext.SURFACE_LEVEL_TOKEN),
|
|
296
330
|
// so it takes the ramp's shell role. The deepest plane is `background-frame`,
|
|
297
331
|
// which is also the `SurfaceLevel` floor a pressed surface clamps at.
|
|
298
|
-
'surface-base': greyRamp[925],
|
|
299
|
-
'surface-elevated': greyRamp[900],
|
|
300
|
-
'surface-raised': greyRamp[875],
|
|
301
|
-
'surface-overlay': greyRamp[850],
|
|
302
|
-
'surface-input': greyRamp[900],
|
|
332
|
+
'surface-base': greyRamp[925], // main surface (#252321, L*13.9)
|
|
333
|
+
'surface-elevated': greyRamp[900], // elevated surface (#2C2A28, L*17.2 — nav/rail)
|
|
334
|
+
'surface-raised': greyRamp[875], // raised surface (#31302F, L*19.9 — cards)
|
|
335
|
+
'surface-overlay': greyRamp[850], // overlay surface (#373635, L*22.7 — hero/popover)
|
|
336
|
+
'surface-input': greyRamp[900], // input surface (#2C2A28 — one plane above base)
|
|
303
337
|
|
|
304
338
|
// Background colors — same ramp, the frame/shell end of it.
|
|
305
|
-
'background-base': greyRamp[950],
|
|
306
|
-
'background-default': greyRamp[925],
|
|
307
|
-
'background-subtle': greyRamp[900],
|
|
339
|
+
'background-base': greyRamp[950], // shell (#1C1916, L*9 — Surface level="background")
|
|
340
|
+
'background-default': greyRamp[925], // main background (#252321, L*13.9 — matches surface-base)
|
|
341
|
+
'background-subtle': greyRamp[900], // subtle background (#2C2A28, L*17.2 — matches surface-elevated)
|
|
308
342
|
// Frame/bezel chrome — the top bar + side nav shell, one step BELOW
|
|
309
343
|
// `background-base`. It used to be described as sitting OUTSIDE the ramp; it
|
|
310
344
|
// is simply the ramp's last step now, and the floor `<Surface pressed>` clamps at.
|
|
311
|
-
'background-frame': greyRamp[975],
|
|
345
|
+
'background-frame': greyRamp[975], // frame / bezel (#100D0A, L*3.8)
|
|
312
346
|
|
|
313
347
|
// Border colors — solid dark borders are RETIRED (TD-07.14). Not a preference — a structural
|
|
314
348
|
// consequence of one ramp. Every step from 850 to 975 is now a surface plane,
|
|
@@ -326,7 +360,7 @@ export const semanticColorsDark = {
|
|
|
326
360
|
// `border-prominent` stays SOLID: it is the one border meant to be seen
|
|
327
361
|
// outright (4 call sites, high-visibility dividers), and grey-800 is not a
|
|
328
362
|
// plane, so it keeps its job without collision.
|
|
329
|
-
'border-prominent': greyRamp[800],
|
|
363
|
+
'border-prominent': greyRamp[800], // high-visibility divider
|
|
330
364
|
'border-focus': '#828DF8',
|
|
331
365
|
'border-input': greyRamp[700],
|
|
332
366
|
'border-input-hover': greyRamp[600],
|
|
@@ -376,7 +410,7 @@ export const semanticColorsDark = {
|
|
|
376
410
|
'interactive-disabled-text': 'rgba(255, 255, 255, 0.26)',
|
|
377
411
|
|
|
378
412
|
// Divider
|
|
379
|
-
|
|
413
|
+
divider: 'rgba(255, 255, 255, 0.09)',
|
|
380
414
|
|
|
381
415
|
// Avatar default
|
|
382
416
|
'avatar-background': greyRamp[700],
|