@titan-design/react-ui 0.11.0 → 0.12.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/dist/bodymap.js +173 -343
- package/dist/bodymap.js.map +1 -1
- package/dist/bodymap.mjs +173 -343
- package/dist/bodymap.mjs.map +1 -1
- package/dist/index.d.mts +24 -21
- package/dist/index.d.ts +24 -21
- package/dist/index.js +366 -561
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +360 -553
- package/dist/index.mjs.map +1 -1
- package/dist/pages.js +242 -407
- package/dist/pages.js.map +1 -1
- package/dist/pages.mjs +242 -407
- package/dist/pages.mjs.map +1 -1
- package/dist/theme/index.d.mts +409 -415
- package/dist/theme/index.d.ts +409 -415
- package/dist/theme/index.js +234 -408
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +227 -399
- package/dist/theme/index.mjs.map +1 -1
- package/dist/theme/tokens-css.js +141 -140
- package/dist/theme/tokens-css.js.map +1 -1
- package/dist/theme/tokens-css.mjs +141 -140
- package/dist/theme/tokens-css.mjs.map +1 -1
- package/package.json +1 -1
- package/src/arch/Architecture.stories.tsx +9 -9
- package/src/components/custom/DateTime/DateTime.stories.tsx +1 -1
- package/src/components/custom/Fatigue/DualGhostSpark.stories.tsx +3 -3
- package/src/components/custom/Fatigue/FatigueLights.stories.tsx +2 -2
- package/src/components/custom/Fatigue/GhostSpark.stories.tsx +3 -3
- package/src/components/custom/Fatigue/LiveFatigueCard.tsx +1 -1
- package/src/components/custom/Fatigue/LiveFatiguePanel.stories.tsx +2 -2
- package/src/components/custom/Fatigue/RomProgressionChart.stories.tsx +2 -2
- package/src/components/custom/Fatigue/SilverRedPalette.stories.tsx +4 -4
- package/src/components/custom/Fatigue/VelocityHero.stories.tsx +3 -3
- package/src/components/custom/Fatigue/VerdictHero.stories.tsx +2 -2
- package/src/components/custom/Fatigue/fatigue-tokens.ts +12 -12
- package/src/components/custom/Sidebar/Sidebar.tsx +4 -4
- package/src/components/custom/Table/Table.tsx +2 -2
- package/src/components/custom/Workout/ActiveWorkoutPage.tsx +3 -3
- package/src/components/custom/Workout/BaseBadge.test.tsx +6 -1
- package/src/components/custom/Workout/BaseBadge.tsx +1 -1
- package/src/components/custom/Workout/BodyMap.tsx +2 -2
- package/src/components/custom/Workout/BodyMapDetailPanel.tsx +2 -2
- package/src/components/custom/Workout/DeviationBar.test.tsx +2 -1
- package/src/components/custom/Workout/DeviationBar.tsx +3 -2
- package/src/components/custom/Workout/ExerciseCard.test.tsx +3 -3
- package/src/components/custom/Workout/ExerciseCard.tsx +2 -2
- package/src/components/custom/Workout/ExerciseDetailPage.tsx +4 -4
- package/src/components/custom/Workout/InputBar.tsx +2 -2
- package/src/components/custom/Workout/LiveAuraFrame.stories.tsx +1 -1
- package/src/components/custom/Workout/LiveAuraFrame.test.tsx +1 -1
- package/src/components/custom/Workout/LiveAuraFrame.tsx +3 -3
- package/src/components/custom/Workout/MesoCard.tsx +3 -1
- package/src/components/custom/Workout/MuscleGroupChip.tsx +4 -3
- package/src/components/custom/Workout/PrHistoryModal.tsx +2 -2
- package/src/components/custom/Workout/ProgramPlanningPage.tsx +1 -1
- package/src/components/custom/Workout/ReadinessCheck.tsx +2 -2
- package/src/components/custom/Workout/RestTimer.tsx +2 -2
- package/src/components/custom/Workout/S3SetTypes.stories.tsx +3 -3
- package/src/components/custom/Workout/SessionHeader.stories.tsx +2 -2
- package/src/components/custom/Workout/SessionHeader.tsx +1 -1
- package/src/components/custom/Workout/SessionRail.stories.tsx +2 -2
- package/src/components/custom/Workout/SessionRail.tsx +13 -5
- package/src/components/custom/Workout/SetBar.tsx +3 -3
- package/src/components/custom/Workout/SetRow.test.tsx +6 -3
- package/src/components/custom/Workout/StatusDot.tsx +5 -4
- package/src/components/custom/Workout/StrengthTrendChart.tsx +1 -1
- package/src/components/custom/Workout/TrainingStatusPage.tsx +2 -2
- package/src/components/custom/Workout/VelocityStrip.test.tsx +5 -2
- package/src/components/custom/Workout/VelocityStrip.tsx +4 -4
- package/src/components/custom/Workout/VolumeLandmarkBar.tsx +3 -3
- package/src/components/custom/Workout/WeightBadge.test.tsx +6 -1
- package/src/components/custom/Workout/WeightBadge.tsx +2 -1
- package/src/components/custom/Workout/WorkoutCard.tsx +3 -1
- package/src/components/custom/Workout/WorkoutPill.tsx +5 -2
- package/src/components/custom/Workout/ZoneTrack.tsx +4 -4
- package/src/components/custom/Workout/setHeadingKit.tsx +14 -8
- package/src/components/custom/Workout/velocity-story-kit.tsx +2 -2
- package/src/components/custom/charts/SetBarChart.tsx +3 -3
- package/src/components/custom/stepper/Stepper.stories.tsx +1 -1
- package/src/components/custom/stepper/Stepper.tsx +3 -3
- package/src/components/shell/DeviceMenu.tsx +2 -2
- package/src/components/shell/SideNav.tsx +1 -1
- package/src/components/shell/TopBar.tsx +1 -1
- package/src/components/ui/autocomplete/Autocomplete.stories.tsx +1 -1
- package/src/components/ui/autocomplete/Autocomplete.tsx +1 -1
- package/src/components/ui/avatar/Avatar.tsx +2 -2
- package/src/components/ui/badge/Badge.tsx +2 -2
- package/src/components/ui/card/Card.tsx +3 -3
- package/src/components/ui/checkbox/Checkbox.tsx +1 -1
- package/src/components/ui/collapse/Collapse.tsx +1 -1
- package/src/components/ui/data-row/DataRow.stories.tsx +1 -1
- package/src/components/ui/drawer/Drawer.tsx +3 -3
- package/src/components/ui/form-field/FormField.tsx +1 -1
- package/src/components/ui/help-tip/HelpTip.tsx +1 -1
- package/src/components/ui/menu/Menu.tsx +2 -2
- package/src/components/ui/pill/Pill.tsx +2 -2
- package/src/components/ui/popover/Popover.stories.tsx +2 -2
- package/src/components/ui/popover/Popover.tsx +1 -1
- package/src/components/ui/progress/Progress.tsx +3 -3
- package/src/components/ui/radio/Radio.stories.tsx +1 -1
- package/src/components/ui/radio/Radio.tsx +4 -4
- package/src/components/ui/select/Select.tsx +3 -3
- package/src/components/ui/surface/Surface.stories.tsx +3 -3
- package/src/components/ui/surface/Surface.test.tsx +32 -19
- package/src/components/ui/surface/Surface.tsx +3 -3
- package/src/components/ui/surface/SurfaceContext.ts +19 -29
- package/src/components/ui/surface/surface.contract.test.ts +57 -44
- package/src/components/ui/switch/Switch.tsx +1 -1
- package/src/components/ui/tabs/Tabs.tsx +2 -2
- package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +5 -5
- package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +1 -1
- package/src/components/ui/toolbar-button/ToolbarButton.tsx +36 -22
- package/src/stories/PresetShowcase.stories.tsx +21 -21
- package/src/theme/ColorPalettes.stories.tsx +41 -38
- package/src/theme/ColorPrimitives.stories.tsx +89 -41
- package/src/theme/Depth.stories.tsx +312 -0
- package/src/theme/DepthCalibration.stories.tsx +655 -0
- package/src/theme/ThemeProvider.tsx +1 -1
- package/src/theme/barrel.ts +7 -14
- package/src/theme/color-stories.coverage.test.ts +15 -20
- package/src/theme/color-story-kit.tsx +1 -1
- package/src/theme/color-utils.ts +197 -0
- package/src/theme/config.ts +0 -8
- package/src/theme/depth-calibration.test.tsx +97 -0
- package/src/theme/elevation.test.ts +62 -1
- package/src/theme/elevation.ts +34 -8
- package/src/theme/global.css +47 -53
- package/src/theme/grey-ramp.test.ts +166 -0
- package/src/theme/materials.test.ts +106 -0
- package/src/theme/materials.ts +211 -0
- package/src/theme/presets/audiobook.ts +4 -4
- package/src/theme/presets/types.ts +3 -3
- package/src/theme/semantic-contrast.test.ts +83 -0
- package/src/theme/tokens/primitives.ts +62 -115
- package/src/theme/tokens/semantic.ts +130 -82
- package/src/utils/colors.ts +1 -1
- package/tailwind.config.js +2 -5
- package/src/theme/bar-paper.ts +0 -59
- package/src/theme/shadows.stories.tsx +0 -523
- package/src/theme/shadows.ts +0 -439
package/dist/bodymap.js
CHANGED
|
@@ -18,52 +18,37 @@ function cn(...inputs) {
|
|
|
18
18
|
|
|
19
19
|
// src/theme/tokens/primitives.ts
|
|
20
20
|
var primitiveColors = {
|
|
21
|
-
// Blue scale
|
|
22
|
-
blue: {
|
|
23
|
-
400: "#60A5FA",
|
|
24
|
-
600: "#5048E5",
|
|
25
|
-
700: "#3832A0"},
|
|
26
|
-
// Red scale
|
|
27
|
-
red: {
|
|
28
|
-
500: "#EF4444",
|
|
29
|
-
600: "#D14343"},
|
|
30
|
-
// Vivid red scale
|
|
31
|
-
redVivid: {
|
|
32
|
-
400: "#FF6070",
|
|
33
|
-
500: "#FF4757",
|
|
34
|
-
700: "#C42539"},
|
|
35
|
-
// Neutral/Gray scale
|
|
36
|
-
neutral: {
|
|
37
|
-
50: "#FAFAFA",
|
|
38
|
-
100: "#F3F4F6",
|
|
39
|
-
300: "#D1D5DB",
|
|
40
|
-
400: "#9CA3AF",
|
|
41
|
-
500: "#6B7280",
|
|
42
|
-
600: "#4B5563",
|
|
43
|
-
900: "#111827"},
|
|
44
|
-
// Charcoal scale (dark backgrounds)
|
|
45
|
-
charcoal: {
|
|
46
|
-
200: "#3C3C3C",
|
|
47
|
-
300: "#2C2C2C",
|
|
48
|
-
400: "#1F1F1F",
|
|
49
|
-
500: "#1C1C1C"},
|
|
50
|
-
// Pure colors
|
|
51
21
|
white: "#FFFFFF"};
|
|
52
|
-
var
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
// L*
|
|
57
|
-
|
|
58
|
-
// L*
|
|
59
|
-
|
|
60
|
-
// L*
|
|
61
|
-
|
|
62
|
-
// L*
|
|
63
|
-
|
|
64
|
-
// L*
|
|
22
|
+
var greyRamp = {
|
|
23
|
+
50: "#F9F6F3",
|
|
24
|
+
// L*97.0 W6
|
|
25
|
+
100: "#EDEAE7",
|
|
26
|
+
// L*92.8 W6
|
|
27
|
+
200: "#D4D1CE",
|
|
28
|
+
// L*75.7 W6
|
|
29
|
+
400: "#A29F9D",
|
|
30
|
+
// L*65.7 W5
|
|
31
|
+
500: "#888684",
|
|
32
|
+
// L*56.0 W4
|
|
33
|
+
600: "#72716F",
|
|
34
|
+
// L*47.7 W3
|
|
35
|
+
700: "#5A5958",
|
|
36
|
+
// L*37.9 W2
|
|
37
|
+
800: "#424140",
|
|
38
|
+
// L*27.6 W2 — generated bridge
|
|
39
|
+
850: "#373635",
|
|
40
|
+
// L*22.7 W2 — surface overlay
|
|
41
|
+
875: "#31302F",
|
|
42
|
+
// L*19.9 W2 — surface raised
|
|
43
|
+
900: "#2C2A28",
|
|
44
|
+
// L*17.2 W4 — surface elevated
|
|
45
|
+
925: "#252321",
|
|
46
|
+
// L*13.9 W4 — surface base
|
|
47
|
+
950: "#1C1916",
|
|
48
|
+
// L*9.0 W6 — background base / shell
|
|
49
|
+
975: "#100D0A"
|
|
50
|
+
// L*3.8 W6 — background frame / bezel
|
|
65
51
|
};
|
|
66
|
-
var backgroundFrameDark = "#100D0A";
|
|
67
52
|
var primitiveRamps = {
|
|
68
53
|
red: {
|
|
69
54
|
50: "#FFF4F4",
|
|
@@ -100,9 +85,11 @@ var primitiveRamps = {
|
|
|
100
85
|
blue: {
|
|
101
86
|
50: "#EFF8FF",
|
|
102
87
|
300: "#78C2FF",
|
|
88
|
+
400: "#3CA8FF",
|
|
103
89
|
500: "#2196F3",
|
|
104
90
|
// pin
|
|
105
|
-
600: "#1072CB"
|
|
91
|
+
600: "#1072CB",
|
|
92
|
+
700: "#135AA8"}};
|
|
106
93
|
var divergingScale = [
|
|
107
94
|
primitiveRamps.blue[500],
|
|
108
95
|
// under
|
|
@@ -177,10 +164,10 @@ var semanticColorsLight = {
|
|
|
177
164
|
"status-error-light": primitiveRamps.red[500],
|
|
178
165
|
"status-error-dark": primitiveRamps.red[700],
|
|
179
166
|
"status-error-subtle": primitiveRamps.red[50],
|
|
180
|
-
"status-error-vivid":
|
|
167
|
+
"status-error-vivid": primitiveRamps.red[600],
|
|
181
168
|
// vivid alert red
|
|
182
|
-
"status-error-vivid-light":
|
|
183
|
-
"status-error-vivid-dark":
|
|
169
|
+
"status-error-vivid-light": primitiveRamps.red[500],
|
|
170
|
+
"status-error-vivid-dark": primitiveRamps.red[700],
|
|
184
171
|
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
185
172
|
"status-warning": primitiveRamps.amber[300],
|
|
186
173
|
"status-warning-light": primitiveRamps.amber[200],
|
|
@@ -207,7 +194,7 @@ var semanticColorsLight = {
|
|
|
207
194
|
"result-inconclusive": "#9E9A97",
|
|
208
195
|
// Gray - no clear result
|
|
209
196
|
"result-inconclusive-light": "rgba(158, 154, 151, 0.12)",
|
|
210
|
-
"result-neutral":
|
|
197
|
+
"result-neutral": greyRamp[600],
|
|
211
198
|
// Neutral baseline
|
|
212
199
|
// Text on result backgrounds (on-result-*)
|
|
213
200
|
"on-result-improve": primitiveColors.white,
|
|
@@ -238,47 +225,38 @@ var semanticColorsLight = {
|
|
|
238
225
|
// Text colors (text-*)
|
|
239
226
|
"text-primary": "#121828",
|
|
240
227
|
"text-secondary": "#65748B",
|
|
241
|
-
"text-tertiary":
|
|
228
|
+
"text-tertiary": greyRamp[400],
|
|
242
229
|
"text-disabled": "rgba(55, 65, 81, 0.48)",
|
|
243
230
|
"text-inverse": primitiveColors.white,
|
|
244
|
-
"text-link":
|
|
245
|
-
"text-link-hover":
|
|
231
|
+
"text-link": primitiveRamps.blue[600],
|
|
232
|
+
"text-link-hover": primitiveRamps.blue[700],
|
|
246
233
|
// Surface colors (surface-*) - for elevated containers
|
|
247
234
|
"surface-base": primitiveColors.white,
|
|
248
|
-
"surface-elevated":
|
|
235
|
+
"surface-elevated": greyRamp[50],
|
|
249
236
|
// slightly off-white for elevated cards
|
|
250
|
-
"surface-raised":
|
|
237
|
+
"surface-raised": greyRamp[100],
|
|
251
238
|
// light gray for raised cards
|
|
252
239
|
"surface-overlay": primitiveColors.white,
|
|
253
|
-
"surface-input":
|
|
240
|
+
"surface-input": greyRamp[50],
|
|
254
241
|
// Input field background (filled variant)
|
|
255
|
-
// Deepest pressed pit (TD-surface-tokens, S-3) — light-mode counterpart of
|
|
256
|
-
// the dark ramp's `inset` plane; a placeholder pairing, not part of the
|
|
257
|
-
// dark-ramp investigation (surface.contract.test.ts is dark-mode only).
|
|
258
|
-
"surface-inset": primitiveColors.neutral[300],
|
|
259
242
|
// Background colors (background-*)
|
|
260
243
|
"background-base": "#EBEBEB",
|
|
261
244
|
"background-default": primitiveColors.white,
|
|
262
|
-
"background-subtle":
|
|
263
|
-
// Frame/bezel chrome
|
|
264
|
-
//
|
|
265
|
-
|
|
266
|
-
// mode (see dark-mode note on `surface-inset` above).
|
|
267
|
-
"background-frame": primitiveColors.neutral[400],
|
|
245
|
+
"background-subtle": greyRamp[50],
|
|
246
|
+
// Frame/bezel chrome — top bar + side nav shell, one step below
|
|
247
|
+
// `background-base`. Placeholder pairing for light mode, which is deferred.
|
|
248
|
+
"background-frame": greyRamp[400],
|
|
268
249
|
// Border colors (border-*)
|
|
269
|
-
"border-
|
|
270
|
-
"border-subtle": primitiveColors.neutral[100],
|
|
271
|
-
"border-strong": primitiveColors.neutral[300],
|
|
272
|
-
"border-prominent": primitiveColors.neutral[400],
|
|
250
|
+
"border-prominent": greyRamp[400],
|
|
273
251
|
// high-visibility divider
|
|
274
|
-
"border-focus":
|
|
275
|
-
"border-input":
|
|
252
|
+
"border-focus": primitiveRamps.blue[600],
|
|
253
|
+
"border-input": greyRamp[200],
|
|
276
254
|
// Input field border
|
|
277
|
-
"border-input-hover":
|
|
255
|
+
"border-input-hover": greyRamp[400],
|
|
278
256
|
// Input field border on hover
|
|
279
|
-
"border-input-focus":
|
|
257
|
+
"border-input-focus": primitiveRamps.blue[600],
|
|
280
258
|
// Input field border on focus
|
|
281
|
-
"border-input-error":
|
|
259
|
+
"border-input-error": primitiveRamps.red[600],
|
|
282
260
|
// Input field border on error
|
|
283
261
|
// Alpha hairline separators (surface-independent — composite toward black on
|
|
284
262
|
// light surfaces, mirroring the dark-mode white-alpha family). See §4/S-2.
|
|
@@ -295,7 +273,7 @@ var semanticColorsLight = {
|
|
|
295
273
|
// Divider
|
|
296
274
|
"divider": "#E8E9EB",
|
|
297
275
|
// Avatar default
|
|
298
|
-
"avatar-background":
|
|
276
|
+
"avatar-background": greyRamp[600],
|
|
299
277
|
"avatar-text": primitiveColors.white
|
|
300
278
|
};
|
|
301
279
|
var semanticColorsDark = {
|
|
@@ -327,9 +305,9 @@ var semanticColorsDark = {
|
|
|
327
305
|
"status-error-light": primitiveRamps.red[500],
|
|
328
306
|
"status-error-dark": primitiveRamps.red[700],
|
|
329
307
|
"status-error-subtle": "rgba(209, 67, 67, 0.12)",
|
|
330
|
-
"status-error-vivid":
|
|
331
|
-
"status-error-vivid-light":
|
|
332
|
-
"status-error-vivid-dark":
|
|
308
|
+
"status-error-vivid": primitiveRamps.red[600],
|
|
309
|
+
"status-error-vivid-light": primitiveRamps.red[500],
|
|
310
|
+
"status-error-vivid-dark": primitiveRamps.red[700],
|
|
333
311
|
"status-error-vivid-subtle": "rgba(255, 71, 87, 0.12)",
|
|
334
312
|
"status-warning": primitiveRamps.amber[300],
|
|
335
313
|
"status-warning-light": primitiveRamps.amber[200],
|
|
@@ -353,7 +331,7 @@ var semanticColorsDark = {
|
|
|
353
331
|
"result-degrade-dark": "#b30000",
|
|
354
332
|
"result-inconclusive": "#9E9A97",
|
|
355
333
|
"result-inconclusive-light": "rgba(158, 154, 151, 0.16)",
|
|
356
|
-
"result-neutral":
|
|
334
|
+
"result-neutral": greyRamp[400],
|
|
357
335
|
// Text on result backgrounds
|
|
358
336
|
"on-result-improve": primitiveColors.white,
|
|
359
337
|
"on-result-degrade": primitiveColors.white,
|
|
@@ -370,74 +348,106 @@ var semanticColorsDark = {
|
|
|
370
348
|
"data-9": discreteRainbow[3],
|
|
371
349
|
"data-10": discreteRainbow[22],
|
|
372
350
|
// Text colors - inverted for dark mode
|
|
373
|
-
"text-primary":
|
|
374
|
-
"text-secondary":
|
|
375
|
-
|
|
351
|
+
"text-primary": greyRamp[50],
|
|
352
|
+
"text-secondary": greyRamp[400],
|
|
353
|
+
// Deliberately ONE step lighter than the L*-nearest match (`greyRamp[600]`).
|
|
354
|
+
// The colour this replaced failed WCAG large-text outright on the three
|
|
355
|
+
// lightest planes — 2.96 / 2.72 / 2.49 against elevated / raised / overlay —
|
|
356
|
+
// and `600` carried that failure forward almost exactly (2.93 / 2.70 / 2.47).
|
|
357
|
+
// `500` clears 3:1 everywhere (3.32–5.34). Contrast beats colour fidelity for
|
|
358
|
+
// text roles; borders and surfaces still use strict L*-nearest. See
|
|
359
|
+
// semantic-contrast.test.ts, which fails if this is moved back down.
|
|
360
|
+
"text-tertiary": greyRamp[500],
|
|
376
361
|
"text-disabled": "rgba(255, 255, 255, 0.38)",
|
|
377
|
-
"text-inverse":
|
|
362
|
+
"text-inverse": greyRamp[950],
|
|
378
363
|
"text-link": "#828DF8",
|
|
379
|
-
"text-link-hover":
|
|
364
|
+
"text-link-hover": primitiveRamps.blue[400],
|
|
380
365
|
// Surface colors - dark backgrounds — warm-tapered DERIVED ramp (TD-surface-tokens,
|
|
381
366
|
// S-1, re-spaced S-3). Shipped verbatim from `deriveSurfaceRamp()` — see
|
|
382
367
|
// `surfaceRampDark` in primitives.ts for the full derivation note. `surface-overlay`
|
|
383
368
|
// and `surface-elevated` are distinct (were both #191919 pre-S-1); `surface-input`
|
|
384
369
|
// tracks one plane above `surface-base`, same relative position as before the remap.
|
|
385
370
|
// `background-base` backs `Surface level="background"` (SurfaceContext.SURFACE_LEVEL_TOKEN),
|
|
386
|
-
// so it takes the ramp's
|
|
387
|
-
//
|
|
388
|
-
|
|
389
|
-
//
|
|
390
|
-
"surface-
|
|
391
|
-
//
|
|
392
|
-
"surface-
|
|
393
|
-
//
|
|
394
|
-
"surface-
|
|
395
|
-
//
|
|
396
|
-
"surface-
|
|
397
|
-
// overlay surface (#373635, L*22.5 — hero/popover)
|
|
398
|
-
"surface-input": surfaceRampDark.elevated,
|
|
371
|
+
// so it takes the ramp's shell role. The deepest plane is `background-frame`,
|
|
372
|
+
// which is also the `SurfaceLevel` floor a pressed surface clamps at.
|
|
373
|
+
"surface-base": greyRamp[925],
|
|
374
|
+
// main surface (#252321, L*13.9)
|
|
375
|
+
"surface-elevated": greyRamp[900],
|
|
376
|
+
// elevated surface (#2C2A28, L*17.2 — nav/rail)
|
|
377
|
+
"surface-raised": greyRamp[875],
|
|
378
|
+
// raised surface (#31302F, L*19.9 — cards)
|
|
379
|
+
"surface-overlay": greyRamp[850],
|
|
380
|
+
// overlay surface (#373635, L*22.7 — hero/popover)
|
|
381
|
+
"surface-input": greyRamp[900],
|
|
399
382
|
// input surface (#2C2A28 — one plane above base)
|
|
400
|
-
"surface-inset": surfaceRampDark.inset,
|
|
401
|
-
// deepest pressed pit (#13100D, L*4.5 — sub-shell well)
|
|
402
383
|
// Background colors — same ramp, the frame/shell end of it.
|
|
403
|
-
"background-base":
|
|
404
|
-
// shell
|
|
405
|
-
"background-default":
|
|
406
|
-
// main background (#252321, L*13.
|
|
407
|
-
"background-subtle":
|
|
408
|
-
// subtle background (#2C2A28, L*17 — matches surface-elevated)
|
|
409
|
-
// Frame/bezel chrome
|
|
410
|
-
// `background-base
|
|
411
|
-
// ramp
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
//
|
|
415
|
-
//
|
|
416
|
-
//
|
|
417
|
-
//
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
|
|
421
|
-
//
|
|
422
|
-
"
|
|
423
|
-
//
|
|
424
|
-
|
|
425
|
-
//
|
|
426
|
-
|
|
384
|
+
"background-base": greyRamp[950],
|
|
385
|
+
// shell (#1C1916, L*9 — Surface level="background")
|
|
386
|
+
"background-default": greyRamp[925],
|
|
387
|
+
// main background (#252321, L*13.9 — matches surface-base)
|
|
388
|
+
"background-subtle": greyRamp[900],
|
|
389
|
+
// subtle background (#2C2A28, L*17.2 — matches surface-elevated)
|
|
390
|
+
// Frame/bezel chrome — the top bar + side nav shell, one step BELOW
|
|
391
|
+
// `background-base`. It used to be described as sitting OUTSIDE the ramp; it
|
|
392
|
+
// is simply the ramp's last step now, and the floor `<Surface pressed>` clamps at.
|
|
393
|
+
"background-frame": greyRamp[975],
|
|
394
|
+
// frame / bezel (#100D0A, L*3.8)
|
|
395
|
+
// Border colors — solid dark borders are RETIRED (TD-07.14). Not a preference — a structural
|
|
396
|
+
// consequence of one ramp. Every step from 850 to 975 is now a surface plane,
|
|
397
|
+
// so a solid border dark enough to read as a border necessarily equals some
|
|
398
|
+
// plane's fill, which is exactly the collision `surface.contract.test.ts` R2
|
|
399
|
+
// forbids. The only non-plane steps left in that band are 800 and 700, and
|
|
400
|
+
// borders there jump from L*~10-25 to L*~28-38 — a restyle, not a migration.
|
|
401
|
+
//
|
|
402
|
+
// So separation moves to the alpha hairlines, which dark mode already called
|
|
403
|
+
// "the primary separation cue". Being alpha, they composite against whatever
|
|
404
|
+
// plane they land on and cannot collide with any of them — the problem stops
|
|
405
|
+
// existing rather than being re-solved per plane. The three solid tokens were
|
|
406
|
+
// deleted outright; consumers point at the `hairline-*` family below.
|
|
407
|
+
//
|
|
408
|
+
// `border-prominent` stays SOLID: it is the one border meant to be seen
|
|
409
|
+
// outright (4 call sites, high-visibility dividers), and grey-800 is not a
|
|
410
|
+
// plane, so it keeps its job without collision.
|
|
411
|
+
"border-prominent": greyRamp[800],
|
|
427
412
|
// high-visibility divider
|
|
428
413
|
"border-focus": "#828DF8",
|
|
429
|
-
"border-input":
|
|
430
|
-
"border-input-hover":
|
|
414
|
+
"border-input": greyRamp[700],
|
|
415
|
+
"border-input-hover": greyRamp[600],
|
|
431
416
|
"border-input-focus": "#828DF8",
|
|
432
|
-
"border-input-error":
|
|
417
|
+
"border-input-error": primitiveRamps.red[500],
|
|
433
418
|
// Alpha hairline separators — the primary separation cue (§4/S-2). Self-
|
|
434
419
|
// normalizing: composites toward white by ~the same amount on ANY plane, so
|
|
435
420
|
// one family works at every elevation instead of per-surface border tokens.
|
|
436
421
|
// Shadows are demoted to floating-overlay use only (not shipped as a fill
|
|
437
422
|
// separator here — see elevation.ts, follow-up S-4).
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
423
|
+
//
|
|
424
|
+
// RETUNED on the wall (VW-99, S-6). The original .06/.09/.14 were set at a
|
|
425
|
+
// desk. On the panel at ~3 m `subtle` rendered but was indiscernible, and
|
|
426
|
+
// `default` — the load-bearing one, with no solid-border fallback since
|
|
427
|
+
// TD-07.14 — went weak on the lightest plane. `strong` read cleanly with room
|
|
428
|
+
// to spare, which is what made raising the whole family viable.
|
|
429
|
+
//
|
|
430
|
+
// Each tier steps up onto the next MEASURED-GOOD rung rather than an
|
|
431
|
+
// interpolated one: the new `subtle` is the old `default`, and the new
|
|
432
|
+
// `default` is the old `strong` — a value just confirmed legible on all four
|
|
433
|
+
// planes. Spacing goes 1 : 1.56 : 2.33, against the original 1 : 1.5 : 2.33.
|
|
434
|
+
//
|
|
435
|
+
// RUN 2 (VW-99): all three tiers were seen on all four planes — the retune
|
|
436
|
+
// worked — but `subtle` was still "a bit hard to read", so the whole family
|
|
437
|
+
// took a further +.01. That is a comfort margin on a passing row, not a fix
|
|
438
|
+
// for a failing one, which is why it is a flat offset: the 1 : 1.56 : 2.33
|
|
439
|
+
// spacing that the run validated is preserved rather than re-derived.
|
|
440
|
+
//
|
|
441
|
+
// Keep these to TWO decimals. react-native-web quantises alpha to 8 bits, so
|
|
442
|
+
// a 3-decimal value silently rounds on the way to the DOM (.135 renders as
|
|
443
|
+
// .13) — the token would say one thing and paint another.
|
|
444
|
+
//
|
|
445
|
+
// DARK ONLY. The light family above composites toward BLACK on light planes,
|
|
446
|
+
// which this run says nothing about — do not mirror these numbers into it
|
|
447
|
+
// without its own verification.
|
|
448
|
+
"hairline-subtle": "rgba(255, 255, 255, 0.10)",
|
|
449
|
+
"hairline-default": "rgba(255, 255, 255, 0.15)",
|
|
450
|
+
"hairline-strong": "rgba(255, 255, 255, 0.22)",
|
|
441
451
|
// Interactive states
|
|
442
452
|
"interactive-hover": "rgba(255, 255, 255, 0.04)",
|
|
443
453
|
"interactive-focus": "rgba(255, 255, 255, 0.12)",
|
|
@@ -446,10 +456,9 @@ var semanticColorsDark = {
|
|
|
446
456
|
"interactive-disabled": "rgba(255, 255, 255, 0.12)",
|
|
447
457
|
"interactive-disabled-text": "rgba(255, 255, 255, 0.26)",
|
|
448
458
|
// Divider
|
|
449
|
-
"divider":
|
|
450
|
-
// divider color
|
|
459
|
+
"divider": "rgba(255, 255, 255, 0.09)",
|
|
451
460
|
// Avatar default
|
|
452
|
-
"avatar-background":
|
|
461
|
+
"avatar-background": greyRamp[700],
|
|
453
462
|
"avatar-text": primitiveColors.white
|
|
454
463
|
};
|
|
455
464
|
function getSemanticColors(mode) {
|
|
@@ -863,7 +872,7 @@ function ViewToggle({ view, onViewChange }) {
|
|
|
863
872
|
borderRadius: 9999,
|
|
864
873
|
backgroundColor: active ? "rgba(255,121,0,0.16)" : "transparent",
|
|
865
874
|
borderWidth: 1,
|
|
866
|
-
borderColor: active ? BRAND_PRIMARY : resolveColor("
|
|
875
|
+
borderColor: active ? BRAND_PRIMARY : resolveColor("hairline-strong")
|
|
867
876
|
},
|
|
868
877
|
testID: `body-map-toggle-${side}`,
|
|
869
878
|
children: /* @__PURE__ */ jsx(
|
|
@@ -905,7 +914,7 @@ function MuscleButton({ entry, highlighted, onMusclePress }) {
|
|
|
905
914
|
paddingVertical: 3,
|
|
906
915
|
borderRadius: 9999,
|
|
907
916
|
borderWidth: 1,
|
|
908
|
-
borderColor: highlighted ? BRAND_PRIMARY : resolveColor("
|
|
917
|
+
borderColor: highlighted ? BRAND_PRIMARY : resolveColor("hairline-default")
|
|
909
918
|
},
|
|
910
919
|
testID: `body-map-muscle-${entry.key}`,
|
|
911
920
|
children: [
|
|
@@ -1017,7 +1026,7 @@ function Indicator({
|
|
|
1017
1026
|
// src/components/ui/badge/Badge.tsx
|
|
1018
1027
|
var variantColorStyles = {
|
|
1019
1028
|
solid: {
|
|
1020
|
-
default: "bg-
|
|
1029
|
+
default: "bg-hairline-strong text-text-inverse",
|
|
1021
1030
|
primary: "bg-brand-primary text-text-inverse",
|
|
1022
1031
|
secondary: "bg-brand-secondary text-text-inverse",
|
|
1023
1032
|
success: "bg-status-success text-text-inverse",
|
|
@@ -1035,7 +1044,7 @@ var variantColorStyles = {
|
|
|
1035
1044
|
info: "bg-status-info-subtle text-status-info"
|
|
1036
1045
|
},
|
|
1037
1046
|
outline: {
|
|
1038
|
-
default: "border border-
|
|
1047
|
+
default: "border border-hairline-strong text-text-secondary",
|
|
1039
1048
|
primary: "border border-brand-primary text-brand-primary",
|
|
1040
1049
|
secondary: "border border-brand-secondary text-brand-secondary",
|
|
1041
1050
|
success: "border border-status-success text-status-success",
|
|
@@ -1359,7 +1368,7 @@ function BodyMapDetailPanel({
|
|
|
1359
1368
|
children: /* @__PURE__ */ jsx(
|
|
1360
1369
|
reactNative.View,
|
|
1361
1370
|
{
|
|
1362
|
-
className: "bg-
|
|
1371
|
+
className: "bg-hairline-strong",
|
|
1363
1372
|
style: { width: 40, height: 4, borderRadius: 2 },
|
|
1364
1373
|
accessibilityElementsHidden: true
|
|
1365
1374
|
}
|
|
@@ -1542,7 +1551,7 @@ function BodyMapDetailPanel({
|
|
|
1542
1551
|
contributingExercises.map((exercise, index) => /* @__PURE__ */ jsxs(
|
|
1543
1552
|
reactNative.View,
|
|
1544
1553
|
{
|
|
1545
|
-
className: "flex-row items-center justify-between bg-surface-raised border-
|
|
1554
|
+
className: "flex-row items-center justify-between bg-surface-raised border-hairline",
|
|
1546
1555
|
style: {
|
|
1547
1556
|
gap: 10,
|
|
1548
1557
|
paddingVertical: 8,
|
|
@@ -1649,6 +1658,8 @@ function BodyMapDetailPanel({
|
|
|
1649
1658
|
}
|
|
1650
1659
|
);
|
|
1651
1660
|
}
|
|
1661
|
+
|
|
1662
|
+
// src/theme/color-utils.ts
|
|
1652
1663
|
function hexToRgb(hex) {
|
|
1653
1664
|
const cleaned = hex.replace("#", "");
|
|
1654
1665
|
let r, g, b;
|
|
@@ -1738,194 +1749,6 @@ function lighten(hex, amount = 0.1) {
|
|
|
1738
1749
|
const newRgb = hsvToRgb(hsv.h, hsv.s, newV);
|
|
1739
1750
|
return rgbToHex(newRgb.r, newRgb.g, newRgb.b);
|
|
1740
1751
|
}
|
|
1741
|
-
var shadowColors = {
|
|
1742
|
-
// For charcoal surfaces (~#2C2C2C to #3C3C3C)
|
|
1743
|
-
charcoal: {
|
|
1744
|
-
dark: "rgba(0, 0, 0, 0.5)",
|
|
1745
|
-
light: "rgba(255, 255, 255, 0.12)",
|
|
1746
|
-
// brighter for crisp rim light
|
|
1747
|
-
darker: "rgba(0, 0, 0, 0.6)"
|
|
1748
|
-
},
|
|
1749
|
-
// For neutral dark surfaces (~#1F2937)
|
|
1750
|
-
neutralDark: {
|
|
1751
|
-
dark: "rgba(0, 0, 0, 0.4)",
|
|
1752
|
-
light: "rgba(255, 255, 255, 0.08)",
|
|
1753
|
-
darker: "rgba(0, 0, 0, 0.5)"
|
|
1754
|
-
},
|
|
1755
|
-
// For light surfaces (white/light gray backgrounds)
|
|
1756
|
-
neutralLight: {
|
|
1757
|
-
dark: "rgba(0, 0, 0, 0.15)",
|
|
1758
|
-
// Visible dark shadow for depth on light backgrounds
|
|
1759
|
-
light: "rgba(255, 255, 255, 1)",
|
|
1760
|
-
// Bright highlight for raised effect (visible on light gray)
|
|
1761
|
-
darker: "rgba(0, 0, 0, 0.2)"
|
|
1762
|
-
// Deeper shadow for pressed states
|
|
1763
|
-
}
|
|
1764
|
-
};
|
|
1765
|
-
var intensityConfig = {
|
|
1766
|
-
subtle: { offset: 1, blur: 2 },
|
|
1767
|
-
// very light, barely visible
|
|
1768
|
-
medium: { offset: 2, blur: 4 },
|
|
1769
|
-
// noticeable but restrained
|
|
1770
|
-
strong: { offset: 2, blur: 5 }
|
|
1771
|
-
// slightly deeper blur, same offset as medium
|
|
1772
|
-
};
|
|
1773
|
-
function createRaisedShadow(surface = "charcoal", intensity = "medium") {
|
|
1774
|
-
const colors = shadowColors[surface];
|
|
1775
|
-
const { offset, blur } = intensityConfig[intensity];
|
|
1776
|
-
const rimBlur = 1;
|
|
1777
|
-
return reactNative.Platform.select({
|
|
1778
|
-
web: {
|
|
1779
|
-
boxShadow: `${offset}px ${offset}px ${blur}px ${colors.dark}, -${offset}px -${offset}px ${rimBlur}px ${colors.light}`
|
|
1780
|
-
},
|
|
1781
|
-
default: {
|
|
1782
|
-
// React Native shadow approximation (limited compared to web)
|
|
1783
|
-
shadowColor: "#000",
|
|
1784
|
-
shadowOffset: { width: offset, height: offset },
|
|
1785
|
-
shadowOpacity: 0.3,
|
|
1786
|
-
shadowRadius: blur / 2,
|
|
1787
|
-
elevation: offset
|
|
1788
|
-
}
|
|
1789
|
-
});
|
|
1790
|
-
}
|
|
1791
|
-
function createPressedShadow(surface = "charcoal", intensity = "medium") {
|
|
1792
|
-
const colors = shadowColors[surface];
|
|
1793
|
-
const { offset, blur } = intensityConfig[intensity];
|
|
1794
|
-
const rimOffset = 1;
|
|
1795
|
-
const rimBlur = 1;
|
|
1796
|
-
return reactNative.Platform.select({
|
|
1797
|
-
web: {
|
|
1798
|
-
boxShadow: `inset ${offset}px ${offset}px ${blur}px ${colors.darker}, inset -${rimOffset}px -${rimOffset}px ${rimBlur}px ${colors.light}`
|
|
1799
|
-
},
|
|
1800
|
-
default: {
|
|
1801
|
-
// React Native doesn't support inset shadows, approximate with darker bg
|
|
1802
|
-
shadowOpacity: 0,
|
|
1803
|
-
elevation: 0
|
|
1804
|
-
}
|
|
1805
|
-
});
|
|
1806
|
-
}
|
|
1807
|
-
function createFlatShadow() {
|
|
1808
|
-
return reactNative.Platform.select({
|
|
1809
|
-
web: {
|
|
1810
|
-
boxShadow: "none"
|
|
1811
|
-
},
|
|
1812
|
-
default: {
|
|
1813
|
-
shadowOpacity: 0,
|
|
1814
|
-
elevation: 0
|
|
1815
|
-
}
|
|
1816
|
-
});
|
|
1817
|
-
}
|
|
1818
|
-
function createRaisedHoverShadow(surface = "charcoal", intensity = "medium") {
|
|
1819
|
-
const colors = shadowColors[surface];
|
|
1820
|
-
const { offset, blur } = intensityConfig[intensity];
|
|
1821
|
-
const hoverOffset = Math.max(1, Math.round(offset / 2));
|
|
1822
|
-
const hoverBlur = Math.max(1, Math.round(blur / 2));
|
|
1823
|
-
const rimBlur = 1;
|
|
1824
|
-
return reactNative.Platform.select({
|
|
1825
|
-
web: {
|
|
1826
|
-
// Keep same offsets as normal state for rim to prevent "shrinking" effect
|
|
1827
|
-
boxShadow: `${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${colors.dark}, -${offset}px -${offset}px ${rimBlur}px ${colors.light}`
|
|
1828
|
-
},
|
|
1829
|
-
default: {
|
|
1830
|
-
shadowColor: "#000",
|
|
1831
|
-
shadowOffset: { width: hoverOffset, height: hoverOffset },
|
|
1832
|
-
shadowOpacity: 0.2,
|
|
1833
|
-
shadowRadius: hoverBlur / 2,
|
|
1834
|
-
elevation: hoverOffset
|
|
1835
|
-
}
|
|
1836
|
-
});
|
|
1837
|
-
}
|
|
1838
|
-
function createPressedHoverShadow(surface = "charcoal", intensity = "medium") {
|
|
1839
|
-
const colors = shadowColors[surface];
|
|
1840
|
-
const { offset, blur } = intensityConfig[intensity];
|
|
1841
|
-
const hoverOffset = Math.max(1, Math.round(offset / 2));
|
|
1842
|
-
const hoverBlur = Math.max(1, Math.round(blur / 2));
|
|
1843
|
-
const rimBlur = 1;
|
|
1844
|
-
return reactNative.Platform.select({
|
|
1845
|
-
web: {
|
|
1846
|
-
// Keep rim offset at 1px (same as pressed normal) to prevent "shrinking" effect
|
|
1847
|
-
boxShadow: `inset ${hoverOffset}px ${hoverOffset}px ${hoverBlur}px ${colors.darker}, inset -1px -1px ${rimBlur}px ${colors.light}`
|
|
1848
|
-
},
|
|
1849
|
-
default: {
|
|
1850
|
-
shadowOpacity: 0,
|
|
1851
|
-
elevation: 0
|
|
1852
|
-
}
|
|
1853
|
-
});
|
|
1854
|
-
}
|
|
1855
|
-
({
|
|
1856
|
-
// Charcoal surface shadows (for dark toolbars, cards)
|
|
1857
|
-
charcoal: {
|
|
1858
|
-
raised: {
|
|
1859
|
-
subtle: createRaisedShadow("charcoal", "subtle"),
|
|
1860
|
-
medium: createRaisedShadow("charcoal", "medium"),
|
|
1861
|
-
strong: createRaisedShadow("charcoal", "strong")
|
|
1862
|
-
},
|
|
1863
|
-
raisedHover: {
|
|
1864
|
-
subtle: createRaisedHoverShadow("charcoal", "subtle"),
|
|
1865
|
-
medium: createRaisedHoverShadow("charcoal", "medium"),
|
|
1866
|
-
strong: createRaisedHoverShadow("charcoal", "strong")
|
|
1867
|
-
},
|
|
1868
|
-
pressed: {
|
|
1869
|
-
subtle: createPressedShadow("charcoal", "subtle"),
|
|
1870
|
-
medium: createPressedShadow("charcoal", "medium"),
|
|
1871
|
-
strong: createPressedShadow("charcoal", "strong")
|
|
1872
|
-
},
|
|
1873
|
-
pressedHover: {
|
|
1874
|
-
subtle: createPressedHoverShadow("charcoal", "subtle"),
|
|
1875
|
-
medium: createPressedHoverShadow("charcoal", "medium"),
|
|
1876
|
-
strong: createPressedHoverShadow("charcoal", "strong")
|
|
1877
|
-
},
|
|
1878
|
-
flat: createFlatShadow()
|
|
1879
|
-
},
|
|
1880
|
-
// Neutral dark surface shadows
|
|
1881
|
-
neutralDark: {
|
|
1882
|
-
raised: {
|
|
1883
|
-
subtle: createRaisedShadow("neutralDark", "subtle"),
|
|
1884
|
-
medium: createRaisedShadow("neutralDark", "medium"),
|
|
1885
|
-
strong: createRaisedShadow("neutralDark", "strong")
|
|
1886
|
-
},
|
|
1887
|
-
raisedHover: {
|
|
1888
|
-
subtle: createRaisedHoverShadow("neutralDark", "subtle"),
|
|
1889
|
-
medium: createRaisedHoverShadow("neutralDark", "medium"),
|
|
1890
|
-
strong: createRaisedHoverShadow("neutralDark", "strong")
|
|
1891
|
-
},
|
|
1892
|
-
pressed: {
|
|
1893
|
-
subtle: createPressedShadow("neutralDark", "subtle"),
|
|
1894
|
-
medium: createPressedShadow("neutralDark", "medium"),
|
|
1895
|
-
strong: createPressedShadow("neutralDark", "strong")
|
|
1896
|
-
},
|
|
1897
|
-
pressedHover: {
|
|
1898
|
-
subtle: createPressedHoverShadow("neutralDark", "subtle"),
|
|
1899
|
-
medium: createPressedHoverShadow("neutralDark", "medium"),
|
|
1900
|
-
strong: createPressedHoverShadow("neutralDark", "strong")
|
|
1901
|
-
},
|
|
1902
|
-
flat: createFlatShadow()
|
|
1903
|
-
},
|
|
1904
|
-
// Neutral light surface shadows
|
|
1905
|
-
neutralLight: {
|
|
1906
|
-
raised: {
|
|
1907
|
-
subtle: createRaisedShadow("neutralLight", "subtle"),
|
|
1908
|
-
medium: createRaisedShadow("neutralLight", "medium"),
|
|
1909
|
-
strong: createRaisedShadow("neutralLight", "strong")
|
|
1910
|
-
},
|
|
1911
|
-
raisedHover: {
|
|
1912
|
-
subtle: createRaisedHoverShadow("neutralLight", "subtle"),
|
|
1913
|
-
medium: createRaisedHoverShadow("neutralLight", "medium"),
|
|
1914
|
-
strong: createRaisedHoverShadow("neutralLight", "strong")
|
|
1915
|
-
},
|
|
1916
|
-
pressed: {
|
|
1917
|
-
subtle: createPressedShadow("neutralLight", "subtle"),
|
|
1918
|
-
medium: createPressedShadow("neutralLight", "medium"),
|
|
1919
|
-
strong: createPressedShadow("neutralLight", "strong")
|
|
1920
|
-
},
|
|
1921
|
-
pressedHover: {
|
|
1922
|
-
subtle: createPressedHoverShadow("neutralLight", "subtle"),
|
|
1923
|
-
medium: createPressedHoverShadow("neutralLight", "medium"),
|
|
1924
|
-
strong: createPressedHoverShadow("neutralLight", "strong")
|
|
1925
|
-
},
|
|
1926
|
-
flat: createFlatShadow()
|
|
1927
|
-
}
|
|
1928
|
-
});
|
|
1929
1752
|
var elevationSystem = {
|
|
1930
1753
|
// Deep inset (recessed input fields, deeply pressed buttons)
|
|
1931
1754
|
[-2]: {
|
|
@@ -1954,7 +1777,13 @@ var elevationSystem = {
|
|
|
1954
1777
|
// Level 1: Subtle elevation (outline cards, subtle containers)
|
|
1955
1778
|
[1]: {
|
|
1956
1779
|
name: "subtle",
|
|
1957
|
-
|
|
1780
|
+
// The whole ladder was re-spaced in TD-07.16. It used to run
|
|
1781
|
+
// 0.01/0.02/0.04/0.06/0.08, where the first step was ~2 RGB values — under
|
|
1782
|
+
// the perceptual floor, so level 1 existed in the type system and nowhere on
|
|
1783
|
+
// screen. With drop-shadow now gated off below FLOATING_ELEVATION_MIN, TONE
|
|
1784
|
+
// is the only thing separating 0-3, so every step has to actually land.
|
|
1785
|
+
// Even 0.025 spacing, verified in elevation.test.ts as ΔL* > 1 per step.
|
|
1786
|
+
colorAdjustment: 0.025,
|
|
1958
1787
|
shadowIntensity: "subtle",
|
|
1959
1788
|
shadowStyle: "raised",
|
|
1960
1789
|
description: "Subtle elevation (outline cards, subtle containers)"
|
|
@@ -1962,7 +1791,7 @@ var elevationSystem = {
|
|
|
1962
1791
|
// Level 2: Standard elevation (default cards, buttons)
|
|
1963
1792
|
[2]: {
|
|
1964
1793
|
name: "standard",
|
|
1965
|
-
colorAdjustment: 0.
|
|
1794
|
+
colorAdjustment: 0.05,
|
|
1966
1795
|
shadowIntensity: "medium",
|
|
1967
1796
|
shadowStyle: "raised",
|
|
1968
1797
|
description: "Standard elevation (default cards, raised buttons)"
|
|
@@ -1970,7 +1799,7 @@ var elevationSystem = {
|
|
|
1970
1799
|
// Level 3: Prominent elevation (important cards, modals)
|
|
1971
1800
|
[3]: {
|
|
1972
1801
|
name: "prominent",
|
|
1973
|
-
colorAdjustment: 0.
|
|
1802
|
+
colorAdjustment: 0.075,
|
|
1974
1803
|
shadowIntensity: "strong",
|
|
1975
1804
|
shadowStyle: "raised",
|
|
1976
1805
|
description: "Prominent elevation (important cards, modals, dropdowns)"
|
|
@@ -1978,7 +1807,7 @@ var elevationSystem = {
|
|
|
1978
1807
|
// Level 4: High elevation (overlays, popovers)
|
|
1979
1808
|
[4]: {
|
|
1980
1809
|
name: "high",
|
|
1981
|
-
colorAdjustment: 0.
|
|
1810
|
+
colorAdjustment: 0.1,
|
|
1982
1811
|
shadowIntensity: "strong",
|
|
1983
1812
|
shadowStyle: "raised",
|
|
1984
1813
|
description: "High elevation (overlays, popovers, tooltips)"
|
|
@@ -1986,7 +1815,7 @@ var elevationSystem = {
|
|
|
1986
1815
|
// Level 5: Floating (toasts, floating action buttons)
|
|
1987
1816
|
[5]: {
|
|
1988
1817
|
name: "floating",
|
|
1989
|
-
colorAdjustment: 0.
|
|
1818
|
+
colorAdjustment: 0.13,
|
|
1990
1819
|
shadowIntensity: "strong",
|
|
1991
1820
|
shadowStyle: "raised",
|
|
1992
1821
|
description: "Floating elevation (toasts, floating action buttons, highest z-index)"
|
|
@@ -2102,12 +1931,12 @@ function calculateElevationShadow(baseColor, level, theme, isHovered = false) {
|
|
|
2102
1931
|
const elevatedSurfaceColor = calculateElevationSurface(baseColor, level);
|
|
2103
1932
|
const rimLightColor = calculateRimLightColor(baseColor, level);
|
|
2104
1933
|
const darkShadowColors = calculateDarkShadowColors(elevatedSurfaceColor);
|
|
2105
|
-
const
|
|
1934
|
+
const intensityConfig = {
|
|
2106
1935
|
subtle: { offset: 1, blur: 2 },
|
|
2107
1936
|
medium: { offset: 2, blur: 4 },
|
|
2108
1937
|
strong: { offset: 2, blur: 5 }
|
|
2109
1938
|
};
|
|
2110
|
-
const { offset, blur } =
|
|
1939
|
+
const { offset, blur } = intensityConfig[config.shadowIntensity];
|
|
2111
1940
|
const rimConfig = getRimLightConfig();
|
|
2112
1941
|
if (config.shadowStyle === "pressed") {
|
|
2113
1942
|
if (isHovered) {
|
|
@@ -2163,12 +1992,13 @@ function calculateElevationShadow(baseColor, level, theme, isHovered = false) {
|
|
|
2163
1992
|
});
|
|
2164
1993
|
}
|
|
2165
1994
|
}
|
|
1995
|
+
var FLOATING_ELEVATION_MIN = 4;
|
|
2166
1996
|
function getElevationShadow(baseColor, level, theme, isHovered = false) {
|
|
2167
1997
|
const cacheKey = getShadowCacheKey(baseColor, level, theme, isHovered);
|
|
2168
1998
|
if (elevationShadowCache.has(cacheKey)) {
|
|
2169
1999
|
return elevationShadowCache.get(cacheKey);
|
|
2170
2000
|
}
|
|
2171
|
-
const result = calculateElevationShadow(baseColor, level, theme, isHovered);
|
|
2001
|
+
const result = level > 0 && level < FLOATING_ELEVATION_MIN ? {} : calculateElevationShadow(baseColor, level, theme, isHovered);
|
|
2172
2002
|
if (elevationShadowCache.size >= MAX_SHADOW_CACHE_SIZE) {
|
|
2173
2003
|
const firstKey = elevationShadowCache.keys().next().value;
|
|
2174
2004
|
elevationShadowCache.delete(firstKey);
|
|
@@ -2254,12 +2084,12 @@ function useTheme() {
|
|
|
2254
2084
|
var variantStyles = {
|
|
2255
2085
|
elevated: "",
|
|
2256
2086
|
// Will be set dynamically via elevation system
|
|
2257
|
-
outline: "border-2 border-
|
|
2087
|
+
outline: "border-2 border-hairline-strong",
|
|
2258
2088
|
// Thicker border with stronger contrast
|
|
2259
2089
|
filled: "",
|
|
2260
2090
|
// Will be set dynamically via elevation system
|
|
2261
|
-
accent: "border border-
|
|
2262
|
-
subtle: "border border-
|
|
2091
|
+
accent: "border border-hairline",
|
|
2092
|
+
subtle: "border border-hairline-subtle"
|
|
2263
2093
|
};
|
|
2264
2094
|
function Card({
|
|
2265
2095
|
variant = "elevated",
|
|
@@ -2379,7 +2209,7 @@ var solidVariantColors = {
|
|
|
2379
2209
|
success: t2["status-success"],
|
|
2380
2210
|
warning: t2["status-warning"],
|
|
2381
2211
|
error: t2["status-error"],
|
|
2382
|
-
neutral:
|
|
2212
|
+
neutral: greyRamp[500]
|
|
2383
2213
|
};
|
|
2384
2214
|
var ringVariantStyles = {
|
|
2385
2215
|
"on-track": {
|
|
@@ -2417,10 +2247,10 @@ var iconColors = {
|
|
|
2417
2247
|
success: "#0A5C52",
|
|
2418
2248
|
warning: "#6B4000",
|
|
2419
2249
|
error: "#5C1A1A",
|
|
2420
|
-
neutral:
|
|
2250
|
+
neutral: greyRamp[200],
|
|
2421
2251
|
"on-track": t2["status-success"],
|
|
2422
2252
|
deviation: t2["status-warning"],
|
|
2423
|
-
future:
|
|
2253
|
+
future: greyRamp[500]
|
|
2424
2254
|
};
|
|
2425
2255
|
var sizeDimensions = {
|
|
2426
2256
|
sm: { size: 8, showIcon: false },
|
|
@@ -2489,7 +2319,7 @@ function StatusDot({
|
|
|
2489
2319
|
/* @__PURE__ */ jsx(
|
|
2490
2320
|
reactNative.Text,
|
|
2491
2321
|
{
|
|
2492
|
-
style: { fontSize: 12, lineHeight: 16, color:
|
|
2322
|
+
style: { fontSize: 12, lineHeight: 16, color: greyRamp[400] },
|
|
2493
2323
|
accessibilityElementsHidden: true,
|
|
2494
2324
|
children: label
|
|
2495
2325
|
}
|
|
@@ -2904,7 +2734,7 @@ function SummaryCards({ summary }) {
|
|
|
2904
2734
|
return /* @__PURE__ */ jsxs(
|
|
2905
2735
|
reactNative.View,
|
|
2906
2736
|
{
|
|
2907
|
-
className: "bg-surface-elevated border-
|
|
2737
|
+
className: "bg-surface-elevated border-hairline",
|
|
2908
2738
|
style: {
|
|
2909
2739
|
flexGrow: 1,
|
|
2910
2740
|
flexBasis: "46%",
|
|
@@ -3045,7 +2875,7 @@ function TrainingStatusPage({
|
|
|
3045
2875
|
/* @__PURE__ */ jsxs(
|
|
3046
2876
|
reactNative.View,
|
|
3047
2877
|
{
|
|
3048
|
-
className: "bg-surface-elevated border-
|
|
2878
|
+
className: "bg-surface-elevated border-hairline",
|
|
3049
2879
|
style: {
|
|
3050
2880
|
borderWidth: 1,
|
|
3051
2881
|
borderRadius: 12,
|