diff --git a/.changeset/components-x3-flex-defaults.md b/.changeset/components-x3-flex-defaults.md new file mode 100644 index 00000000000..472558822d1 --- /dev/null +++ b/.changeset/components-x3-flex-defaults.md @@ -0,0 +1,7 @@ +--- +'@fluentui-react-native/components': minor +--- + +Read Flex colors through the design package's interactive color envelope and adopt the current x3 default tokens. +Components rendered with the default theme change appearance, including an achromatic brand, translucent neutral +backgrounds, and larger corner radii. Component token contracts reference the per-state color paths. diff --git a/.changeset/default-theme-design-fluent.md b/.changeset/default-theme-design-fluent.md new file mode 100644 index 00000000000..b9342af2b5a --- /dev/null +++ b/.changeset/default-theme-design-fluent.md @@ -0,0 +1,9 @@ +--- +'@fluentui-react-native/default-theme': minor +--- + +Use the design package's Fluent themes instead of building default tokens locally. `defaultFluentTheme` and +`defaultFluentDarkTheme` are now the design package's `fluentLightTheme` and `fluentDarkTheme`, and `createDefaultTheme` +resolves its `fluentTheme`, so each platform uses its own generated Fluent tokens (macOS previously used the Windows +set) and high contrast follows the color scheme. Breaking: `createAliasTokens` is removed; read alias colors from +`theme.colors` instead. diff --git a/.changeset/design-complete-platform-tokens.md b/.changeset/design-complete-platform-tokens.md new file mode 100644 index 00000000000..3aeacd129ac --- /dev/null +++ b/.changeset/design-complete-platform-tokens.md @@ -0,0 +1,11 @@ +--- +'@fluentui-react-native/design': patch +--- + +Generate complete Fluent color, shadow, font, and appearance token sets for Win32, Windows, macOS, iOS, and Android. +Every platform provides light, dark, light elevated, dark elevated, high-contrast light, and high-contrast dark sets. +Elevated sets fall back to their color scheme, high-contrast light falls back to high-contrast dark, and platforms +without high-contrast data use light and dark. Windows high contrast uses the Win32 high-contrast set with Windows +system color brushes. Preserve native values and fill missing tokens with same-platform equivalents, then portable +same-scheme defaults. Use platform global typography when font aliases are absent and enforce required generated token +types. diff --git a/.changeset/design-deprecated-entry-point.md b/.changeset/design-deprecated-entry-point.md new file mode 100644 index 00000000000..32092eacead --- /dev/null +++ b/.changeset/design-deprecated-entry-point.md @@ -0,0 +1,12 @@ +--- +'@fluentui-react-native/design': minor +--- + +Breaking: move every module that loads the Fluent 2 token JSON into a new `@fluentui-react-native/design/deprecated` +entry point, reserved for tests and the existing platform themes. It exports `getAliasTokens`, `getShadowTokens`, +`globalTokens`, `hcAliasTokens`, `mapPipelineToTheme`, `mapFontPipelineToTheme`, and `mapPipelineToShadow`. The +`theming` entry point no longer exports the pipeline mappers, and the `tokens/legacy` and `theming/compat/defaults` +entry points and `getDefaultLegacyTheme` are removed; use the Fluent themes from `@fluentui-react-native/design/themes` +for complete default themes. `themeFromFlexTokens` now fills the values Flex cannot represent from the generated Fluent +theme for the appearance instead of the removed legacy defaults, so the `theming` entry point no longer bundles the +token JSON. diff --git a/.changeset/design-flex-themes.md b/.changeset/design-flex-themes.md new file mode 100644 index 00000000000..7ec17705cce --- /dev/null +++ b/.changeset/design-flex-themes.md @@ -0,0 +1,9 @@ +--- +'@fluentui-react-native/design': minor +--- + +Add `flexTheme` and `flexWarmTheme` to the `@fluentui-react-native/design/themes` entry point. Each is a new +`FlexThemeDescription`, which pairs a complete Flex token description with an optional `ColorTone`, holding the cool or +warm x3 defaults. `FlexThemeReference` now accepts a `FlexThemeDescription` as its `base`: the description replaces the +package defaults, and its tone becomes the reference's default `appearance.colorTone` unless the `appearance` option or +a provider request sets one. The `ThemeState` types now live with the Flex model; their exports are unchanged. diff --git a/.changeset/design-fluent-themes.md b/.changeset/design-fluent-themes.md new file mode 100644 index 00000000000..ce767bf806b --- /dev/null +++ b/.changeset/design-fluent-themes.md @@ -0,0 +1,10 @@ +--- +'@fluentui-react-native/design': minor +--- + +Add the `@fluentui-react-native/design/themes` entry point with `fluentLightTheme`, `fluentDarkTheme`, `fluentHcTheme`, +and `fluentTheme`. The themes are built from the generated Fluent 2 alias colors, shadows, font aliases, and global +tokens rather than hand-authored values, and each legacy palette color points at the alias color that plays its role. +`fluentTheme` is a `ThemeReference` that follows the system appearance, including high contrast, and the `appearance` +prop of `ThemeProvider` or `ThemedRoot` overrides it. `fluentHcTheme` always resolves the high-contrast theme for the +color scheme. Elevated appearances resolve by color scheme for now. diff --git a/.changeset/design-shared-generated-values.md b/.changeset/design-shared-generated-values.md new file mode 100644 index 00000000000..4b016a1bf0c --- /dev/null +++ b/.changeset/design-shared-generated-values.md @@ -0,0 +1,6 @@ +--- +'@fluentui-react-native/design': patch +--- + +Shrink the generated Flex defaults by about 6 KB minified: values that repeat are emitted once, and the entries both +tones share are emitted once in a common object. The default token values are unchanged. diff --git a/.changeset/design-x3-flex-defaults.md b/.changeset/design-x3-flex-defaults.md new file mode 100644 index 00000000000..2dc1835aac2 --- /dev/null +++ b/.changeset/design-x3-flex-defaults.md @@ -0,0 +1,30 @@ +--- +'@fluentui-react-native/design': minor +--- + +Rework Flex tokens around the current x3 defaults. Legacy `ThemeReference` themes, `ThemeProvider`, `useTheme`, and +Flex tokens projected from legacy themes keep their values. + +Breaking changes for Flex consumers and theme authors: + +- Every Flex semantic color is a resolved `InteractiveColor` with `rest`, `hover`, and `pressed`. Read + `tokens.color.x.rest` instead of `tokens.color.x`, and `.hover` or `.pressed` instead of the removed `color.hover` + and `color.pressed` maps. Omitted interactive states derive lazily from rest with no configuration. +- Author a color as a value, a `[light, dark]` tuple, or `flexColor` options with explicit states and a `standard`, + `inverted`, or `fixed` interaction type. Each color override replaces the previous color atomically. Recipes receive + the authored description; `selectColorEntry` reads an entry for an appearance. +- Appearances accept an optional `colorTone` (`cool` or `warm`) that selects the default tokens and interaction + algorithm. +- The default tokens follow x3-design/fluent-design@206e890b for both tones, including an achromatic brand, + translucent neutral backgrounds, and larger corner radii. Tests should read defaults from `defaultFlexTokens` in the + `testing` entry point. +- Shadows are arrays of `{ x, y, blur, color }` layers and may vary by color scheme; author a former `{ ambient, key }` + shadow as `[ambient, key]`, and use `selectShadowEntry` to read an authored entry. Motion tokens and + `spacing.componentBase800` are new. +- The `color-lib` interaction functions no longer take a token; their `variant` option is replaced by `colorTone`, + `direction`, and `compositing`. `isInverseInteractionToken` moves from `color-lib` to the package root, alongside the + new `INTERACTIVE_COLOR_TOKENS` and `isInteractiveColorToken`. + +Root `useThemeState` consumers now bundle the interaction algorithm and generated defaults, about 23 KB raw and 8 KB +gzip in the measured scenarios. Package sources move under `src/flex`, `src/fluent`, `src/types`, and `src/test`; export +keys and conditions are unchanged. diff --git a/.changeset/spotty-cases-build.md b/.changeset/spotty-cases-build.md new file mode 100644 index 00000000000..0e89297f93f --- /dev/null +++ b/.changeset/spotty-cases-build.md @@ -0,0 +1,5 @@ +--- + +--- + +Documentation-only design refactoring proposal; no package release. diff --git a/.changeset/storybook-runtime-flex-chrome.md b/.changeset/storybook-runtime-flex-chrome.md new file mode 100644 index 00000000000..295c154a52a --- /dev/null +++ b/.changeset/storybook-runtime-flex-chrome.md @@ -0,0 +1,6 @@ +--- +'@fluentui-react-native/storybook-desktop-runtime': patch +--- + +Keep the Storybook chrome and story canvas on the Flex theme. The Theme selector now applies Flex or Fluent only to +story content, while scheme, contrast, and tone still apply to the chrome. diff --git a/.changeset/storybook-runtime-flex-colors.md b/.changeset/storybook-runtime-flex-colors.md new file mode 100644 index 00000000000..3025b043f1d --- /dev/null +++ b/.changeset/storybook-runtime-flex-colors.md @@ -0,0 +1,5 @@ +--- +'@fluentui-react-native/storybook-desktop-runtime': patch +--- + +Read Storybook chrome colors through the design package's interactive color envelope. diff --git a/.changeset/storybook-runtime-theme-selector.md b/.changeset/storybook-runtime-theme-selector.md new file mode 100644 index 00000000000..638ad9aec4a --- /dev/null +++ b/.changeset/storybook-runtime-theme-selector.md @@ -0,0 +1,5 @@ +--- +'@fluentui-react-native/storybook-desktop-runtime': patch +--- + +Replace the fixed Storybook theme buttons with Theme (Flex or Fluent), Scheme (light, dark, or system), Contrast, and Tone dropdowns. The toolbar now defaults to Flex light, standard contrast, and cool tone, independent of the host appearance. diff --git a/.changeset/theming-design-deprecated-imports.md b/.changeset/theming-design-deprecated-imports.md new file mode 100644 index 00000000000..0d7013966f5 --- /dev/null +++ b/.changeset/theming-design-deprecated-imports.md @@ -0,0 +1,10 @@ +--- +'@fluentui-react-native/android-theme': patch +'@fluentui-react-native/apple-theme': patch +'@fluentui-react-native/win32-theme': patch +'@fluentui-react-native/theme-tokens': patch +'@fluentui-react-native/theming-utils': patch +--- + +Import the Fluent 2 token loaders and pipeline mappers from `@fluentui-react-native/design/deprecated`. Theme values and +the shims' exports are unchanged. diff --git a/apps/bundle-size/README.md b/apps/bundle-size/README.md index 3a8f69c3418..5ec90ef3a80 100644 --- a/apps/bundle-size/README.md +++ b/apps/bundle-size/README.md @@ -54,5 +54,12 @@ workflow. 3. Run `yarn bundle-size` and inspect the generated esbuild metafile. The metafile can also be loaded into the esbuild bundle analyzer. +A scenario can also guard module boundaries with path substrings. `forbiddenInputPatterns` and +`requiredInputPatterns` match every module esbuild resolves from the entry, including modules +tree shaking later removes. `forbiddenOutputPatterns` and `requiredOutputPatterns` match only +the modules that contribute bytes to the bundle. Use input patterns when a module must not +even be reachable, and output patterns when a shared entry reaches a module that a consumer's +imports must not retain. + Use a supported public package or subpath export when measuring consumer cost. A source-relative module path is useful for diagnostics, but it does not prove the cost of the published API. diff --git a/apps/bundle-size/baseline.json b/apps/bundle-size/baseline.json index 8bdda76f001..7eae7325d21 100644 --- a/apps/bundle-size/baseline.json +++ b/apps/bundle-size/baseline.json @@ -4,37 +4,37 @@ { "platform": "macos", "scenario": "components-button", - "rawBytes": 50630, - "gzipBytes": 13548, - "moduleCount": 64, - "metafileInputCount": 230, + "rawBytes": 73626, + "gzipBytes": 21384, + "moduleCount": 78, + "metafileInputCount": 243, "workspaceModules": { "@fluentui-react-native/components": 16, - "@fluentui-react-native/design": 21, - "@fluentui-react-native/framework-base": 26 + "@fluentui-react-native/design": 34, + "@fluentui-react-native/framework-base": 27 }, "workspaceBytes": { - "@fluentui-react-native/components": 9308, - "@fluentui-react-native/design": 28720, - "@fluentui-react-native/framework-base": 12566 + "@fluentui-react-native/components": 9761, + "@fluentui-react-native/design": 50730, + "@fluentui-react-native/framework-base": 13099 } }, { "platform": "macos", "scenario": "components-catalog", - "rawBytes": 205485, - "gzipBytes": 55777, - "moduleCount": 214, - "metafileInputCount": 230, + "rawBytes": 229314, + "gzipBytes": 63682, + "moduleCount": 227, + "metafileInputCount": 243, "workspaceModules": { "@fluentui-react-native/components": 151, - "@fluentui-react-native/design": 23, + "@fluentui-react-native/design": 36, "@fluentui-react-native/framework-base": 27, "@fluentui-react-native/native-core": 12 }, "workspaceBytes": { - "@fluentui-react-native/components": 150941, - "@fluentui-react-native/design": 29882, + "@fluentui-react-native/components": 152677, + "@fluentui-react-native/design": 51975, "@fluentui-react-native/framework-base": 15305, "@fluentui-react-native/native-core": 9228 } @@ -42,115 +42,209 @@ { "platform": "macos", "scenario": "design-theme-state", - "rawBytes": 30151, - "gzipBytes": 6434, - "moduleCount": 34, - "metafileInputCount": 60, + "rawBytes": 53271, + "gzipBytes": 14189, + "moduleCount": 47, + "metafileInputCount": 73, "workspaceModules": { - "@fluentui-react-native/design": 15, + "@fluentui-react-native/design": 28, "@fluentui-react-native/framework-base": 18 }, "workspaceBytes": { - "@fluentui-react-native/design": 28151, - "@fluentui-react-native/framework-base": 1960 + "@fluentui-react-native/design": 51266, + "@fluentui-react-native/framework-base": 1964 } }, { "platform": "macos", "scenario": "design-themed-root", - "rawBytes": 32116, - "gzipBytes": 7119, - "moduleCount": 38, - "metafileInputCount": 60, + "rawBytes": 55262, + "gzipBytes": 14869, + "moduleCount": 51, + "metafileInputCount": 73, "workspaceModules": { - "@fluentui-react-native/design": 19, + "@fluentui-react-native/design": 32, "@fluentui-react-native/framework-base": 18 }, "workspaceBytes": { - "@fluentui-react-native/design": 30116, - "@fluentui-react-native/framework-base": 1960 + "@fluentui-react-native/design": 53256, + "@fluentui-react-native/framework-base": 1964 } }, { "platform": "macos", "scenario": "design-color-lib", - "rawBytes": 6328, - "gzipBytes": 2794, + "rawBytes": 6266, + "gzipBytes": 2757, "moduleCount": 6, "metafileInputCount": 7, "workspaceModules": { "@fluentui-react-native/design": 5 }, "workspaceBytes": { - "@fluentui-react-native/design": 6289 + "@fluentui-react-native/design": 6227 } }, { "platform": "macos", "scenario": "design-theme-state-legacy-source", - "rawBytes": 31807, - "gzipBytes": 6762, + "rawBytes": 53804, + "gzipBytes": 14217, + "moduleCount": 48, + "metafileInputCount": 76, + "workspaceModules": { + "@fluentui-react-native/design": 29, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 51799, + "@fluentui-react-native/framework-base": 1964 + } + }, + { + "platform": "macos", + "scenario": "design-legacy-theme", + "rawBytes": 39106, + "gzipBytes": 9004, + "moduleCount": 42, + "metafileInputCount": 82, + "workspaceModules": { + "@fluentui-react-native/design": 23, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 37097, + "@fluentui-react-native/framework-base": 1967 + } + }, + { + "platform": "macos", + "scenario": "design-legacy-theme-from-flex", + "rawBytes": 59872, + "gzipBytes": 16095, + "moduleCount": 54, + "metafileInputCount": 82, + "workspaceModules": { + "@fluentui-react-native/design": 35, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 57863, + "@fluentui-react-native/framework-base": 1967 + } + }, + { + "platform": "macos", + "scenario": "design-fluent-light-theme", + "rawBytes": 18739, + "gzipBytes": 4009, + "moduleCount": 7, + "metafileInputCount": 68, + "workspaceModules": { + "@fluentui-react-native/design": 6 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 18703 + } + }, + { + "platform": "macos", + "scenario": "design-fluent-theme", + "rawBytes": 27455, + "gzipBytes": 6743, "moduleCount": 35, - "metafileInputCount": 63, + "metafileInputCount": 68, "workspaceModules": { "@fluentui-react-native/design": 16, "@fluentui-react-native/framework-base": 18 }, "workspaceBytes": { - "@fluentui-react-native/design": 29807, - "@fluentui-react-native/framework-base": 1960 + "@fluentui-react-native/design": 25446, + "@fluentui-react-native/framework-base": 1973 } }, { "platform": "macos", - "scenario": "design-legacy-theme-from-flex", - "rawBytes": 97766, - "gzipBytes": 19873, - "moduleCount": 58, - "metafileInputCount": 84, + "scenario": "design-fluent-hc-theme", + "rawBytes": 27343, + "gzipBytes": 6694, + "moduleCount": 32, + "metafileInputCount": 68, "workspaceModules": { - "@fluentui-react-native/design": 28, - "@fluentui-react-native/framework-base": 21 + "@fluentui-react-native/design": 13, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 25335, + "@fluentui-react-native/framework-base": 1972 + } + }, + { + "platform": "macos", + "scenario": "design-flex-theme", + "rawBytes": 23368, + "gzipBytes": 8032, + "moduleCount": 33, + "metafileInputCount": 68, + "workspaceModules": { + "@fluentui-react-native/design": 16, + "@fluentui-react-native/framework-base": 16 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 22632, + "@fluentui-react-native/framework-base": 700 + } + }, + { + "platform": "macos", + "scenario": "design-flex-warm-theme", + "rawBytes": 23432, + "gzipBytes": 8064, + "moduleCount": 33, + "metafileInputCount": 68, + "workspaceModules": { + "@fluentui-react-native/design": 16, + "@fluentui-react-native/framework-base": 16 }, "workspaceBytes": { - "@fluentui-react-native/design": 58553, - "@fluentui-react-native/framework-base": 2526 + "@fluentui-react-native/design": 22696, + "@fluentui-react-native/framework-base": 700 } }, { "platform": "windows", "scenario": "components-button", - "rawBytes": 50554, - "gzipBytes": 13523, - "moduleCount": 65, - "metafileInputCount": 231, + "rawBytes": 73547, + "gzipBytes": 21342, + "moduleCount": 79, + "metafileInputCount": 244, "workspaceModules": { "@fluentui-react-native/components": 16, - "@fluentui-react-native/design": 22, - "@fluentui-react-native/framework-base": 26 + "@fluentui-react-native/design": 35, + "@fluentui-react-native/framework-base": 27 }, "workspaceBytes": { - "@fluentui-react-native/components": 9308, - "@fluentui-react-native/design": 28644, - "@fluentui-react-native/framework-base": 12566 + "@fluentui-react-native/components": 9761, + "@fluentui-react-native/design": 50651, + "@fluentui-react-native/framework-base": 13099 } }, { "platform": "windows", "scenario": "components-catalog", - "rawBytes": 205409, - "gzipBytes": 55767, - "moduleCount": 215, - "metafileInputCount": 231, + "rawBytes": 229238, + "gzipBytes": 63628, + "moduleCount": 228, + "metafileInputCount": 244, "workspaceModules": { "@fluentui-react-native/components": 151, - "@fluentui-react-native/design": 24, + "@fluentui-react-native/design": 37, "@fluentui-react-native/framework-base": 27, "@fluentui-react-native/native-core": 12 }, "workspaceBytes": { - "@fluentui-react-native/components": 150941, - "@fluentui-react-native/design": 29806, + "@fluentui-react-native/components": 152677, + "@fluentui-react-native/design": 51899, "@fluentui-react-native/framework-base": 15305, "@fluentui-react-native/native-core": 9228 } @@ -158,79 +252,173 @@ { "platform": "windows", "scenario": "design-theme-state", - "rawBytes": 30075, - "gzipBytes": 6404, - "moduleCount": 35, - "metafileInputCount": 61, + "rawBytes": 53195, + "gzipBytes": 14148, + "moduleCount": 48, + "metafileInputCount": 74, "workspaceModules": { - "@fluentui-react-native/design": 16, + "@fluentui-react-native/design": 29, "@fluentui-react-native/framework-base": 18 }, "workspaceBytes": { - "@fluentui-react-native/design": 28075, - "@fluentui-react-native/framework-base": 1960 + "@fluentui-react-native/design": 51190, + "@fluentui-react-native/framework-base": 1964 } }, { "platform": "windows", "scenario": "design-themed-root", - "rawBytes": 32040, - "gzipBytes": 7084, - "moduleCount": 39, - "metafileInputCount": 61, + "rawBytes": 55186, + "gzipBytes": 14822, + "moduleCount": 52, + "metafileInputCount": 74, "workspaceModules": { - "@fluentui-react-native/design": 20, + "@fluentui-react-native/design": 33, "@fluentui-react-native/framework-base": 18 }, "workspaceBytes": { - "@fluentui-react-native/design": 30039, - "@fluentui-react-native/framework-base": 1960 + "@fluentui-react-native/design": 53180, + "@fluentui-react-native/framework-base": 1964 } }, { "platform": "windows", "scenario": "design-color-lib", - "rawBytes": 6328, - "gzipBytes": 2794, + "rawBytes": 6266, + "gzipBytes": 2757, "moduleCount": 6, "metafileInputCount": 7, "workspaceModules": { "@fluentui-react-native/design": 5 }, "workspaceBytes": { - "@fluentui-react-native/design": 6289 + "@fluentui-react-native/design": 6227 } }, { "platform": "windows", "scenario": "design-theme-state-legacy-source", - "rawBytes": 31731, - "gzipBytes": 6728, - "moduleCount": 36, - "metafileInputCount": 64, + "rawBytes": 53728, + "gzipBytes": 14172, + "moduleCount": 49, + "metafileInputCount": 77, + "workspaceModules": { + "@fluentui-react-native/design": 30, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 51723, + "@fluentui-react-native/framework-base": 1964 + } + }, + { + "platform": "windows", + "scenario": "design-legacy-theme", + "rawBytes": 42907, + "gzipBytes": 9653, + "moduleCount": 42, + "metafileInputCount": 83, "workspaceModules": { - "@fluentui-react-native/design": 17, + "@fluentui-react-native/design": 23, "@fluentui-react-native/framework-base": 18 }, "workspaceBytes": { - "@fluentui-react-native/design": 29731, - "@fluentui-react-native/framework-base": 1960 + "@fluentui-react-native/design": 40895, + "@fluentui-react-native/framework-base": 1970 } }, { "platform": "windows", "scenario": "design-legacy-theme-from-flex", - "rawBytes": 97633, - "gzipBytes": 19793, - "moduleCount": 59, - "metafileInputCount": 85, + "rawBytes": 63686, + "gzipBytes": 16781, + "moduleCount": 54, + "metafileInputCount": 83, "workspaceModules": { - "@fluentui-react-native/design": 29, - "@fluentui-react-native/framework-base": 21 + "@fluentui-react-native/design": 35, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 61677, + "@fluentui-react-native/framework-base": 1967 + } + }, + { + "platform": "windows", + "scenario": "design-fluent-light-theme", + "rawBytes": 22592, + "gzipBytes": 4610, + "moduleCount": 7, + "metafileInputCount": 69, + "workspaceModules": { + "@fluentui-react-native/design": 6 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 22556 + } + }, + { + "platform": "windows", + "scenario": "design-fluent-theme", + "rawBytes": 31248, + "gzipBytes": 7323, + "moduleCount": 35, + "metafileInputCount": 69, + "workspaceModules": { + "@fluentui-react-native/design": 16, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 29227, + "@fluentui-react-native/framework-base": 1985 + } + }, + { + "platform": "windows", + "scenario": "design-fluent-hc-theme", + "rawBytes": 31131, + "gzipBytes": 7279, + "moduleCount": 32, + "metafileInputCount": 69, + "workspaceModules": { + "@fluentui-react-native/design": 13, + "@fluentui-react-native/framework-base": 18 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 29110, + "@fluentui-react-native/framework-base": 1985 + } + }, + { + "platform": "windows", + "scenario": "design-flex-theme", + "rawBytes": 23356, + "gzipBytes": 8025, + "moduleCount": 33, + "metafileInputCount": 69, + "workspaceModules": { + "@fluentui-react-native/design": 16, + "@fluentui-react-native/framework-base": 16 + }, + "workspaceBytes": { + "@fluentui-react-native/design": 22620, + "@fluentui-react-native/framework-base": 700 + } + }, + { + "platform": "windows", + "scenario": "design-flex-warm-theme", + "rawBytes": 23420, + "gzipBytes": 8058, + "moduleCount": 33, + "metafileInputCount": 69, + "workspaceModules": { + "@fluentui-react-native/design": 16, + "@fluentui-react-native/framework-base": 16 }, "workspaceBytes": { - "@fluentui-react-native/design": 58420, - "@fluentui-react-native/framework-base": 2526 + "@fluentui-react-native/design": 22684, + "@fluentui-react-native/framework-base": 700 } } ] diff --git a/apps/bundle-size/scenarios.json b/apps/bundle-size/scenarios.json index bd5bb639491..2ad4fd72404 100644 --- a/apps/bundle-size/scenarios.json +++ b/apps/bundle-size/scenarios.json @@ -15,13 +15,21 @@ "name": "design-theme-state", "module": "@fluentui-react-native/design", "exports": ["FlexThemeReference", "ThemeProvider", "useThemeState"], - "forbiddenInputPatterns": ["/theming/compat/", "/tokens/legacy/", "/color-lib/"] + "forbiddenInputPatterns": ["/design/src/fluent/", "/design/src/deprecated/", "/design/src/test/", "/color-lib/compositing."], + "requiredInputPatterns": [ + "/design/src/flex/flexThemeReference.", + "/design/src/flex/useThemeState.", + "/design/src/theming/ThemeProvider." + ], + "requiredOutputPatterns": ["/color-lib/interaction.", "/design/src/flex/colors/interactionPolicy."] }, { "name": "design-themed-root", "module": "@fluentui-react-native/design", "exports": ["ThemedRoot", "useRootSettings", "useThemeState"], - "forbiddenInputPatterns": ["/theming/compat/", "/tokens/legacy/", "/color-lib/"] + "forbiddenInputPatterns": ["/design/src/fluent/", "/design/src/deprecated/", "/design/src/test/", "/color-lib/compositing."], + "requiredInputPatterns": ["/design/src/flex/useThemeState.", "/design/src/theming/ThemedRoot."], + "requiredOutputPatterns": ["/color-lib/interaction.", "/design/src/flex/colors/interactionPolicy."] }, { "name": "design-color-lib", @@ -41,13 +49,128 @@ "exports": ["ThemeReference"] } ], - "forbiddenInputPatterns": ["/theming/compat/", "/tokens/legacy/"] + "forbiddenInputPatterns": ["/design/src/fluent/compat/", "/design/src/deprecated/", "/design/src/test/", "/color-lib/compositing."], + "requiredInputPatterns": ["/design/src/fluent/themeReference."], + "forbiddenOutputPatterns": ["/design/src/flex/flexThemeReference."], + "requiredOutputPatterns": ["/color-lib/interaction.", "/design/src/flex/colors/interactionPolicy."] + }, + { + "name": "design-legacy-theme", + "module": "@fluentui-react-native/design/theming", + "exports": ["ThemeProvider", "ThemeReference", "useTheme"], + "forbiddenInputPatterns": ["/design/src/deprecated/", "/design/src/test/"], + "requiredInputPatterns": ["/design/src/theming/ThemeProvider."], + "forbiddenOutputPatterns": ["/color-lib/", "/design/src/flex/"], + "requiredOutputPatterns": ["/design/src/fluent/themeReference.", "/design/src/fluent/useTheme."] }, { "name": "design-legacy-theme-from-flex", "module": "@fluentui-react-native/design/theming", "exports": ["FlexThemeReference", "ThemeProvider", "useTheme"], - "requiredInputPatterns": ["/theming/compat/themeFromFlexTokens.", "/tokens/legacy/"] + "forbiddenInputPatterns": ["/design/src/deprecated/", "/design/src/test/"], + "requiredInputPatterns": [ + "/design/src/fluent/compat/themeFromFlexTokens.", + "/design/src/themes/fluent/selectFluentTheme.", + "/design/src/fluent/defaults/fluentTokens.generated.", + "/design/src/fluent/useTheme." + ] + }, + { + "name": "design-fluent-light-theme", + "module": "@fluentui-react-native/design/themes", + "exports": ["fluentLightTheme"], + "forbiddenInputPatterns": [ + "/design/src/fluent/compat/", + "/design/src/deprecated/", + "/design/src/fluent/useTheme.", + "/design/src/test/" + ], + "requiredInputPatterns": ["/design/src/themes/fluent/legacyPalette.", "/design/src/fluent/defaults/fluentTokens.generated."], + "forbiddenOutputPatterns": [ + "/design/src/themes/fluent/fluentDarkTheme.", + "/design/src/themes/fluent/fluentTheme.", + "/design/src/themes/fluent/fluentHc", + "/design/src/fluent/themeReference.", + "/design/src/flex/", + "/design/src/themes/flex/", + "/color-lib/" + ], + "requiredOutputPatterns": ["/design/src/themes/fluent/fluentLightTheme.", "/design/src/themes/fluent/legacyPalette."] + }, + { + "name": "design-fluent-theme", + "module": "@fluentui-react-native/design/themes", + "exports": ["fluentTheme"], + "forbiddenInputPatterns": [ + "/design/src/fluent/compat/", + "/design/src/deprecated/", + "/design/src/fluent/useTheme.", + "/design/src/test/" + ], + "forbiddenOutputPatterns": ["/design/src/flex/", "/design/src/themes/flex/", "/color-lib/"], + "requiredOutputPatterns": [ + "/design/src/themes/fluent/fluentTheme.", + "/design/src/themes/fluent/fluentLightTheme.", + "/design/src/themes/fluent/fluentDarkTheme.", + "/design/src/themes/fluent/fluentHcLightTheme.", + "/design/src/themes/fluent/fluentHcDarkTheme.", + "/design/src/fluent/themeReference." + ] + }, + { + "name": "design-fluent-hc-theme", + "module": "@fluentui-react-native/design/themes", + "exports": ["fluentHcTheme"], + "forbiddenInputPatterns": [ + "/design/src/fluent/compat/", + "/design/src/deprecated/", + "/design/src/fluent/useTheme.", + "/design/src/test/" + ], + "forbiddenOutputPatterns": [ + "/design/src/themes/fluent/fluentLightTheme.", + "/design/src/themes/fluent/fluentDarkTheme.", + "/design/src/themes/fluent/fluentTheme.", + "/design/src/flex/", + "/design/src/themes/flex/", + "/color-lib/" + ], + "requiredOutputPatterns": [ + "/design/src/themes/fluent/fluentHcTheme.", + "/design/src/themes/fluent/fluentHcLightTheme.", + "/design/src/themes/fluent/fluentHcDarkTheme.", + "/design/src/fluent/themeReference." + ] + }, + { + "name": "design-flex-theme", + "module": "@fluentui-react-native/design/themes", + "exports": ["flexTheme"], + "forbiddenInputPatterns": [ + "/design/src/fluent/compat/", + "/design/src/deprecated/", + "/design/src/fluent/useTheme.", + "/design/src/test/", + "/color-lib/compositing." + ], + "requiredInputPatterns": ["/design/src/flex/defaults/defaultTokens.generated."], + "forbiddenOutputPatterns": ["/design/src/fluent/", "/design/src/themes/fluent/", "/design/src/themes/flex/flexWarmTheme."], + "requiredOutputPatterns": ["/design/src/themes/flex/flexTheme.", "/design/src/flex/defaults/defaultTokens.generated."] + }, + { + "name": "design-flex-warm-theme", + "module": "@fluentui-react-native/design/themes", + "exports": ["flexWarmTheme"], + "forbiddenInputPatterns": [ + "/design/src/fluent/compat/", + "/design/src/deprecated/", + "/design/src/fluent/useTheme.", + "/design/src/test/", + "/color-lib/compositing." + ], + "requiredInputPatterns": ["/design/src/flex/defaults/defaultTokens.generated."], + "forbiddenOutputPatterns": ["/design/src/fluent/", "/design/src/themes/fluent/", "/design/src/themes/flex/flexTheme."], + "requiredOutputPatterns": ["/design/src/themes/flex/flexWarmTheme.", "/design/src/flex/defaults/defaultTokens.generated."] } ] } diff --git a/apps/bundle-size/scripts/measure.mts b/apps/bundle-size/scripts/measure.mts index 171b7e58e57..d019da1d37c 100644 --- a/apps/bundle-size/scripts/measure.mts +++ b/apps/bundle-size/scripts/measure.mts @@ -97,9 +97,7 @@ function getWorkspacePackage(source: string): string | undefined { return undefined; } -function getWorkspaceContributions(metafile: Metafile) { - const packageModules = new Map(); - const packageBytes = new Map(); +function getContributingInputs(metafile: Metafile): Map { const contributingInputs = new Map(); for (const output of Object.values(metafile.outputs)) { @@ -110,6 +108,13 @@ function getWorkspaceContributions(metafile: Metafile) { } } + return contributingInputs; +} + +function getWorkspaceContributions(contributingInputs: Map) { + const packageModules = new Map(); + const packageBytes = new Map(); + for (const [source, bytes] of contributingInputs) { const packageName = getWorkspacePackage(source); if (packageName) { @@ -127,6 +132,29 @@ function getWorkspaceContributions(metafile: Metafile) { }; } +function assertModulePatterns( + scenario: Scenario, + kind: 'input' | 'output', + paths: string[], + forbidden: string[] = [], + required: string[] = [], +) { + const subject = kind === 'input' ? 'includes' : 'retains'; + for (const pattern of forbidden) { + const match = paths.find((source) => source.includes(pattern)); + if (match) { + throw new Error(`Scenario "${scenario.name}" unexpectedly ${subject} "${match}" (forbidden by "${pattern}")`); + } + } + for (const pattern of required) { + if (!paths.some((source) => source.includes(pattern))) { + throw new Error( + `Scenario "${scenario.name}" does not ${subject.slice(0, -1)} a module matching required ${kind} pattern "${pattern}"`, + ); + } + } +} + async function runBundle(platform: string, scenario: Scenario): Promise { const entryPath = join(entryRoot, `${scenario.name}.js`); const bundlePath = join(outputRoot, platform, `${scenario.name}.bundle`); @@ -143,19 +171,23 @@ async function runBundle(platform: string, scenario: Scenario): Promise source.replaceAll('\\', '/')); - for (const pattern of scenario.forbiddenInputPatterns ?? []) { - const match = inputPaths.find((source) => source.includes(pattern)); - if (match) { - throw new Error(`Scenario "${scenario.name}" unexpectedly includes "${match}" (forbidden by "${pattern}")`); - } - } - for (const pattern of scenario.requiredInputPatterns ?? []) { - if (!inputPaths.some((source) => source.includes(pattern))) { - throw new Error(`Scenario "${scenario.name}" does not include a module matching required pattern "${pattern}"`); - } - } - const contributions = getWorkspaceContributions(metafile); + const normalizePath = (source: string) => source.replaceAll('\\', '/'); + const contributingInputs = getContributingInputs(metafile); + assertModulePatterns( + scenario, + 'input', + Object.keys(metafile.inputs).map(normalizePath), + scenario.forbiddenInputPatterns, + scenario.requiredInputPatterns, + ); + assertModulePatterns( + scenario, + 'output', + [...contributingInputs.keys()].map(normalizePath), + scenario.forbiddenOutputPatterns, + scenario.requiredOutputPatterns, + ); + const contributions = getWorkspaceContributions(contributingInputs); return { platform, diff --git a/apps/bundle-size/scripts/types.mts b/apps/bundle-size/scripts/types.mts index 57f3e3889a9..15fa03a86ff 100644 --- a/apps/bundle-size/scripts/types.mts +++ b/apps/bundle-size/scripts/types.mts @@ -12,6 +12,8 @@ export interface Scenario { imports?: ScenarioImport[]; forbiddenInputPatterns?: string[]; requiredInputPatterns?: string[]; + forbiddenOutputPatterns?: string[]; + requiredOutputPatterns?: string[]; } export interface ScenarioConfig { diff --git a/apps/tester-core/src/TestComponents/ColorTokens/ColorTokenTest.tsx b/apps/tester-core/src/TestComponents/ColorTokens/ColorTokenTest.tsx index 76695950f41..aaef09d9328 100644 --- a/apps/tester-core/src/TestComponents/ColorTokens/ColorTokenTest.tsx +++ b/apps/tester-core/src/TestComponents/ColorTokens/ColorTokenTest.tsx @@ -3,14 +3,12 @@ import type { ViewStyle, ColorValue } from 'react-native'; import { View, StyleSheet, Platform } from 'react-native'; import { Text, ToggleButton } from '@fluentui/react-native'; -import { createAliasTokens } from '@fluentui-react-native/default-theme'; import { COLORTOKENS_TEST_COMPONENT, COLORTOKEN_TESTPAGE } from '@fluentui-react-native/e2e-testing'; import type { SvgIconProps } from '@fluentui-react-native/icon'; -import { globalTokens } from '@fluentui-react-native/design/tokens/legacy'; +import { globalTokens } from '@fluentui-react-native/design/deprecated'; import type { Theme } from '@fluentui-react-native/design/theming'; import { useTheme } from '@fluentui-react-native/design/theming'; import { themedStyleSheet } from '@fluentui-react-native/design/styling/stylesheet'; -import { getCurrentAppearance } from '@fluentui-react-native/design/theming'; import { createOfficeAliasTokens } from '@fluentui-react-native/win32-theme'; import type { SvgProps } from 'react-native-svg'; import Svg, { G, Path } from 'react-native-svg'; @@ -100,9 +98,7 @@ const AliasColorTokensSwatchList: React.FunctionComponent = () => { theme.name === 'Black' || theme.name === 'HighContrast'; - const aliasColorTokens = isOfficeTheme - ? createOfficeAliasTokens(theme.name) - : createAliasTokens(getCurrentAppearance(theme.host.appearance, 'light')); + const aliasColorTokens = isOfficeTheme ? createOfficeAliasTokens(theme.name) : theme.colors; const aggregator = React.useCallback( (colorName: string) => { diff --git a/docs/pages/Theming/Basics.md b/docs/pages/Theming/Basics.md index 00bd645f280..5379fbad526 100644 --- a/docs/pages/Theming/Basics.md +++ b/docs/pages/Theming/Basics.md @@ -46,8 +46,11 @@ export const App = () => ( An omitted `theme` inherits the nearest theme boundary, including an existing `ThemeProvider`. Without a boundary it uses a default `FlexThemeReference`. -That default supplies the existing baseline Flex tokens; use an appearance-aware -theme recipe when colors should vary with the resolved appearance. +That default supplies the x3 Flex tokens for the resolved light or dark color +scheme and `colorTone`; use an appearance-aware theme recipe for high-contrast or +elevated values. Read each Flex color through its `rest`, `hover`, or `pressed` +state, as described in the design package's +[Flex colors reference](../../../packages/agentic/design/references/flex-colors.md). Nested roots can override individual `appearance` fields, `appearanceSource`, or `fallbackAppearance` while retaining the inherited source and other options. An explicit `theme` starts a new theme/appearance configuration, using that diff --git a/docs/pages/Theming/CustomTheme.md b/docs/pages/Theming/CustomTheme.md index 800a85d1e18..b226e436df2 100644 --- a/docs/pages/Theming/CustomTheme.md +++ b/docs/pages/Theming/CustomTheme.md @@ -8,7 +8,7 @@ There are two ways to make a custom theme: you can tack onto an existing one usi ### Extending an existing `ThemeReference` -We have a concept of `ThemeRecipes` which allow for layering of partial theme objects to create the ultimately desired theme. `ThemeRecipes` are functions which take a `Theme` and spit out a [`PartialTheme`](../../../packages/agentic/design/src/theming/types/Theme.types.ts), which is then deep merged into the base theme object. +We have a concept of `ThemeRecipes` which allow for layering of partial theme objects to create the ultimately desired theme. `ThemeRecipes` are functions which take a `Theme` and spit out a [`PartialTheme`](../../../packages/agentic/design/src/fluent/types/Theme.types.ts), which is then deep merged into the base theme object. You can extend one of our default themes by creating a `ThemeReference` using the default theme as the base theme, and then add your customization as a `ThemeRecipe`: @@ -35,7 +35,7 @@ const theme = new ThemeReference(createDefaultTheme(), ### `ThemeReference` from scratch -You can create your own `ThemeReference` and pass it into the `ThemeProvider`. To create a `ThemeReference` you'll need to create a new instance of `ThemeReference`. You can find the type definition [here](../../../packages/agentic/design/src/theming/themeReference.ts). +You can create your own `ThemeReference` and pass it into the `ThemeProvider`. To create a `ThemeReference` you'll need to create a new instance of `ThemeReference`. You can find the type definition [here](../../../packages/agentic/design/src/fluent/themeReference.ts). ## Theme property customization @@ -46,7 +46,7 @@ There's two ways to customize a FURN theme's properties: ### Changing theme tokens directly -Theme tokens can be overridden directly. You can specify different values for theme entries and add to the set of colors. You can see what can be overridden by looking at the [Theme type definition](../../../packages/agentic/design/src/theming/types/Theme.types.ts). +Theme tokens can be overridden directly. You can specify different values for theme entries and add to the set of colors. You can see what can be overridden by looking at the [Theme type definition](../../../packages/agentic/design/src/fluent/types/Theme.types.ts). This approach is useful if you need the customizations to be applied to all components. @@ -161,7 +161,7 @@ interface Theme { } ``` -(Taken from the [`Theme` type definition](../../../packages/agentic/design/src/theming/types/Theme.types.ts).) +(Taken from the [`Theme` type definition](../../../packages/agentic/design/src/fluent/types/Theme.types.ts).) NOTE: If you would prefer to customize one instance of a FURN component instead, use [the customize API](../../../packages/framework/composition/README.md). diff --git a/docs/pages/Theming/Tokens/Basics.md b/docs/pages/Theming/Tokens/Basics.md index c2bdc62b1bf..06fd9f882ba 100644 --- a/docs/pages/Theming/Tokens/Basics.md +++ b/docs/pages/Theming/Tokens/Basics.md @@ -74,7 +74,7 @@ export const defaultNotificationTokens: TokenSettings Notes about alias color tokens: -- Different platforms can have different sets of alias tokens; however, the entire set of alias tokens are all defined in the same interface. See [Color.types.ts](../../../../packages/agentic/design/src/theming/types/Color.types.ts#L861) for this interface and which platforms define which alias tokens. +- Different platforms can have different sets of alias tokens; however, the entire set of alias tokens are all defined in the same interface. See [Color.types.ts](../../../../packages/agentic/design/src/fluent/types/Color.types.ts#L861) for this interface and which platforms define which alias tokens. - As a result, if an alias token is referenced that does not exist for that platform, there won't be any compile-time or run-time errors. Instead, the color shown will default to black. Special case: if accessing a specific color, you can find it in the `globalTokens.color` property. diff --git a/packages/agentic/components/references/styles-and-tokens.md b/packages/agentic/components/references/styles-and-tokens.md index e2384c1dc5c..8d34ff0748d 100644 --- a/packages/agentic/components/references/styles-and-tokens.md +++ b/packages/agentic/components/references/styles-and-tokens.md @@ -19,9 +19,13 @@ Consult `flex-token-map.yaml` before choosing a value. -- Read semantic colors from `useThemeState().tokens.color`. +- Read semantic colors from `useThemeState().tokens.color`. Each color is a resolved envelope: read `.rest` for static + styles and `.hover` or `.pressed` only for those states, because an omitted state is computed on first read. The design + Flex color reference (`@fluentui-react-native/design/references/flex-colors.md`) owns the color contract. - Read grouped categories from `tokens.borderRadius`, `tokens.spacing`, `tokens.strokeWidth`, `tokens.fontFamily`, - `tokens.fontSize`, `tokens.fontWeight`, `tokens.lineHeight`, and `tokens.shadow`. + `tokens.fontSize`, `tokens.fontWeight`, `tokens.lineHeight`, `tokens.shadow`, and `tokens.motion`. Each shadow is an + array of layers; the design token reference (`@fluentui-react-native/design/references/tokens.md`) describes shadow + and motion values. - Prefer Flex tokens for every mapped semantic value. - Import named global tokens only when Flex has no equivalent, such as current Button icon dimensions or a true zero. - Record a genuine token gap in the component spec. Do not replace it with a nearby token or numeric literal. @@ -74,12 +78,12 @@ states in `disabled`, `pressed`, `hovered` order so the first active state has t Use `getThemedStateStyleFactory` for token-derived hierarchy definitions and `getStateStyleFactory` for theme-independent definitions. Use `getThemedColorStyleFactory` for semantic background, border, and foreground colors; -it automatically resolves `tokens.color.hover` and `tokens.color.pressed` for inherited semantic keys. +it automatically reads the resolved `hover` and `pressed` states of inherited semantic keys. An interaction may intentionally switch semantic keys. Button Subtle is transparent at rest but explicitly selects `backgroundNeutralSubtle` inside hovered and pressed branches. Button Outline uses `strokeNeutralLoud`, whose hover and pressed token values provide visible stroke feedback. Do not assume a token named `Transparent` will produce visible -interaction states; verify the resolved token maps. +interaction states; verify the resolved colors' `hover` and `pressed` values. Build the state source from resolved state without hiding precedence in conditionals. Button pushes appearance, selected, disabled, pressed, and hovered values, then lets the declared hierarchy select the winner. diff --git a/packages/agentic/components/src/common/applyFocusRingStyles.ts b/packages/agentic/components/src/common/applyFocusRingStyles.ts index c35b474375c..68748d6840f 100644 --- a/packages/agentic/components/src/common/applyFocusRingStyles.ts +++ b/packages/agentic/components/src/common/applyFocusRingStyles.ts @@ -10,12 +10,12 @@ import type { FocusVisualsState } from './useFocusVisuals'; const getStyles = themedStyleSheetFactory('FocusRing', ({ tokens }) => StyleSheet.create({ outer: { - borderColor: tokens.color.strokeFocusOuter, + borderColor: tokens.color.strokeFocusOuter.rest, borderStyle: 'solid', borderWidth: tokens.strokeWidth.thick, }, inner: { - borderColor: tokens.color.strokeFocusInner, + borderColor: tokens.color.strokeFocusInner.rest, borderStyle: 'solid', borderWidth: tokens.strokeWidth.thin, }, diff --git a/packages/agentic/components/src/common/focusVisualPolicy.test.tsx b/packages/agentic/components/src/common/focusVisualPolicy.test.tsx index 51b9761abc7..e9fec7bd405 100644 --- a/packages/agentic/components/src/common/focusVisualPolicy.test.tsx +++ b/packages/agentic/components/src/common/focusVisualPolicy.test.tsx @@ -67,12 +67,12 @@ describe.each(['windows', 'macos', 'win32'])('component focus visuals on %s', (p expect(component.getByTestId('focus-visual', { includeHiddenElements: true })).toBe(outerRing); expect(component.getByTestId('focus-visual-inner', { includeHiddenElements: true })).toBe(innerRing); expect(StyleSheet.flatten(outerRing.props.style)).toMatchObject({ - borderColor: defaultFlexTokens.color.strokeFocusOuter, + borderColor: defaultFlexTokens.color.strokeFocusOuter.rest, borderWidth: defaultFlexTokens.strokeWidth.thick, }); expect(StyleSheet.flatten(outerRing.props.style).opacity).toBeUndefined(); expect(StyleSheet.flatten(innerRing.props.style)).toMatchObject({ - borderColor: defaultFlexTokens.color.strokeFocusInner, + borderColor: defaultFlexTokens.color.strokeFocusInner.rest, borderWidth: defaultFlexTokens.strokeWidth.thin, }); expect(outerRing.props).toMatchObject({ accessible: false, focusable: false, pointerEvents: 'none' }); diff --git a/packages/agentic/components/src/common/renderWithTheme.test.tsx b/packages/agentic/components/src/common/renderWithTheme.test.tsx index 99d26ccd1fb..5490b14614b 100644 --- a/packages/agentic/components/src/common/renderWithTheme.test.tsx +++ b/packages/agentic/components/src/common/renderWithTheme.test.tsx @@ -58,7 +58,7 @@ describe('themed test scenes', () => { await scene.rerender(); expect(wrapperRoots.every((root) => root === roots[0])).toBe(true); - expect(themes.every((state) => state.tokens.color.foregroundNeutralPrimary === '#123456')).toBe(true); + expect(themes.every((state) => state.tokens.color.foregroundNeutralPrimary.rest === '#123456')).toBe(true); expect(roots.every((root) => root === roots[0])).toBe(true); }); diff --git a/packages/agentic/components/src/common/useFocusVisuals.test.tsx b/packages/agentic/components/src/common/useFocusVisuals.test.tsx index 1fda2c47f34..ba5df593d97 100644 --- a/packages/agentic/components/src/common/useFocusVisuals.test.tsx +++ b/packages/agentic/components/src/common/useFocusVisuals.test.tsx @@ -133,7 +133,7 @@ describe('useFocusVisuals', () => { get tokens() { return getTokens(); }, - appearance: { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base' }, + appearance: { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base', colorTone: 'cool' }, highContrast: false, themeStyles: {}, }; diff --git a/packages/agentic/components/src/components/accordion/accordion.test.tsx b/packages/agentic/components/src/components/accordion/accordion.test.tsx index bf8217a99e1..8c6880ed38b 100644 --- a/packages/agentic/components/src/components/accordion/accordion.test.tsx +++ b/packages/agentic/components/src/components/accordion/accordion.test.tsx @@ -153,21 +153,21 @@ describe('Accordion', () => { const header = getHeader(component); expect(getHeaderStyle(component)).toMatchObject({ - backgroundColor: colors.backgroundNeutralTransparent, + backgroundColor: colors.backgroundNeutralTransparent.rest, }); - expect(getTitleStyle(component).color).toBe(colors.foregroundNeutralPrimary); + expect(getTitleStyle(component).color).toBe(colors.foregroundNeutralPrimary.rest); await fireEvent(header, 'hoverIn', {}); expect(getHeaderStyle(component)).toMatchObject({ - backgroundColor: colors.hover.backgroundNeutralSubtle, + backgroundColor: colors.backgroundNeutralSubtle.hover, }); - expect(getTitleStyle(component).color).toBe(colors.hover.foregroundNeutralPrimary); + expect(getTitleStyle(component).color).toBe(colors.foregroundNeutralPrimary.hover); await fireEvent(header, 'pressIn', {}); expect(getHeaderStyle(component)).toMatchObject({ - backgroundColor: colors.pressed.backgroundNeutralSubtle, + backgroundColor: colors.backgroundNeutralSubtle.pressed, }); - expect(getTitleStyle(component).color).toBe(colors.pressed.foregroundNeutralPrimary); + expect(getTitleStyle(component).color).toBe(colors.foregroundNeutralPrimary.pressed); }); it('places the chevron at the leading or trailing edge according to layout', async () => { diff --git a/packages/agentic/components/src/components/accordion/spec/tokens.yaml b/packages/agentic/components/src/components/accordion/spec/tokens.yaml index f5309e90e45..883c8812a2f 100644 --- a/packages/agentic/components/src/components/accordion/spec/tokens.yaml +++ b/packages/agentic/components/src/components/accordion/spec/tokens.yaml @@ -21,8 +21,8 @@ bindings: paddingVertical: spacing.componentBase100 background: rest: color.backgroundNeutralTransparent - hovered: color.hover.backgroundNeutralSubtle - pressed: color.pressed.backgroundNeutralSubtle + hovered: color.backgroundNeutralSubtle.hover + pressed: color.backgroundNeutralSubtle.pressed title: small: fontFamily: fontFamily.functional diff --git a/packages/agentic/components/src/components/avatar/avatar.styles.ts b/packages/agentic/components/src/components/avatar/avatar.styles.ts index 86881e2e279..8f613f5e147 100644 --- a/packages/agentic/components/src/components/avatar/avatar.styles.ts +++ b/packages/agentic/components/src/components/avatar/avatar.styles.ts @@ -39,7 +39,7 @@ type AvatarSizeState = StateNames; function createRingStyle({ color, strokeWidth }: FlexTokens, offset: 'thin' | 'thick', width: 'thin' | 'thick' | 'thicker'): ViewStyle { const inset = -(strokeWidth[offset] + strokeWidth[width]); return { - borderColor: color.strokeBrandLoud, + borderColor: color.strokeBrandLoud.rest, borderStyle: 'solid', borderWidth: strokeWidth[width], bottom: inset, @@ -54,11 +54,11 @@ function createSizeStyleDefinition(tokens: FlexTokens, size: AvatarSize): StyleD return { alignItems: 'center', - backgroundColor: color.backgroundNeutralSoft, + backgroundColor: color.backgroundNeutralSoft.rest, borderRadius: borderRadius.circular, height: size, image: { - backgroundColor: color.backgroundNeutralTransparent, + backgroundColor: color.backgroundNeutralTransparent.rest, padding: 0, }, minHeight: size, diff --git a/packages/agentic/components/src/components/avatar/avatar.test.tsx b/packages/agentic/components/src/components/avatar/avatar.test.tsx index a39ab80c3cd..9f59d6bc6c9 100644 --- a/packages/agentic/components/src/components/avatar/avatar.test.tsx +++ b/packages/agentic/components/src/components/avatar/avatar.test.tsx @@ -89,7 +89,7 @@ describe('Avatar', () => { expect(component.getByText('LM', { includeHiddenElements: true })).toBeOnTheScreen(); expect(getRootStyle(component)).toMatchObject({ alignItems: 'center', - backgroundColor: tokens.color.backgroundNeutralSoft, + backgroundColor: tokens.color.backgroundNeutralSoft.rest, flexDirection: 'row', height: 40, justifyContent: 'center', @@ -123,7 +123,7 @@ describe('Avatar', () => { top: 0, }); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: tokens.color.backgroundNeutralTransparent, + backgroundColor: tokens.color.backgroundNeutralTransparent.rest, height: 56, padding: 0, width: 56, @@ -144,7 +144,7 @@ describe('Avatar', () => { height: 120, }); expect(StyleSheet.flatten(component.getByTestId('avatar-activity-ring', { includeHiddenElements: true }).props.style)).toMatchObject({ - borderColor: tokens.color.strokeBrandLoud, + borderColor: tokens.color.strokeBrandLoud.rest, borderRadius: tokens.borderRadius.circular, borderStyle: 'solid', borderWidth: tokens.strokeWidth.thicker, @@ -182,7 +182,7 @@ describe('Avatar', () => { pointerEvents: 'none', }); expect(StyleSheet.flatten(ring.props.style)).toMatchObject({ - borderColor: tokens.color.strokeBrandLoud, + borderColor: tokens.color.strokeBrandLoud.rest, borderWidth: width, bottom: -(offset + width), left: -(offset + width), diff --git a/packages/agentic/components/src/components/avatar/useAvatarStyles.ts b/packages/agentic/components/src/components/avatar/useAvatarStyles.ts index 24c91a3d44f..b7e409df821 100644 --- a/packages/agentic/components/src/components/avatar/useAvatarStyles.ts +++ b/packages/agentic/components/src/components/avatar/useAvatarStyles.ts @@ -7,7 +7,7 @@ import { avatarStyles, getAvatarActivityRingStyle, getAvatarIconSize, getAvatarI import type { AvatarState } from './avatar.types'; export function useAvatarStyles_unstable(state: AvatarState) { - const foregroundColor = state.tokens.color.foregroundNeutralPrimary; + const foregroundColor = state.tokens.color.foregroundNeutralPrimary.rest; const imageStyle: StyleProp = [ avatarStyles.image, { diff --git a/packages/agentic/components/src/components/badge/badge.test.tsx b/packages/agentic/components/src/components/badge/badge.test.tsx index 8ffffa0e0e4..ee2cff8046d 100644 --- a/packages/agentic/components/src/components/badge/badge.test.tsx +++ b/packages/agentic/components/src/components/badge/badge.test.tsx @@ -68,13 +68,13 @@ describe('Badge', () => { expect(getRoot(component).props.accessible).toBe(true); expect(getRootStyle(component)).toMatchObject({ alignItems: 'center', - backgroundColor: tokens.color.backgroundBrandSoft, + backgroundColor: tokens.color.backgroundBrandSoft.rest, borderRadius: tokens.borderRadius.circular, minHeight: 20, paddingHorizontal: tokens.spacing.componentBase150, }); expect(StyleSheet.flatten(component.getByText('Badge').props.style)).toMatchObject({ - color: tokens.color.foregroundBrandPrimary, + color: tokens.color.foregroundBrandPrimary.rest, fontFamily: expect.any(String), fontSize: tokens.fontSize.functionalBodySmall, }); @@ -83,7 +83,7 @@ describe('Badge', () => { width: 16, }); expect(StyleSheet.flatten(component.getByText(String.fromCodePoint(badgeIcon.fontSource.codepoint)).props.style)).toMatchObject({ - color: tokens.color.foregroundBrandPrimary, + color: tokens.color.foregroundBrandPrimary.rest, }); }); @@ -160,11 +160,11 @@ describe('Badge', () => { }); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: tokens.color[backgroundToken], - borderColor: tokens.color[borderToken], + backgroundColor: tokens.color[backgroundToken].rest, + borderColor: tokens.color[borderToken].rest, borderWidth, }); - expect(StyleSheet.flatten(component.getByText('Badge').props.style).color).toBe(tokens.color[foregroundToken]); + expect(StyleSheet.flatten(component.getByText('Badge').props.style).color).toBe(tokens.color[foregroundToken].rest); }); it.each([ diff --git a/packages/agentic/components/src/components/button/__snapshots__/button.test.tsx.snap b/packages/agentic/components/src/components/button/__snapshots__/button.test.tsx.snap index 99fa028ba69..483162a1eab 100644 --- a/packages/agentic/components/src/components/button/__snapshots__/button.test.tsx.snap +++ b/packages/agentic/components/src/components/button/__snapshots__/button.test.tsx.snap @@ -6,7 +6,7 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "appearance": "primary", "contentStyles": [ { - "color": "#bdbdbd", + "color": "#0000006d", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -18,9 +18,9 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#f0f0f0", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#0000001a", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -36,7 +36,7 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "appearance": "secondary", "contentStyles": [ { - "color": "#bdbdbd", + "color": "#0000006d", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -48,9 +48,9 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#f0f0f0", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#00000008", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -66,7 +66,7 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "appearance": "outline", "contentStyles": [ { - "color": "#bdbdbd", + "color": "#0000006d", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -78,9 +78,9 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#e0e0e0", - "borderRadius": 4, + "backgroundColor": "#24242400", + "borderColor": "#00000014", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -96,7 +96,7 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "appearance": "subtle", "contentStyles": [ { - "color": "#bdbdbd", + "color": "#0000006d", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -108,9 +108,9 @@ exports[`Button matches the disabled visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#24242400", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -143,9 +143,9 @@ exports[`Button matches the focused visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#185abd", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#242424", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -161,7 +161,7 @@ exports[`Button matches the focused visual state snapshot across appearances 1`] "appearance": "secondary", "contentStyles": [ { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -173,9 +173,9 @@ exports[`Button matches the focused visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#fafafa", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#0000000d", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -191,7 +191,7 @@ exports[`Button matches the focused visual state snapshot across appearances 1`] "appearance": "outline", "contentStyles": [ { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -203,9 +203,9 @@ exports[`Button matches the focused visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#d1d1d1", - "borderRadius": 4, + "backgroundColor": "#24242400", + "borderColor": "#6f6f6f", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -221,7 +221,7 @@ exports[`Button matches the focused visual state snapshot across appearances 1`] "appearance": "subtle", "contentStyles": [ { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -233,9 +233,9 @@ exports[`Button matches the focused visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#24242400", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -268,9 +268,9 @@ exports[`Button matches the hovered visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#1651aa", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#363636", + "borderColor": "#1313130a", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -286,7 +286,7 @@ exports[`Button matches the hovered visual state snapshot across appearances 1`] "appearance": "secondary", "contentStyles": [ { - "color": "#242424", + "color": "#000000e5", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -298,9 +298,9 @@ exports[`Button matches the hovered visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#f0f0f0", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#00000017", + "borderColor": "#1313130a", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -316,7 +316,7 @@ exports[`Button matches the hovered visual state snapshot across appearances 1`] "appearance": "outline", "contentStyles": [ { - "color": "#242424", + "color": "#000000e5", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -328,9 +328,9 @@ exports[`Button matches the hovered visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#c7c7c7", - "borderRadius": 4, + "backgroundColor": "#1313130a", + "borderColor": "#787878", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -346,7 +346,7 @@ exports[`Button matches the hovered visual state snapshot across appearances 1`] "appearance": "subtle", "contentStyles": [ { - "color": "#242424", + "color": "#000000e5", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -358,9 +358,9 @@ exports[`Button matches the hovered visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#f0f0f0", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#00000017", + "borderColor": "#1313130a", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -393,9 +393,9 @@ exports[`Button matches the pressed visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#0e336a", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#494949", + "borderColor": "#05050514", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -411,7 +411,7 @@ exports[`Button matches the pressed visual state snapshot across appearances 1`] "appearance": "secondary", "contentStyles": [ { - "color": "#242424", + "color": "#000000ef", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -423,9 +423,9 @@ exports[`Button matches the pressed visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#dbdbdb", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#00000021", + "borderColor": "#05050514", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -441,7 +441,7 @@ exports[`Button matches the pressed visual state snapshot across appearances 1`] "appearance": "outline", "contentStyles": [ { - "color": "#242424", + "color": "#000000ef", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -453,9 +453,9 @@ exports[`Button matches the pressed visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#b3b3b3", - "borderRadius": 4, + "backgroundColor": "#05050514", + "borderColor": "#818181", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -471,7 +471,7 @@ exports[`Button matches the pressed visual state snapshot across appearances 1`] "appearance": "subtle", "contentStyles": [ { - "color": "#242424", + "color": "#000000ef", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -483,9 +483,9 @@ exports[`Button matches the pressed visual state snapshot across appearances 1`] "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#dbdbdb", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#00000021", + "borderColor": "#05050514", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -518,9 +518,9 @@ exports[`Button matches the rest visual state snapshot across appearances 1`] = "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#185abd", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#242424", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -536,7 +536,7 @@ exports[`Button matches the rest visual state snapshot across appearances 1`] = "appearance": "secondary", "contentStyles": [ { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -548,9 +548,9 @@ exports[`Button matches the rest visual state snapshot across appearances 1`] = "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#fafafa", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#0000000d", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -566,7 +566,7 @@ exports[`Button matches the rest visual state snapshot across appearances 1`] = "appearance": "outline", "contentStyles": [ { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -578,9 +578,9 @@ exports[`Button matches the rest visual state snapshot across appearances 1`] = "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#d1d1d1", - "borderRadius": 4, + "backgroundColor": "#24242400", + "borderColor": "#6f6f6f", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -596,7 +596,7 @@ exports[`Button matches the rest visual state snapshot across appearances 1`] = "appearance": "subtle", "contentStyles": [ { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -608,9 +608,9 @@ exports[`Button matches the rest visual state snapshot across appearances 1`] = "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#00000000", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#24242400", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -653,9 +653,9 @@ exports[`Button matches the selected visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#185abd", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#242424", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -693,9 +693,9 @@ exports[`Button matches the selected visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#616161", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#242424", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -733,9 +733,9 @@ exports[`Button matches the selected visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#616161", - "borderColor": "#616161", - "borderRadius": 4, + "backgroundColor": "#242424", + "borderColor": "#242424", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", @@ -751,7 +751,7 @@ exports[`Button matches the selected visual state snapshot across appearances 1` "appearance": "subtle", "contentStyles": [ { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -761,7 +761,7 @@ exports[`Button matches the selected visual state snapshot across appearances 1` "textAlign": "center", }, { - "color": "#242424", + "color": "#000000db", "flexShrink": 1, "fontFamily": "Helvetica Neue", "fontSize": 14, @@ -773,9 +773,9 @@ exports[`Button matches the selected visual state snapshot across appearances 1` "rootStyle": { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#0000001a", - "borderColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#00000014", + "borderColor": "#24242400", + "borderRadius": 12, "borderStyle": "solid", "borderWidth": 1, "flexDirection": "row", diff --git a/packages/agentic/components/src/components/button/button.test.tsx b/packages/agentic/components/src/components/button/button.test.tsx index 8691fad1773..c55776efd45 100644 --- a/packages/agentic/components/src/components/button/button.test.tsx +++ b/packages/agentic/components/src/components/button/button.test.tsx @@ -54,7 +54,7 @@ describe('Button', () => { expect(component.getByText('Save')).toBeOnTheScreen(); expect(getRootStyle(component)).toMatchObject({ alignItems: 'center', - backgroundColor: '#fafafa', + backgroundColor: defaultFlexTokens.color.backgroundNeutralSubtle.rest, minHeight: 24, minWidth: 24, }); @@ -72,7 +72,7 @@ describe('Button', () => { expect(getRootStyle(component).backgroundColor).not.toBe(restBackground); await fireEvent(root, 'pressIn', {}); - expect(getRootStyle(component).backgroundColor).toBe('#dbdbdb'); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSubtle.pressed); await fireEvent.press(root); expect(onPress).toHaveBeenCalledTimes(1); @@ -127,7 +127,7 @@ describe('Button', () => { expect(root).toBeDisabled(); expect(root.props.focusable).toBe(false); expect(root.props.accessibilityState).toEqual({ disabled: true }); - expect(getRootStyle(component).backgroundColor).toBe('#f0f0f0'); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSubtleDisabled.rest); await fireEvent.press(root); expect(onPress).not.toHaveBeenCalled(); }); @@ -323,13 +323,13 @@ describe('Button', () => { }); it.each([ - ['primary', '#185abd'], - ['secondary', '#fafafa'], - ['outline', '#00000000'], - ['subtle', '#00000000'], - ] as const)('resolves the %s appearance', async (appearance, backgroundColor) => { + ['primary', 'backgroundBrandHeavy'], + ['secondary', 'backgroundNeutralSubtle'], + ['outline', 'backgroundNeutralTransparent'], + ['subtle', 'backgroundNeutralTransparent'], + ] as const)('resolves the %s appearance', async (appearance, backgroundToken) => { const component = await renderButton({ appearance, content: appearance }); - expect(getRootStyle(component).backgroundColor).toBe(backgroundColor); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color[backgroundToken].rest); }); it.each([ @@ -343,20 +343,20 @@ describe('Button', () => { const root = getRoot(component); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors[restBackground], - borderColor: colors[restBorder], + backgroundColor: colors[restBackground].rest, + borderColor: colors[restBorder].rest, }); await fireEvent(root, 'hoverIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.hover[interactionBackground], - borderColor: colors.hover[interactionBorder], + backgroundColor: colors[interactionBackground].hover, + borderColor: colors[interactionBorder].hover, }); await fireEvent(root, 'pressIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.pressed[interactionBackground], - borderColor: colors.pressed[interactionBorder], + backgroundColor: colors[interactionBackground].pressed, + borderColor: colors[interactionBorder].pressed, }); }, ); @@ -415,40 +415,40 @@ describe('Button', () => { StyleSheet.flatten(component.getAllByText(appearance, { includeHiddenElements: true })[1].props.style).color; expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors[background], - borderColor: colors[border], + backgroundColor: colors[background].rest, + borderColor: colors[border].rest, }); - expect(getForegroundColor()).toBe(colors[foreground]); + expect(getForegroundColor()).toBe(colors[foreground].rest); await fireEvent(root, 'hoverIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.hover[background], - borderColor: colors.hover[border], + backgroundColor: colors[background].hover, + borderColor: colors[border].hover, }); - expect(getForegroundColor()).toBe(colors.hover[foreground]); + expect(getForegroundColor()).toBe(colors[foreground].hover); await fireEvent(root, 'pressIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.pressed[background], - borderColor: colors.pressed[border], + backgroundColor: colors[background].pressed, + borderColor: colors[border].pressed, }); - expect(getForegroundColor()).toBe(colors.pressed[foreground]); + expect(getForegroundColor()).toBe(colors[foreground].pressed); const disabledComponent = await renderButton({ appearance, content: appearance, disabled: true, selected: true }); expect(getRootStyle(disabledComponent)).toMatchObject({ - backgroundColor: colors[disabledBackground], - borderColor: colors[disabledBorder], + backgroundColor: colors[disabledBackground].rest, + borderColor: colors[disabledBorder].rest, }); expect(StyleSheet.flatten(disabledComponent.getAllByText(appearance, { includeHiddenElements: true })[1].props.style).color).toBe( - colors.foregroundNeutralDisabled, + colors.foregroundNeutralDisabled.rest, ); }, ); it.each([ - ['small', 12, 8, 4], - ['medium', 14, 10, 4], - ['large', 16, 12, 6], + ['small', 12, 8, defaultFlexTokens.borderRadius.base200], + ['medium', 14, 10, defaultFlexTokens.borderRadius.base300], + ['large', 16, 12, defaultFlexTokens.borderRadius.base400], ] as const)('resolves the %s size', async (size, fontSize, paddingHorizontal, borderRadius) => { const component = await renderButton({ content: size, size }); expect(StyleSheet.flatten(component.getByText(size).props.style)).toMatchObject({ diff --git a/packages/agentic/components/src/components/button/spec/tokens.yaml b/packages/agentic/components/src/components/button/spec/tokens.yaml index d9e8def76f5..dba51d5d657 100644 --- a/packages/agentic/components/src/components/button/spec/tokens.yaml +++ b/packages/agentic/components/src/components/button/spec/tokens.yaml @@ -67,10 +67,11 @@ bindings: selectedSubtle: backgroundColor: color.backgroundNeutralSubtleDisabled interaction: - hovered: color.hover - pressed: color.pressed - subtleHoveredBackground: color.hover.backgroundNeutralSubtle - subtlePressedBackground: color.pressed.backgroundNeutralSubtle + # is the semantic color key the state inherits from its parent style. + hovered: color..hover + pressed: color..pressed + subtleHoveredBackground: color.backgroundNeutralSubtle.hover + subtlePressedBackground: color.backgroundNeutralSubtle.pressed size: small: roundedRadius: borderRadius.base200 diff --git a/packages/agentic/components/src/components/card/card.styles.ts b/packages/agentic/components/src/components/card/card.styles.ts index 6506bf79c4f..f48b1846952 100644 --- a/packages/agentic/components/src/components/card/card.styles.ts +++ b/packages/agentic/components/src/components/card/card.styles.ts @@ -161,7 +161,7 @@ type NestedBlockStyleStateLevels = typeof nestedBlockStyleStateLevels; type NestedBlockStyleState = StateNames; function createNestedBlockStyleDefinition({ borderRadius, color }: FlexTokens): StyleDefinition { - const nestedBackground: ViewStyle = { backgroundColor: color.backgroundNeutralTranslucent }; + const nestedBackground: ViewStyle = { backgroundColor: color.backgroundNeutralTranslucent.rest }; return { small: { default: { diff --git a/packages/agentic/components/src/components/card/card.test.tsx b/packages/agentic/components/src/components/card/card.test.tsx index 712c661cf46..988cca77c6e 100644 --- a/packages/agentic/components/src/components/card/card.test.tsx +++ b/packages/agentic/components/src/components/card/card.test.tsx @@ -130,8 +130,8 @@ describe('Card', () => { const colors = defaultFlexTokens.color; expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.surfaceNeutralTranslucent, - borderColor: colors.strokeNeutralSubtle, + backgroundColor: colors.surfaceNeutralTranslucent.rest, + borderColor: colors.strokeNeutralSubtle.rest, }); expect(component.getByText('Summary')).toBeOnTheScreen(); }); @@ -164,20 +164,20 @@ describe('Card', () => { expect(button.props.accessibilityState).toEqual({ disabled: false, selected: true }); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.backgroundNeutralSoft, - borderColor: colors.strokeNeutralSoft, + backgroundColor: colors.backgroundNeutralSoft.rest, + borderColor: colors.strokeNeutralSoft.rest, }); await fireEvent(button, 'hoverIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.hover.backgroundNeutralSoft, - borderColor: colors.hover.strokeNeutralSoft, + backgroundColor: colors.backgroundNeutralSoft.hover, + borderColor: colors.strokeNeutralSoft.hover, }); await fireEvent(button, 'pressIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.pressed.backgroundNeutralSoft, - borderColor: colors.pressed.strokeNeutralSoft, + backgroundColor: colors.backgroundNeutralSoft.pressed, + borderColor: colors.strokeNeutralSoft.pressed, }); await fireEvent(button, 'focus', {}); diff --git a/packages/agentic/components/src/components/card/spec/tokens.yaml b/packages/agentic/components/src/components/card/spec/tokens.yaml index 2ddeb7d69bd..d68ee9eb1e6 100644 --- a/packages/agentic/components/src/components/card/spec/tokens.yaml +++ b/packages/agentic/components/src/components/card/spec/tokens.yaml @@ -24,8 +24,9 @@ bindings: disabled: backgroundColor: color.backgroundNeutralDisabled borderColor: color.strokeNeutralDisabled - hovered: color.hover - pressed: color.pressed + # is the semantic color key the state inherits from its parent style. + hovered: color..hover + pressed: color..pressed size: small: borderRadius: borderRadius.base600 diff --git a/packages/agentic/components/src/components/checkbox/checkbox.test.tsx b/packages/agentic/components/src/components/checkbox/checkbox.test.tsx index 66ae89dde3b..4ee42ef188f 100644 --- a/packages/agentic/components/src/components/checkbox/checkbox.test.tsx +++ b/packages/agentic/components/src/components/checkbox/checkbox.test.tsx @@ -39,8 +39,8 @@ describe('Checkbox', () => { expect(component.getByText('Save drafts')).toBeOnTheScreen(); expect(getIndicatorStyle(component)).toMatchObject({ alignItems: 'center', - backgroundColor: colors.backgroundNeutralTransparent, - borderColor: colors.strokeNeutralHeavy, + backgroundColor: colors.backgroundNeutralTransparent.rest, + borderColor: colors.strokeNeutralHeavy.rest, }); expect(getRootStyle(component)).toMatchObject({ borderStyle: 'solid', @@ -251,23 +251,23 @@ describe('Checkbox', () => { const root = getRoot(component); expect(getIndicatorStyle(component)).toMatchObject({ - backgroundColor: colors.backgroundNeutralTransparent, - borderColor: colors.strokeNeutralHeavy, + backgroundColor: colors.backgroundNeutralTransparent.rest, + borderColor: colors.strokeNeutralHeavy.rest, }); await fireEvent(root, 'hoverIn', {}); expect(getIndicatorStyle(component)).toMatchObject({ - backgroundColor: colors.hover.backgroundNeutralTransparent, - borderColor: colors.hover.strokeNeutralHeavy, + backgroundColor: colors.backgroundNeutralTransparent.hover, + borderColor: colors.strokeNeutralHeavy.hover, }); - expect(StyleSheet.flatten(component.getByTestId('checkbox-label').props.style).color).toBe(colors.hover.foregroundNeutralSecondary); + expect(StyleSheet.flatten(component.getByTestId('checkbox-label').props.style).color).toBe(colors.foregroundNeutralSecondary.hover); await fireEvent(root, 'pressIn', {}); expect(getIndicatorStyle(component)).toMatchObject({ - backgroundColor: colors.pressed.backgroundNeutralTransparent, - borderColor: colors.pressed.strokeNeutralHeavy, + backgroundColor: colors.backgroundNeutralTransparent.pressed, + borderColor: colors.strokeNeutralHeavy.pressed, }); - expect(StyleSheet.flatten(component.getByTestId('checkbox-label').props.style).color).toBe(colors.pressed.foregroundNeutralSecondary); + expect(StyleSheet.flatten(component.getByTestId('checkbox-label').props.style).color).toBe(colors.foregroundNeutralSecondary.pressed); }); it('uses native focus visuals without mounting custom rings', async () => { @@ -299,14 +299,14 @@ describe('Checkbox', () => { const component = await renderCheckbox({ label: status, status }); const label = component.getByTestId('checkbox-label'); const indicator = component.getByTestId('checkbox-indicator'); - const expectedBackground = status === 'unchecked' ? colors.backgroundNeutralTransparent : colors.backgroundBrandHeavy; - const expectedLabelColor = status === 'unchecked' ? colors.foregroundNeutralSecondary : colors.foregroundNeutralPrimary; + const expectedBackground = status === 'unchecked' ? colors.backgroundNeutralTransparent.rest : colors.backgroundBrandHeavy.rest; + const expectedLabelColor = status === 'unchecked' ? colors.foregroundNeutralSecondary.rest : colors.foregroundNeutralPrimary.rest; expect(StyleSheet.flatten(indicator.props.style).backgroundColor).toBe(expectedBackground); expect(StyleSheet.flatten(label.props.style).color).toBe(expectedLabelColor); if (status !== 'unchecked') { const icon = component.getByText(status === 'indeterminate' ? '\u2212' : '\u2713'); - expect(StyleSheet.flatten(icon.props.style).color).toBe(colors.foregroundBrandOnloud); + expect(StyleSheet.flatten(icon.props.style).color).toBe(colors.foregroundBrandOnloud.rest); } }); @@ -326,10 +326,10 @@ describe('Checkbox', () => { const tokens = defaultFlexTokens.color; expect(StyleSheet.flatten(component.getByTestId('checkbox-indicator').props.style)).toMatchObject({ - backgroundColor: tokens.backgroundNeutralHeavyDisabled, - borderColor: tokens.strokeNeutralTransparent, + backgroundColor: tokens.backgroundNeutralHeavyDisabled.rest, + borderColor: tokens.strokeNeutralTransparent.rest, }); - expect(StyleSheet.flatten(component.getByTestId('checkbox-label').props.style).color).toBe(tokens.foregroundNeutralDisabled); + expect(StyleSheet.flatten(component.getByTestId('checkbox-label').props.style).color).toBe(tokens.foregroundNeutralDisabled.rest); }); describe('SPEC regression coverage', () => { @@ -480,26 +480,26 @@ describe('Checkbox', () => { async (status) => { const colors = defaultFlexTokens.color; const component = await renderCheckbox({ status, showSecondaryText: true }); - for (const [event, palette] of [ - ['hoverIn', colors.hover], - ['pressIn', colors.pressed], - ['pressOut', colors.hover], - ['hoverOut', colors], + for (const [event, state] of [ + ['hoverIn', 'hover'], + ['pressIn', 'pressed'], + ['pressOut', 'hover'], + ['hoverOut', 'rest'], ] as const) { await fireEvent(getRoot(component), event, {}); expect(getIndicatorStyle(component)).toMatchObject({ - backgroundColor: status === 'unchecked' ? palette.backgroundNeutralTransparent : palette.backgroundBrandHeavy, - borderColor: status === 'unchecked' ? palette.strokeNeutralHeavy : palette.strokeNeutralTransparent, + backgroundColor: (status === 'unchecked' ? colors.backgroundNeutralTransparent : colors.backgroundBrandHeavy)[state], + borderColor: (status === 'unchecked' ? colors.strokeNeutralHeavy : colors.strokeNeutralTransparent)[state], }); expect(StyleSheet.flatten(component.getByTestId('checkbox-label').props.style).color).toBe( - status === 'unchecked' ? palette.foregroundNeutralSecondary : palette.foregroundNeutralPrimary, + (status === 'unchecked' ? colors.foregroundNeutralSecondary : colors.foregroundNeutralPrimary)[state], ); expect(StyleSheet.flatten(component.getByTestId('checkbox-secondary', { includeHiddenElements: true }).props.style).color).toBe( - palette.foregroundNeutralSecondary, + colors.foregroundNeutralSecondary[state], ); if (status !== 'unchecked') { expect(StyleSheet.flatten(component.getByText(status === 'checked' ? '\u2713' : '\u2212').props.style).color).toBe( - palette.foregroundBrandOnloud, + colors.foregroundBrandOnloud[state], ); } } @@ -515,17 +515,17 @@ describe('Checkbox', () => { await component.rerender(); const colors = defaultFlexTokens.color; expect(getIndicatorStyle(component)).toMatchObject({ - backgroundColor: status === 'unchecked' ? colors.backgroundNeutralTransparent : colors.backgroundNeutralHeavyDisabled, - borderColor: status === 'unchecked' ? colors.strokeNeutralDisabled : colors.strokeNeutralTransparent, + backgroundColor: (status === 'unchecked' ? colors.backgroundNeutralTransparent : colors.backgroundNeutralHeavyDisabled).rest, + borderColor: (status === 'unchecked' ? colors.strokeNeutralDisabled : colors.strokeNeutralTransparent).rest, }); for (const id of ['checkbox-label', 'checkbox-secondary']) { expect(StyleSheet.flatten(component.getByTestId(id, { includeHiddenElements: true }).props.style).color).toBe( - colors.foregroundNeutralDisabled, + colors.foregroundNeutralDisabled.rest, ); } if (status !== 'unchecked') { expect(StyleSheet.flatten(component.getByText(status === 'checked' ? '\u2713' : '\u2212').props.style).color).toBe( - colors.foregroundNeutralDisabled, + colors.foregroundNeutralDisabled.rest, ); } }, diff --git a/packages/agentic/components/src/components/checkbox/spec/tokens.yaml b/packages/agentic/components/src/components/checkbox/spec/tokens.yaml index 92401fb0095..d68ae06cbce 100644 --- a/packages/agentic/components/src/components/checkbox/spec/tokens.yaml +++ b/packages/agentic/components/src/components/checkbox/spec/tokens.yaml @@ -3,9 +3,9 @@ component: checkbox implementation: checkbox.styles.ts # Interaction colors are declared once per status. The `hovered` and `pressed` -# entries resolve the same semantic color key through the `color.hover` and -# `color.pressed` sub-palettes, so no separate interaction token names appear -# in the definitions below. +# entries read the `hover` and `pressed` states of the same resolved semantic +# color, so no separate interaction token names appear in the definitions +# below. statePrecedence: - status - disabled diff --git a/packages/agentic/components/src/components/divider/divider.styles.ts b/packages/agentic/components/src/components/divider/divider.styles.ts index 974b58c246a..191e5679be7 100644 --- a/packages/agentic/components/src/components/divider/divider.styles.ts +++ b/packages/agentic/components/src/components/divider/divider.styles.ts @@ -74,14 +74,14 @@ function createLabelStyleDefinition({ return { horizontal: { - color: color.foregroundNeutralSecondary, + color: color.foregroundNeutralSecondary.rest, fontFamily: fontFamily.functional, fontSize: bodySmallSize, fontWeight: fontWeight.functionalRegular, lineHeight: bodySmallLineHeight, }, vertical: { - color: color.foregroundNeutralSecondary, + color: color.foregroundNeutralSecondary.rest, fontFamily: fontFamily.functional, fontSize: bodySmallSize, fontWeight: fontWeight.functionalRegular, @@ -102,7 +102,7 @@ export function getDividerLineStyle(state: DividerState, position: 'before' | 'a const lineThickness = Number(state.tokens.strokeWidth.thin); return { - backgroundColor: state.tokens.color.strokeNeutralSubtle, + backgroundColor: state.tokens.color.strokeNeutralSubtle.rest, ...(state.vertical ? { width: lineThickness } : { height: lineThickness }), flexBasis, flexGrow: isStub ? 0 : 1, diff --git a/packages/agentic/components/src/components/divider/divider.test.tsx b/packages/agentic/components/src/components/divider/divider.test.tsx index 17bb3673d58..f25e9d22010 100644 --- a/packages/agentic/components/src/components/divider/divider.test.tsx +++ b/packages/agentic/components/src/components/divider/divider.test.tsx @@ -118,12 +118,12 @@ describe('Divider', () => { const afterExpected = layout === 'end' ? { flexBasis: stub, flexGrow: 0 } : { flexBasis: 0, flexGrow: 1 }; expect(StyleSheet.flatten(beforeLine.props.style)).toMatchObject({ - backgroundColor: tokens.color.strokeNeutralSubtle, + backgroundColor: tokens.color.strokeNeutralSubtle.rest, height: tokens.strokeWidth.thin, ...beforeExpected, }); expect(StyleSheet.flatten(afterLine.props.style)).toMatchObject({ - backgroundColor: tokens.color.strokeNeutralSubtle, + backgroundColor: tokens.color.strokeNeutralSubtle.rest, height: tokens.strokeWidth.thin, ...afterExpected, }); @@ -142,7 +142,7 @@ describe('Divider', () => { expect(StyleSheet.flatten(root.props.style)).toMatchObject({ flexDirection: 'column' }); expect(StyleSheet.flatten(beforeLine.props.style)).toMatchObject({ - backgroundColor: tokens.color.strokeNeutralSubtle, + backgroundColor: tokens.color.strokeNeutralSubtle.rest, width: tokens.strokeWidth.thin, flexGrow: 1, }); @@ -151,7 +151,7 @@ describe('Divider', () => { paddingVertical: tokens.spacing.componentBase300, }); expect(StyleSheet.flatten(component.getByText('Section').props.style)).toMatchObject({ - color: tokens.color.foregroundNeutralSecondary, + color: tokens.color.foregroundNeutralSecondary.rest, fontFamily: tokens.fontFamily.functional, fontSize: tokens.fontSize.functionalBodySmall, lineHeight: tokens.lineHeight.functionalBodySmall, diff --git a/packages/agentic/components/src/components/divider/useDividerStyles.ts b/packages/agentic/components/src/components/divider/useDividerStyles.ts index 26632d4e920..9ef070644dd 100644 --- a/packages/agentic/components/src/components/divider/useDividerStyles.ts +++ b/packages/agentic/components/src/components/divider/useDividerStyles.ts @@ -27,7 +27,7 @@ export function useDividerStyles_unstable(state: DividerState) { if (state.icon) { attachSlotProps(state.icon, { accessible: false, - color: state.tokens.color.foregroundNeutralSecondary, + color: state.tokens.color.foregroundNeutralSecondary.rest, height: 20, width: 20, }); diff --git a/packages/agentic/components/src/components/dropdown/dropdown.styles.ts b/packages/agentic/components/src/components/dropdown/dropdown.styles.ts index 18df1099b81..9b69ba200b1 100644 --- a/packages/agentic/components/src/components/dropdown/dropdown.styles.ts +++ b/packages/agentic/components/src/components/dropdown/dropdown.styles.ts @@ -38,8 +38,8 @@ export const dropdownStyles = StyleSheet.create({ export const getDropdownThemeStyles = themedStyleSheetFactory('Dropdown.listbox', ({ tokens }) => StyleSheet.create({ surface: { - backgroundColor: tokens.color.surfaceNeutralNearer, - borderColor: tokens.color.strokeNeutralSubtle, + backgroundColor: tokens.color.surfaceNeutralNearer.rest, + borderColor: tokens.color.strokeNeutralSubtle.rest, borderRadius: tokens.borderRadius.base400, borderStyle: 'solid', borderWidth: tokens.strokeWidth.thin, @@ -51,10 +51,10 @@ export const getDropdownThemeStyles = themedStyleSheetFactory('Dropdown.listbox' /** The chevron is disabled when disabled, primary in error or while the focus indicator shows, and secondary otherwise. */ export function getDropdownChevronColor(tokens: FlexTokens, visualState: InputVisualState, focusVisible: boolean): ColorValue { if (visualState === 'disabled') { - return tokens.color.foregroundNeutralDisabled; + return tokens.color.foregroundNeutralDisabled.rest; } if (visualState === 'error' || focusVisible) { - return tokens.color.foregroundNeutralPrimary; + return tokens.color.foregroundNeutralPrimary.rest; } - return tokens.color.foregroundNeutralSecondary; + return tokens.color.foregroundNeutralSecondary.rest; } diff --git a/packages/agentic/components/src/components/input/input.styles.ts b/packages/agentic/components/src/components/input/input.styles.ts index adcf3bc903f..e349cd2cbd6 100644 --- a/packages/agentic/components/src/components/input/input.styles.ts +++ b/packages/agentic/components/src/components/input/input.styles.ts @@ -168,22 +168,22 @@ function createContentsStrokeDefinition(tokens: FlexTokens): StyleDefinition; const underlineStates = { - disabled: { borderBottomColor: color.strokeNeutralDisabled }, - error: { borderBottomColor: color.strokeDangerLoud }, - focused: { borderBottomColor: color.strokeFocusOuter }, - hovered: { borderBottomColor: color.hover.strokeNeutralLoud }, - pressed: { borderBottomColor: color.pressed.strokeNeutralLoud }, - readOnly: { borderBottomColor: color.strokeNeutralDisabled }, - rest: { borderBottomColor: color.strokeNeutralLoud }, + disabled: { borderBottomColor: color.strokeNeutralDisabled.rest }, + error: { borderBottomColor: color.strokeDangerLoud.rest }, + focused: { borderBottomColor: color.strokeFocusOuter.rest }, + hovered: { borderBottomColor: color.strokeNeutralLoud.hover }, + pressed: { borderBottomColor: color.strokeNeutralLoud.pressed }, + readOnly: { borderBottomColor: color.strokeNeutralDisabled.rest }, + rest: { borderBottomColor: color.strokeNeutralLoud.rest }, } satisfies Record; function createSizeBranch(base: ViewStyle, states: Record) { @@ -254,7 +254,7 @@ function createTextInputDefinition(tokens: FlexTokens): StyleDefinition { expect(onFocus).toHaveBeenCalledTimes(1); expect(onChangeText).toHaveBeenCalledWith('hello'); expect(flattenStyle(getContents(component).props.style)).toMatchObject({ - borderColor: colors.strokeNeutralSubtle, + borderColor: colors.strokeNeutralSubtle.rest, }); }); @@ -215,7 +215,7 @@ describe('Input', () => { expect(textbox.props.editable).toBe(false); expect(textbox.props.accessibilityState).toMatchObject({ disabled: true, readOnly: false }); expect(flattenStyle(getContents(component).props.style)).toMatchObject({ - borderColor: colors.strokeNeutralDisabled, + borderColor: colors.strokeNeutralDisabled.rest, }); await fireEvent.changeText(textbox, 'blocked'); @@ -230,7 +230,7 @@ describe('Input', () => { expect(textbox.props.editable).toBe(false); expect(textbox.props.accessibilityState).toMatchObject({ disabled: false, readOnly: true }); expect(flattenStyle(getContents(component).props.style)).toMatchObject({ - borderColor: colors.strokeNeutralDisabled, + borderColor: colors.strokeNeutralDisabled.rest, }); }); @@ -271,21 +271,21 @@ describe('Input', () => { } expect(flattenStyle(indicator.props.style).opacity).not.toBe(0); const boundary = props.error - ? colors.strokeDangerLoud + ? colors.strokeDangerLoud.rest : props.readOnly - ? colors.strokeNeutralDisabled + ? colors.strokeNeutralDisabled.rest : props.variant === 'outline' - ? colors.strokeNeutralSubtle - : colors.strokeFocusOuter; + ? colors.strokeNeutralSubtle.rest + : colors.strokeFocusOuter.rest; if (props.variant === 'outline') { expect(flattenStyle(getContents(component).props.style).borderColor).toBe(boundary); expect(flattenStyle(indicator.props.style)).toMatchObject({ - borderColor: colors.strokeFocusOuter, + borderColor: colors.strokeFocusOuter.rest, borderWidth: defaultFlexTokens.strokeWidth.thick, }); const inner = component.getByTestId('focus-visual-inner', { includeHiddenElements: true }); expect(flattenStyle(inner.props.style)).toMatchObject({ - borderColor: colors.strokeFocusInner, + borderColor: colors.strokeFocusInner.rest, borderWidth: defaultFlexTokens.strokeWidth.thin, }); } else { @@ -295,7 +295,7 @@ describe('Input', () => { borderBottomWidth: defaultFlexTokens.strokeWidth.thin, }); expect(flattenStyle(indicator.props.style)).toMatchObject({ - borderBottomColor: colors.strokeFocusOuter, + borderBottomColor: colors.strokeFocusOuter.rest, borderBottomWidth: defaultFlexTokens.strokeWidth.thin, bottom: defaultFlexTokens.strokeWidth.thin, }); @@ -327,7 +327,7 @@ describe('Input', () => { width: 24, }); expect(flattenStyle(component.getByText('\u2605').props.style)).toMatchObject({ - color: colors.foregroundNeutralPrimary, + color: colors.foregroundNeutralPrimary.rest, }); expect(component.getByTestId('icon-end-1').props.style).toMatchObject({ height: 24, width: 24 }); expect(component.getByTestId('icon-end-2').props.style).toMatchObject({ height: 24, width: 24 }); diff --git a/packages/agentic/components/src/components/input/spec/tokens.yaml b/packages/agentic/components/src/components/input/spec/tokens.yaml index 490dd22a475..8c9be6f7b0c 100644 --- a/packages/agentic/components/src/components/input/spec/tokens.yaml +++ b/packages/agentic/components/src/components/input/spec/tokens.yaml @@ -56,8 +56,8 @@ bindings: focused: outline: color.strokeNeutralSubtle underline: color.strokeFocusOuter - pressed: color.pressed.strokeNeutralLoud - hovered: color.hover.strokeNeutralLoud + pressed: color.strokeNeutralLoud.pressed + hovered: color.strokeNeutralLoud.hover rest: color.strokeNeutralLoud iconTextStack: diff --git a/packages/agentic/components/src/components/list-item/__snapshots__/list-item.test.tsx.snap b/packages/agentic/components/src/components/list-item/__snapshots__/list-item.test.tsx.snap index 43aa51c6e88..7a88ae632a7 100644 --- a/packages/agentic/components/src/components/list-item/__snapshots__/list-item.test.tsx.snap +++ b/packages/agentic/components/src/components/list-item/__snapshots__/list-item.test.tsx.snap @@ -4,8 +4,8 @@ exports[`ListItem renders the default row with selection hidden and stable conte { "alignItems": "center", "alignSelf": "stretch", - "backgroundColor": "#00000000", - "borderRadius": 4, + "backgroundColor": "#24242400", + "borderRadius": 12, "flexDirection": "row", "justifyContent": "flex-start", "paddingHorizontal": 12, diff --git a/packages/agentic/components/src/components/list-item/list-item.test.tsx b/packages/agentic/components/src/components/list-item/list-item.test.tsx index 90945f3bc9d..ffa7cc1a9a5 100644 --- a/packages/agentic/components/src/components/list-item/list-item.test.tsx +++ b/packages/agentic/components/src/components/list-item/list-item.test.tsx @@ -49,8 +49,8 @@ describe('ListItem', () => { } expect(getRootStyle(component).backgroundColor).toBe( selected && selectionMode !== 'multiple' - ? defaultFlexTokens.color.backgroundNeutralSoft - : defaultFlexTokens.color.backgroundNeutralTransparent, + ? defaultFlexTokens.color.backgroundNeutralSoft.rest + : defaultFlexTokens.color.backgroundNeutralTransparent.rest, ); }); @@ -69,7 +69,7 @@ describe('ListItem', () => { it.each(['none', 'single', 'multiple'] as const)('LIT-004 suppresses selected fill while disabled in %s mode', async (selectionMode) => { const component = await renderListItem({ content: 'Unavailable', selected: true, disabled: true, selectionMode }); - expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent.rest); expect(getRoot(component).props.accessibilityState).toEqual({ disabled: true, selected: true }); }); @@ -104,7 +104,7 @@ describe('ListItem', () => { await fireEvent(root, 'hoverIn', {}); expect(onHoverIn).toHaveBeenCalledTimes(1); - expect(getRootStyle(component).backgroundColor).toBe(colors.hover.backgroundNeutralTransparent); + expect(getRootStyle(component).backgroundColor).toBe(colors.backgroundNeutralTransparent.hover); await fireEvent(root, 'pressIn', {}); expect(onPress).toHaveBeenCalledTimes(0); @@ -137,7 +137,7 @@ describe('ListItem', () => { const component = await renderListItem({ content: 'Selected', selectionMode: 'multiple', selected: true }); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: colors.backgroundNeutralTransparent, + backgroundColor: colors.backgroundNeutralTransparent.rest, }); }); diff --git a/packages/agentic/components/src/components/listbox-item/listbox-item.styles.ts b/packages/agentic/components/src/components/listbox-item/listbox-item.styles.ts index e33430c0b12..df19711c228 100644 --- a/packages/agentic/components/src/components/listbox-item/listbox-item.styles.ts +++ b/packages/agentic/components/src/components/listbox-item/listbox-item.styles.ts @@ -64,18 +64,18 @@ export const listboxItemStyles = StyleSheet.create({ function getColor(state: ListboxItemState, key: 'primary' | 'secondary'): ViewStyle['backgroundColor'] { const colors = state.tokens.color; if (state.disabled) { - return colors.foregroundNeutralDisabled; + return colors.foregroundNeutralDisabled.rest; } if (state.pressed) { - return key === 'primary' ? colors.pressed.foregroundNeutralPrimary : colors.pressed.foregroundNeutralSecondary; + return key === 'primary' ? colors.foregroundNeutralPrimary.pressed : colors.foregroundNeutralSecondary.pressed; } if (state.hovered) { - return key === 'primary' ? colors.hover.foregroundNeutralPrimary : colors.hover.foregroundNeutralSecondary; + return key === 'primary' ? colors.foregroundNeutralPrimary.hover : colors.foregroundNeutralSecondary.hover; } if (key === 'secondary' && state.variant === 'listItem' && state.selected && !state.multiselect) { - return colors.foregroundNeutralPrimary; + return colors.foregroundNeutralPrimary.rest; } - return key === 'primary' ? colors.foregroundNeutralPrimary : colors.foregroundNeutralSecondary; + return key === 'primary' ? colors.foregroundNeutralPrimary.rest : colors.foregroundNeutralSecondary.rest; } function getLabelWeight(state: ListboxItemState): TextStyle['fontWeight'] { @@ -89,19 +89,19 @@ export function getListboxItemRootStyle(state: ListboxItemState): ViewStyle { const selected = state.variant === 'listItem' && state.selected && !state.multiselect; const backgroundColor = state.disabled ? selected - ? colors.backgroundNeutralSubtleDisabled - : colors.backgroundNeutralTransparent + ? colors.backgroundNeutralSubtleDisabled.rest + : colors.backgroundNeutralTransparent.rest : state.pressed ? selected - ? colors.pressed.backgroundNeutralSoft - : colors.pressed.backgroundNeutralTransparent + ? colors.backgroundNeutralSoft.pressed + : colors.backgroundNeutralTransparent.pressed : state.hovered ? selected - ? colors.hover.backgroundNeutralSoft - : colors.hover.backgroundNeutralTransparent + ? colors.backgroundNeutralSoft.hover + : colors.backgroundNeutralTransparent.hover : selected - ? colors.backgroundNeutralSoft - : colors.backgroundNeutralTransparent; + ? colors.backgroundNeutralSoft.rest + : colors.backgroundNeutralTransparent.rest; return { backgroundColor, @@ -114,7 +114,7 @@ export function getListboxItemRootStyle(state: ListboxItemState): ViewStyle { export function getListboxItemHeaderStyle(state: ListboxItemState): ViewStyle { return { - backgroundColor: state.tokens.color.backgroundNeutralTransparent, + backgroundColor: state.tokens.color.backgroundNeutralTransparent.rest, borderRadius: state.tokens.borderRadius.base300, minHeight: 40, paddingHorizontal: state.tokens.spacing.componentBase300, diff --git a/packages/agentic/components/src/components/listbox-item/listbox-item.test.tsx b/packages/agentic/components/src/components/listbox-item/listbox-item.test.tsx index 94df9b80004..a0a3d566224 100644 --- a/packages/agentic/components/src/components/listbox-item/listbox-item.test.tsx +++ b/packages/agentic/components/src/components/listbox-item/listbox-item.test.tsx @@ -117,7 +117,7 @@ describe('ListboxItem', () => { const component = await renderListboxItem({ content: 'Choice', multiselect: true, selected: true }); const root = component.getByRole('button'); - expect(StyleSheet.flatten(root.props.style).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent); + expect(StyleSheet.flatten(root.props.style).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent.rest); expect(StyleSheet.flatten(component.getByText('Choice').props.style).fontWeight).toBe(defaultFlexTokens.fontWeight.functionalRegular); expect(component.getByText('✓')).toBeOnTheScreen(); }); @@ -147,16 +147,16 @@ describe('ListboxItem', () => { const component = await renderListboxItem({ content: 'Choice' }); const root = component.getByRole('button'); await fireEvent(root, 'hoverIn', {}); - expect(StyleSheet.flatten(root.props.style).backgroundColor).toBe(defaultFlexTokens.color.hover.backgroundNeutralTransparent); + expect(StyleSheet.flatten(root.props.style).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent.hover); await fireEvent(root, 'pressIn', {}); - expect(StyleSheet.flatten(root.props.style).backgroundColor).toBe(defaultFlexTokens.color.pressed.backgroundNeutralTransparent); + expect(StyleSheet.flatten(root.props.style).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent.pressed); await fireEvent(root, 'focus', {}); expect(root.props.enableFocusRing).toBe(true); expect(component.queryByTestId('focus-visual', { includeHiddenElements: true })).toBeNull(); expect(StyleSheet.flatten(root.props.style)).not.toMatchObject({ - outlineColor: defaultFlexTokens.color.strokeFocusOuter, + outlineColor: defaultFlexTokens.color.strokeFocusOuter.rest, outlineStyle: 'solid', }); }); diff --git a/packages/agentic/components/src/components/listbox-item/useListboxItemStyles.ts b/packages/agentic/components/src/components/listbox-item/useListboxItemStyles.ts index 906dfbe2e3a..1d713000add 100644 --- a/packages/agentic/components/src/components/listbox-item/useListboxItemStyles.ts +++ b/packages/agentic/components/src/components/listbox-item/useListboxItemStyles.ts @@ -90,7 +90,7 @@ export function useListboxItemStyles_unstable(state: ListboxItemState) { if (state.chevronIndicator) { attachSlotProps(state.chevronIndicator, { accessible: false, - color: state.tokens.color.foregroundNeutralPrimary, + color: state.tokens.color.foregroundNeutralPrimary.rest, height: getListboxItemIconSize(), width: getListboxItemIconSize(), }); @@ -99,7 +99,7 @@ export function useListboxItemStyles_unstable(state: ListboxItemState) { if (state.checkmarkIndicator) { attachSlotProps(state.checkmarkIndicator, { accessible: false, - color: state.tokens.color.foregroundNeutralPrimary, + color: state.tokens.color.foregroundNeutralPrimary.rest, height: getListboxItemCheckmarkSize(), width: getListboxItemCheckmarkSize(), }); @@ -107,14 +107,16 @@ export function useListboxItemStyles_unstable(state: ListboxItemState) { if (state.checkboxIndicator) { attachSlotProps(state.checkboxIndicator, { - iconColor: state.tokens.color.foregroundNeutralOnloud, + iconColor: state.tokens.color.foregroundNeutralOnloud.rest, iconSize: 12, status: state.selected ? 'checked' : 'unchecked', style: [ listboxItemStyles.checkboxBox, { - backgroundColor: state.selected ? state.tokens.color.backgroundBrandHeavy : state.tokens.color.backgroundNeutralTransparent, - borderColor: state.selected ? state.tokens.color.backgroundBrandHeavy : state.tokens.color.foregroundNeutralSecondary, + backgroundColor: state.selected + ? state.tokens.color.backgroundBrandHeavy.rest + : state.tokens.color.backgroundNeutralTransparent.rest, + borderColor: state.selected ? state.tokens.color.backgroundBrandHeavy.rest : state.tokens.color.foregroundNeutralSecondary.rest, height: getListboxItemCheckmarkSize(), width: getListboxItemCheckmarkSize(), }, diff --git a/packages/agentic/components/src/components/menu-item/menu-item.styles.ts b/packages/agentic/components/src/components/menu-item/menu-item.styles.ts index 7f84efe1bf7..e472c214e48 100644 --- a/packages/agentic/components/src/components/menu-item/menu-item.styles.ts +++ b/packages/agentic/components/src/components/menu-item/menu-item.styles.ts @@ -289,8 +289,8 @@ export function getMenuItemCheckboxStyle(state: MenuItemState): ViewStyle { const colors = state.tokens.color; return { alignItems: 'center', - backgroundColor: state.selected ? colors.backgroundBrandHeavy : colors.backgroundNeutralTransparent, - borderColor: state.selected ? colors.backgroundBrandHeavy : colors.strokeNeutralLoud, + backgroundColor: state.selected ? colors.backgroundBrandHeavy.rest : colors.backgroundNeutralTransparent.rest, + borderColor: state.selected ? colors.backgroundBrandHeavy.rest : colors.strokeNeutralLoud.rest, borderRadius: 4, borderWidth: 1, height: size160, diff --git a/packages/agentic/components/src/components/menu-item/menu-item.test.tsx b/packages/agentic/components/src/components/menu-item/menu-item.test.tsx index ae1e638eb43..50505706788 100644 --- a/packages/agentic/components/src/components/menu-item/menu-item.test.tsx +++ b/packages/agentic/components/src/components/menu-item/menu-item.test.tsx @@ -5,6 +5,7 @@ import { fireEvent } from '@testing-library/react-native'; import { render } from '../../common/renderWithTheme'; import type { RenderResult } from '@testing-library/react-native'; +import { defaultFlexTokens } from '@fluentui-react-native/design/testing'; import { MenuItem } from './menu-item'; import type { MenuItemProps } from './menu-item.types'; import { MenuItemMenuContext } from './menuItemContext'; @@ -40,7 +41,7 @@ describe('MenuItem', () => { expect(component.getAllByText('Save', { includeHiddenElements: true })).toHaveLength(2); expect(component.getAllByText('Secondary', { includeHiddenElements: true })).toHaveLength(2); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: '#00000000', + backgroundColor: defaultFlexTokens.color.backgroundNeutralTransparent.rest, minHeight: 40, }); }); @@ -55,7 +56,7 @@ describe('MenuItem', () => { expect(component.queryByTestId('regular-icon')).toBeNull(); expect(component.getByTestId('selected-icon')).toBeOnTheScreen(); - expect(getRootStyle(component).backgroundColor).toBe('#0000001a'); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSoft.rest); expect( component .getAllByText('Favorite', { includeHiddenElements: true }) @@ -69,7 +70,7 @@ describe('MenuItem', () => { expect(getRoot(component, 'menuitemradio').props.accessibilityRole).toBe('menuitemradio'); expect(getRoot(component, 'menuitemradio').props.accessibilityState).toMatchObject({ checked: false }); - expect(getRootStyle(component, 'menuitemradio').backgroundColor).toBe('#00000000'); + expect(getRootStyle(component, 'menuitemradio').backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent.rest); }); it('renders a multiselect checkbox and keeps the row background transparent', async () => { @@ -81,7 +82,7 @@ describe('MenuItem', () => { expect(getRoot(component, 'menuitemcheckbox').props.accessibilityRole).toBe('menuitemcheckbox'); expect(getRoot(component, 'menuitemcheckbox').props.accessibilityState).toMatchObject({ checked: true }); - expect(getRootStyle(component, 'menuitemcheckbox').backgroundColor).toBe('#00000000'); + expect(getRootStyle(component, 'menuitemcheckbox').backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralTransparent.rest); }); it('supports section headers, loading skeletons, and no focusability', async () => { diff --git a/packages/agentic/components/src/components/menu-item/useMenuItemStyles.ts b/packages/agentic/components/src/components/menu-item/useMenuItemStyles.ts index 7b06dbd23f8..1b73b289190 100644 --- a/packages/agentic/components/src/components/menu-item/useMenuItemStyles.ts +++ b/packages/agentic/components/src/components/menu-item/useMenuItemStyles.ts @@ -65,7 +65,7 @@ export function useMenuItemStyles_unstable(state: MenuItemState) { if (state.checkmark) { attachSlotProps(state.checkmark, { accessible: false, - color: state.hasMultiselect ? state.tokens.color.foregroundBrandOnloud : labelColor, + color: state.hasMultiselect ? state.tokens.color.foregroundBrandOnloud.rest : labelColor, height: state.hasMultiselect ? 12 : 16, style: state.selected ? undefined : { opacity: 0 }, width: state.hasMultiselect ? 12 : 16, @@ -75,7 +75,7 @@ export function useMenuItemStyles_unstable(state: MenuItemState) { if (state.multiselectCheckbox) { attachSlotProps(state.multiselectCheckbox, { ...hiddenFromAccessibilityProps, - iconColor: state.tokens.color.foregroundBrandOnloud, + iconColor: state.tokens.color.foregroundBrandOnloud.rest, iconSize: 12, status: state.selected ? 'checked' : 'unchecked', style: [menuItemStyles.multiselectCheckbox, getMenuItemCheckboxStyle(state), getMenuItemTrailingStyle(state)], diff --git a/packages/agentic/components/src/components/menu/menu.styles.ts b/packages/agentic/components/src/components/menu/menu.styles.ts index 05eabf96f97..0f3b4588b25 100644 --- a/packages/agentic/components/src/components/menu/menu.styles.ts +++ b/packages/agentic/components/src/components/menu/menu.styles.ts @@ -14,8 +14,8 @@ export const menuStyles = StyleSheet.create({ export const getMenuThemeStyles = themedStyleSheetFactory('Menu.surface', ({ tokens }) => StyleSheet.create({ surface: { - backgroundColor: tokens.color.surfaceNeutralNearer, - borderColor: tokens.color.strokeNeutralSubtle, + backgroundColor: tokens.color.surfaceNeutralNearer.rest, + borderColor: tokens.color.strokeNeutralSubtle.rest, borderRadius: tokens.borderRadius.base400, borderStyle: 'solid', borderWidth: tokens.strokeWidth.thin, diff --git a/packages/agentic/components/src/components/popover/popover.styles.ts b/packages/agentic/components/src/components/popover/popover.styles.ts index 09f3f032732..0412d0f6864 100644 --- a/packages/agentic/components/src/components/popover/popover.styles.ts +++ b/packages/agentic/components/src/components/popover/popover.styles.ts @@ -13,8 +13,8 @@ export const popoverStyles = StyleSheet.create({ export const getPopoverThemeStyles = themedStyleSheetFactory('Popover.surface', ({ tokens }) => StyleSheet.create({ surface: { - backgroundColor: tokens.color.surfaceNeutralNearer, - borderColor: tokens.color.strokeNeutralSubtle, + backgroundColor: tokens.color.surfaceNeutralNearer.rest, + borderColor: tokens.color.strokeNeutralSubtle.rest, borderRadius: tokens.borderRadius.base400, borderStyle: 'solid', borderWidth: tokens.strokeWidth.thin, diff --git a/packages/agentic/components/src/components/progress-bar/progress-bar.styles.ts b/packages/agentic/components/src/components/progress-bar/progress-bar.styles.ts index fedb0564bcc..9f56aed59a7 100644 --- a/packages/agentic/components/src/components/progress-bar/progress-bar.styles.ts +++ b/packages/agentic/components/src/components/progress-bar/progress-bar.styles.ts @@ -35,7 +35,7 @@ export function getProgressBarThemeStyles(themeState: ThemeState): ProgressBarTh minWidth: 0, }, indicator: { - backgroundColor: color.foregroundBrandPrimary, + backgroundColor: color.foregroundBrandPrimary.rest, borderRadius: cornerRadiusCircular, bottom: 0, left: 0, @@ -43,7 +43,7 @@ export function getProgressBarThemeStyles(themeState: ThemeState): ProgressBarTh top: 0, }, label: { - color: color.foregroundNeutralPrimary, + color: color.foregroundNeutralPrimary.rest, flexGrow: 1, flexShrink: 1, fontFamily: fontFamily.functional, @@ -62,7 +62,7 @@ export function getProgressBarThemeStyles(themeState: ThemeState): ProgressBarTh gap: getGapStyleValue(spacing.componentBase100), }, track: { - backgroundColor: color.backgroundNeutralSoft, + backgroundColor: color.backgroundNeutralSoft.rest, borderRadius: cornerRadiusCircular, height: spacing.componentBase100, overflow: 'hidden', @@ -73,7 +73,7 @@ export function getProgressBarThemeStyles(themeState: ThemeState): ProgressBarTh width: size160, }, valueText: { - color: color.foregroundNeutralSecondary, + color: color.foregroundNeutralSecondary.rest, fontFamily: fontFamily.functional, fontSize: fontSize.functionalBodySmall, lineHeight: lineHeight.functionalBodySmall, diff --git a/packages/agentic/components/src/components/progress-bar/progress-bar.test.tsx b/packages/agentic/components/src/components/progress-bar/progress-bar.test.tsx index 35fef0f1467..f4f20b7d9f4 100644 --- a/packages/agentic/components/src/components/progress-bar/progress-bar.test.tsx +++ b/packages/agentic/components/src/components/progress-bar/progress-bar.test.tsx @@ -94,9 +94,9 @@ describe('ProgressBar', () => { }); const icon = component.getByTestId('validation-icon', { includeHiddenElements: true }); - expect(getIndicatorStyle(component).backgroundColor).toBe(defaultFlexTokens.color[token]); + expect(getIndicatorStyle(component).backgroundColor).toBe(defaultFlexTokens.color[token].rest); expect(StyleSheet.flatten(component.getByText('★', { includeHiddenElements: true }).props.style).color).toBe( - defaultFlexTokens.color[token], + defaultFlexTokens.color[token].rest, ); expect(icon.props.accessible).toBe(false); expect(StyleSheet.flatten(icon.props.style)).toMatchObject({ height: 16, width: 16 }); @@ -188,7 +188,10 @@ describe('ProgressBar', () => { nativeEvent: { layout: { height: 4, width: 200, x: 0, y: 0 } }, }); - expect(getIndicatorStyle(component)).toMatchObject({ backgroundColor: '#185abd', width: 100 }); + expect(getIndicatorStyle(component)).toMatchObject({ + backgroundColor: defaultFlexTokens.color.foregroundBrandPrimary.rest, + width: 100, + }); expect(StyleSheet.flatten(getRoot(component).props.style)).toMatchObject({ backgroundColor: 'hotpink' }); expect(component.getByText('Halfway there')).toBeOnTheScreen(); }); diff --git a/packages/agentic/components/src/components/progress-bar/useProgressBar.ts b/packages/agentic/components/src/components/progress-bar/useProgressBar.ts index 18dd793e572..df07f3dc181 100644 --- a/packages/agentic/components/src/components/progress-bar/useProgressBar.ts +++ b/packages/agentic/components/src/components/progress-bar/useProgressBar.ts @@ -29,12 +29,12 @@ function getStatusColor(themeState: ReturnType, status: Pr const { color } = themeState.tokens; switch (status) { case 'error': - return color.foregroundDangerPrimary; + return color.foregroundDangerPrimary.rest; case 'success': - return color.foregroundSuccessPrimary; + return color.foregroundSuccessPrimary.rest; case 'neutral': default: - return color.foregroundBrandPrimary; + return color.foregroundBrandPrimary.rest; } } diff --git a/packages/agentic/components/src/components/radio/radio.styles.ts b/packages/agentic/components/src/components/radio/radio.styles.ts index f1b1ffa3350..5102e4f458b 100644 --- a/packages/agentic/components/src/components/radio/radio.styles.ts +++ b/packages/agentic/components/src/components/radio/radio.styles.ts @@ -50,7 +50,7 @@ const toDimensionValue = (value: unknown): number => Number(getNumericStyleValue const getRadioRootLayoutStyle = getThemedStateStyleFactory( 'Radio.rootLayout', ({ borderRadius, color, spacing }: FlexTokens): StyleDefinition => ({ - backgroundColor: color.backgroundNeutralTransparent, + backgroundColor: color.backgroundNeutralTransparent.rest, borderRadius: borderRadius.base300, gap: toDimensionValue(spacing.componentBase100), }), @@ -60,7 +60,7 @@ const getRadioRootLayoutStyle = getThemedStateStyleFactory( const getRadioIndicatorLayoutStyle = getThemedStateStyleFactory( 'Radio.indicatorLayout', ({ color, spacing, strokeWidth }: FlexTokens): StyleDefinition => ({ - backgroundColor: color.backgroundNeutralTransparent, + backgroundColor: color.backgroundNeutralTransparent.rest, borderRadius: 8, borderStyle: 'solid', borderWidth: strokeWidth.thin, diff --git a/packages/agentic/components/src/components/radio/radio.test.tsx b/packages/agentic/components/src/components/radio/radio.test.tsx index db83b7fe2b3..4c03cf8d7cd 100644 --- a/packages/agentic/components/src/components/radio/radio.test.tsx +++ b/packages/agentic/components/src/components/radio/radio.test.tsx @@ -67,26 +67,26 @@ describe('Radio', () => { expect(getRootStyle(component)).toMatchObject({ alignItems: 'center', - backgroundColor: tokens.color.backgroundNeutralTransparent, + backgroundColor: tokens.color.backgroundNeutralTransparent.rest, borderRadius: tokens.borderRadius.base300, gap: tokens.spacing.componentBase100, }); expect(StyleSheet.flatten(getTestId(component, 'radio-indicator').props.style)).toMatchObject({ - backgroundColor: tokens.color.backgroundNeutralTransparent, - borderColor: tokens.color.strokeNeutralHeavy, + backgroundColor: tokens.color.backgroundNeutralTransparent.rest, + borderColor: tokens.color.strokeNeutralHeavy.rest, borderStyle: 'solid', borderWidth: tokens.strokeWidth.thin, height: 16, width: 16, }); expect(StyleSheet.flatten(getTestId(component, 'radio-dot').props.style)).toMatchObject({ - backgroundColor: tokens.color.foregroundBrandPrimary, + backgroundColor: tokens.color.foregroundBrandPrimary.rest, height: 10, opacity: 0, width: 10, }); expect(StyleSheet.flatten(getText(component, 'Choice').props.style)).toMatchObject({ - color: tokens.color.foregroundNeutralSecondary, + color: tokens.color.foregroundNeutralSecondary.rest, fontSize: expect.any(Number), }); }); @@ -97,12 +97,12 @@ describe('Radio', () => { const root = getRoot(component); expect(root.props.accessibilityState).toEqual({ checked: true, selected: true, disabled: false }); - expect(StyleSheet.flatten(getTestId(component, 'radio-indicator').props.style).borderColor).toBe(tokens.strokeBrandLoud); + expect(StyleSheet.flatten(getTestId(component, 'radio-indicator').props.style).borderColor).toBe(tokens.strokeBrandLoud.rest); expect(StyleSheet.flatten(getTestId(component, 'radio-dot').props.style)).toMatchObject({ - backgroundColor: tokens.foregroundBrandPrimary, + backgroundColor: tokens.foregroundBrandPrimary.rest, opacity: 1, }); - expect(StyleSheet.flatten(getText(component, 'Choice').props.style).color).toBe(tokens.foregroundNeutralPrimary); + expect(StyleSheet.flatten(getText(component, 'Choice').props.style).color).toBe(tokens.foregroundNeutralPrimary.rest); }); it('updates interaction colors on hover and press', async () => { @@ -111,12 +111,12 @@ describe('Radio', () => { const root = getRoot(component); await fireEvent(root, 'hoverIn', {}); - expect(StyleSheet.flatten(getTestId(component, 'radio-indicator').props.style).borderColor).toBe(tokens.hover.strokeNeutralHeavy); - expect(StyleSheet.flatten(getText(component, 'Choice').props.style).color).toBe(tokens.hover.foregroundNeutralSecondary); + expect(StyleSheet.flatten(getTestId(component, 'radio-indicator').props.style).borderColor).toBe(tokens.strokeNeutralHeavy.hover); + expect(StyleSheet.flatten(getText(component, 'Choice').props.style).color).toBe(tokens.foregroundNeutralSecondary.hover); await fireEvent(root, 'pressIn', {}); - expect(StyleSheet.flatten(getTestId(component, 'radio-indicator').props.style).borderColor).toBe(tokens.pressed.strokeNeutralHeavy); - expect(StyleSheet.flatten(getText(component, 'Choice').props.style).color).toBe(tokens.pressed.foregroundNeutralSecondary); + expect(StyleSheet.flatten(getTestId(component, 'radio-indicator').props.style).borderColor).toBe(tokens.strokeNeutralHeavy.pressed); + expect(StyleSheet.flatten(getText(component, 'Choice').props.style).color).toBe(tokens.foregroundNeutralSecondary.pressed); }); it('uses native focus visuals without mounting custom rings', async () => { diff --git a/packages/agentic/components/src/components/skeleton/__snapshots__/skeleton.test.tsx.snap b/packages/agentic/components/src/components/skeleton/__snapshots__/skeleton.test.tsx.snap index ea426179096..1c8e1bdf0b3 100644 --- a/packages/agentic/components/src/components/skeleton/__snapshots__/skeleton.test.tsx.snap +++ b/packages/agentic/components/src/components/skeleton/__snapshots__/skeleton.test.tsx.snap @@ -2,8 +2,8 @@ exports[`Skeleton renders a decorative bar with themed fill and rounded corners 1`] = ` { - "backgroundColor": "#0000001a", - "borderRadius": 2, + "backgroundColor": "#00000014", + "borderRadius": 4, "height": 16, "overflow": "hidden", "position": "relative", diff --git a/packages/agentic/components/src/components/skeleton/skeleton.stories.tsx b/packages/agentic/components/src/components/skeleton/skeleton.stories.tsx index 48e16b99af8..878b24042cd 100644 --- a/packages/agentic/components/src/components/skeleton/skeleton.stories.tsx +++ b/packages/agentic/components/src/components/skeleton/skeleton.stories.tsx @@ -59,7 +59,7 @@ type Story = WdioStory>; function MotionExample() { const reduceMotion = useReducedMotion(); - const highlightColor: unknown = useThemeState().tokens.color.backgroundNeutralSubtle; + const highlightColor: unknown = useThemeState().tokens.color.backgroundNeutralSubtle.rest; return ( diff --git a/packages/agentic/components/src/components/skeleton/skeleton.styles.ts b/packages/agentic/components/src/components/skeleton/skeleton.styles.ts index 7ec3b201c63..d5470522a76 100644 --- a/packages/agentic/components/src/components/skeleton/skeleton.styles.ts +++ b/packages/agentic/components/src/components/skeleton/skeleton.styles.ts @@ -23,12 +23,12 @@ export const skeletonStyles = StyleSheet.create({ }); export const getSkeletonThemeStyles = themedStyleSheetFactory('Skeleton', ({ tokens }: ThemeState) => { - const opaqueHighlight = typeof tokens.color.backgroundNeutralSubtle !== 'string'; + const opaqueHighlight = typeof tokens.color.backgroundNeutralSubtle.rest !== 'string'; return StyleSheet.create({ root: { - backgroundColor: tokens.color.backgroundNeutralSoft, + backgroundColor: tokens.color.backgroundNeutralSoft.rest, borderRadius: tokens.borderRadius.base100, - ...(opaqueHighlight ? { borderColor: tokens.color.strokeNeutralLoud, borderWidth: Number(tokens.strokeWidth.thin) } : {}), + ...(opaqueHighlight ? { borderColor: tokens.color.strokeNeutralLoud.rest, borderWidth: Number(tokens.strokeWidth.thin) } : {}), }, }); }); diff --git a/packages/agentic/components/src/components/skeleton/skeleton.test.tsx b/packages/agentic/components/src/components/skeleton/skeleton.test.tsx index f24ed96c223..e68f17120bc 100644 --- a/packages/agentic/components/src/components/skeleton/skeleton.test.tsx +++ b/packages/agentic/components/src/components/skeleton/skeleton.test.tsx @@ -80,7 +80,7 @@ describe('Skeleton', () => { await component.rerender(); expect(animation.stop).toHaveBeenCalledTimes(1); expect(getRoot(component).children).toHaveLength(0); - expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSoft); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSoft.rest); mockUseReducedMotion.mockReturnValue(false); await component.rerender(); @@ -154,7 +154,7 @@ describe('Skeleton', () => { y2: bandWidth / 2, }); expect(gradient.props.x2 - gradient.props.x1).toBe(gradient.props.y2 - gradient.props.y1); - const color = processColor(defaultFlexTokens.color.backgroundNeutralSubtle); + const color = processColor(defaultFlexTokens.color.backgroundNeutralSubtle.rest); if (typeof color !== 'number') { throw new Error('The test theme must supply a concrete SVG highlight color.'); } @@ -220,8 +220,8 @@ describe('Skeleton', () => { }); expect(component.queryByTestId('skeleton-shimmer', { includeHiddenElements: true })).toBeNull(); - expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSoft); - expect(getRootStyle(component).backgroundColor).not.toBe(defaultFlexTokens.color.backgroundNeutralSubtle); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSoft.rest); + expect(getRootStyle(component).backgroundColor).not.toBe(defaultFlexTokens.color.backgroundNeutralSubtle.rest); }); it('reports unsupported opaque gradient colors and retains a native outlined placeholder', async () => { diff --git a/packages/agentic/components/src/components/skeleton/useSkeleton.ts b/packages/agentic/components/src/components/skeleton/useSkeleton.ts index 149f93f8623..ce86b483e85 100644 --- a/packages/agentic/components/src/components/skeleton/useSkeleton.ts +++ b/packages/agentic/components/src/components/skeleton/useSkeleton.ts @@ -19,7 +19,7 @@ export function useSkeleton_unstable(props: SkeletonProps): SkeletonState { const { onLayout, style: userStyle, ...rest } = props; const themeState = useThemeState(); const gradientId = `skeleton-gradient-${React.useId().replace(/:/g, '')}`; - const highlightColor: unknown = themeState.tokens.color.backgroundNeutralSubtle; + const highlightColor: unknown = themeState.tokens.color.backgroundNeutralSubtle.rest; const shimmerColor = typeof highlightColor === 'string' ? highlightColor : undefined; const [layout, setLayout] = React.useState(createEmptyLayout); const reduceMotion = useReducedMotion() ?? false; diff --git a/packages/agentic/components/src/components/spinner/spinner.test.tsx b/packages/agentic/components/src/components/spinner/spinner.test.tsx index bbba2d1b9b2..8729fb8eda9 100644 --- a/packages/agentic/components/src/components/spinner/spinner.test.tsx +++ b/packages/agentic/components/src/components/spinner/spinner.test.tsx @@ -69,9 +69,9 @@ describe('Spinner', () => { expect(getRootStyle(component)).toMatchObject({ height: 32, width: 32 }); expect(svg.props.width).toBe(32); expect(svg.props.height).toBe(32); - expect(track.props.stroke).toEqual(normalizeColor(tokens.color.strokeNeutralSubtle)); + expect(track.props.stroke).toEqual(normalizeColor(tokens.color.strokeNeutralSubtle.rest)); expect(track.props.strokeWidth).toBe(tokens.strokeWidth.thick); - expect(indicator.props.stroke).toEqual(normalizeColor(tokens.color.strokeNeutralLoud)); + expect(indicator.props.stroke).toEqual(normalizeColor(tokens.color.strokeNeutralLoud.rest)); const circumference = 2 * Math.PI * ((32 - Number(tokens.strokeWidth.thick)) / 2); expect(indicator.props.strokeDasharray).toEqual([circumference / 4, (circumference * 3) / 4]); expect(indicator.props).not.toHaveProperty('pathLength'); diff --git a/packages/agentic/components/src/components/spinner/useSpinner.ts b/packages/agentic/components/src/components/spinner/useSpinner.ts index 72cdb80f58f..2403ed1adaf 100644 --- a/packages/agentic/components/src/components/spinner/useSpinner.ts +++ b/packages/agentic/components/src/components/spinner/useSpinner.ts @@ -19,8 +19,8 @@ export function useSpinner_unstable(props: SpinnerProps): SpinnerState { const themeState = useThemeState(); const { center, diameter, radius, strokeWidth } = getSpinnerMetrics(size, themeState.tokens); - const trackColor = themeState.tokens.color.strokeNeutralSubtle; - const indicatorColor = themeState.tokens.color.strokeNeutralLoud; + const trackColor = themeState.tokens.color.strokeNeutralSubtle.rest; + const indicatorColor = themeState.tokens.color.strokeNeutralLoud.rest; const reduceMotionEnabled = useReducedMotion(); const rotation = useSharedAnimatedLoop({ channel: 'agentic-components:spinner', diff --git a/packages/agentic/components/src/components/switch/switch.styles.ts b/packages/agentic/components/src/components/switch/switch.styles.ts index fa1b979cea3..610fe95e8b2 100644 --- a/packages/agentic/components/src/components/switch/switch.styles.ts +++ b/packages/agentic/components/src/components/switch/switch.styles.ts @@ -129,13 +129,13 @@ const labelStateLevels = [['disabled']] as const; const getLabelStyle = getThemedStateStyleFactory( 'Switch.label', ({ color, fontFamily, fontSize, fontWeight, lineHeight }: FlexTokens): StyleDefinition => ({ - color: color.foregroundNeutralPrimary, + color: color.foregroundNeutralPrimary.rest, fontFamily: fontFamily.functional, fontSize: fontSize.functionalBodyMedium, fontWeight: fontWeight.functionalRegular, lineHeight: lineHeight.functionalBodyMedium, disabled: { - color: color.foregroundNeutralDisabled, + color: color.foregroundNeutralDisabled.rest, }, }), labelStateLevels, diff --git a/packages/agentic/components/src/components/switch/switch.test.tsx b/packages/agentic/components/src/components/switch/switch.test.tsx index c5f365f7713..50da14bf280 100644 --- a/packages/agentic/components/src/components/switch/switch.test.tsx +++ b/packages/agentic/components/src/components/switch/switch.test.tsx @@ -343,27 +343,27 @@ describe('Switch', () => { const baseThumbKey = checked ? 'foregroundNeutralOnloud' : 'foregroundNeutralSecondary'; const expectedTrackBackground = disabled ? checked - ? colors.backgroundNeutralHeavyDisabled - : colors.backgroundNeutralTransparent + ? colors.backgroundNeutralHeavyDisabled.rest + : colors.backgroundNeutralTransparent.rest : pressed - ? colors.pressed[baseBackgroundKey] + ? colors[baseBackgroundKey].pressed : hovered - ? colors.hover[baseBackgroundKey] - : colors[baseBackgroundKey]; + ? colors[baseBackgroundKey].hover + : colors[baseBackgroundKey].rest; const expectedTrackBorder = disabled - ? colors.strokeNeutralDisabled + ? colors.strokeNeutralDisabled.rest : pressed - ? colors.pressed[baseBorderKey] + ? colors[baseBorderKey].pressed : hovered - ? colors.hover[baseBorderKey] - : colors[baseBorderKey]; + ? colors[baseBorderKey].hover + : colors[baseBorderKey].rest; const expectedThumb = disabled - ? colors.foregroundNeutralDisabled + ? colors.foregroundNeutralDisabled.rest : pressed - ? colors.pressed[baseThumbKey] + ? colors[baseThumbKey].pressed : hovered - ? colors.hover[baseThumbKey] - : colors[baseThumbKey]; + ? colors[baseThumbKey].hover + : colors[baseThumbKey].rest; const resolvedTrack = getSwitchTrackColorStyle(state, checked); const resolvedThumb = getSwitchThumbColorStyle(state, checked); diff --git a/packages/agentic/components/src/components/tab/tab.test.tsx b/packages/agentic/components/src/components/tab/tab.test.tsx index f3abf06a1dc..50930d8e7e5 100644 --- a/packages/agentic/components/src/components/tab/tab.test.tsx +++ b/packages/agentic/components/src/components/tab/tab.test.tsx @@ -69,11 +69,7 @@ describe('Tab', () => { } else if (interaction === 'pressed') { await fireEvent(getRoot(component), 'pressIn', {}); } - const expected = disabled - ? colors.foregroundNeutralDisabled - : interaction === 'rest' - ? colors[foreground] - : colors[interaction][foreground]; + const expected = disabled ? colors.foregroundNeutralDisabled.rest : colors[foreground][interaction]; const labels = component.getAllByText('Files', { includeHiddenElements: true }); expect(labels).toHaveLength(2); expect(labels.map((label) => StyleSheet.flatten(label.props.style).color)).toEqual([expected, expected]); @@ -325,7 +321,7 @@ describe('Tab', () => { expect(StyleSheet.flatten(labels[1].parent?.props.style)).toMatchObject({ position: 'absolute', justifyContent: 'center' }); expect(getRootStyle(component)).toMatchObject({ alignItems: 'center', - backgroundColor: tokens.color.backgroundNeutralTransparent, + backgroundColor: tokens.color.backgroundNeutralTransparent.rest, borderRadius: tokens.borderRadius.base300, gap: tokens.spacing.componentBase100, paddingHorizontal: tokens.spacing.componentBase300, @@ -345,11 +341,11 @@ describe('Tab', () => { const root = getRoot(component); const colors = defaultFlexTokens.color; - expect(getRootStyle(component).backgroundColor).toBe(colors.backgroundNeutralHeavy); + expect(getRootStyle(component).backgroundColor).toBe(colors.backgroundNeutralHeavy.rest); await fireEvent(root, 'hoverIn', {}); - expect(getRootStyle(component).backgroundColor).toBe(colors.hover.backgroundNeutralHeavy); + expect(getRootStyle(component).backgroundColor).toBe(colors.backgroundNeutralHeavy.hover); await fireEvent(root, 'pressIn', {}); - expect(getRootStyle(component).backgroundColor).toBe(colors.pressed.backgroundNeutralHeavy); + expect(getRootStyle(component).backgroundColor).toBe(colors.backgroundNeutralHeavy.pressed); await fireEvent.press(root); expect(onHoverIn).toHaveBeenCalledTimes(1); expect(onPress).toHaveBeenCalledTimes(1); @@ -378,7 +374,7 @@ describe('Tab', () => { expect(root).toBeDisabled(); expect(root.props.focusable).toBe(false); expect(root.props.accessibilityState).toEqual({ disabled: true, selected: true }); - expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralHeavyDisabled); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralHeavyDisabled.rest); }); it('renders icon-only tabs with icon swap and accessible labels', async () => { diff --git a/packages/agentic/components/src/components/tag/tag.test.tsx b/packages/agentic/components/src/components/tag/tag.test.tsx index efc6bc4fd92..1fc32ae74dc 100644 --- a/packages/agentic/components/src/components/tag/tag.test.tsx +++ b/packages/agentic/components/src/components/tag/tag.test.tsx @@ -104,7 +104,7 @@ describe('Tag', () => { expect(component.getByText('Engineering')).toBeOnTheScreen(); expect(getRootStyle(component)).toMatchObject({ alignItems: 'center', - backgroundColor: '#fafafa', + backgroundColor: defaultFlexTokens.color.backgroundNeutralSubtle.rest, minHeight: 24, minWidth: 24, }); @@ -136,7 +136,7 @@ describe('Tag', () => { expect(root).toBeDisabled(); expect(root.props.focusable).toBe(false); expect(root.props.accessibilityState).toEqual({ disabled: true }); - expect(getRootStyle(component).backgroundColor).toBe('#f0f0f0'); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color.backgroundNeutralSubtleDisabled.rest); await fireEvent.press(root); expect(onPress).not.toHaveBeenCalled(); }); @@ -192,21 +192,21 @@ describe('Tag', () => { const restForeground = StyleSheet.flatten(text.props.style).color; expect(getRootStyle(component)).toMatchObject({ - backgroundColor: tokens.color.backgroundBrandHeavy, + backgroundColor: tokens.color.backgroundBrandHeavy.rest, }); - expect(restForeground).toBe(tokens.color.foregroundNeutralOnloud); + expect(restForeground).toBe(tokens.color.foregroundNeutralOnloud.rest); await fireEvent(root, 'hoverIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: tokens.color.hover.backgroundBrandHeavy, + backgroundColor: tokens.color.backgroundBrandHeavy.hover, }); - expect(StyleSheet.flatten(text.props.style).color).toBe(tokens.color.foregroundNeutralOnloud); + expect(StyleSheet.flatten(text.props.style).color).toBe(tokens.color.foregroundNeutralOnloud.rest); await fireEvent(root, 'pressIn', {}); expect(getRootStyle(component)).toMatchObject({ - backgroundColor: tokens.color.pressed.backgroundBrandHeavy, + backgroundColor: tokens.color.backgroundBrandHeavy.pressed, }); - expect(StyleSheet.flatten(text.props.style).color).toBe(tokens.color.foregroundNeutralOnloud); + expect(StyleSheet.flatten(text.props.style).color).toBe(tokens.color.foregroundNeutralOnloud.rest); }); it('uses native focus visuals without mounting custom rings', async () => { @@ -220,11 +220,11 @@ describe('Tag', () => { }); it.each([ - ['primary', '#185abd'], - ['secondary', '#fafafa'], - ] as const)('resolves the %s appearance', async (appearance, backgroundColor) => { + ['primary', 'backgroundBrandHeavy'], + ['secondary', 'backgroundNeutralSubtle'], + ] as const)('resolves the %s appearance', async (appearance, backgroundToken) => { const component = await renderTag({ appearance, content: appearance }); - expect(getRootStyle(component).backgroundColor).toBe(backgroundColor); + expect(getRootStyle(component).backgroundColor).toBe(defaultFlexTokens.color[backgroundToken].rest); }); it.each([ @@ -247,8 +247,8 @@ describe('Tag', () => { }); it.each([ - ['rounded', 4], - ['circular', 9999], + ['rounded', defaultFlexTokens.borderRadius.base300], + ['circular', defaultFlexTokens.borderRadius.circular], ] as const)('resolves the %s shape', async (shape, borderRadius) => { const component = await renderTag({ content: shape, shape }); expect(getRootStyle(component).borderRadius).toBe(borderRadius); diff --git a/packages/agentic/components/src/components/text/text.styles.ts b/packages/agentic/components/src/components/text/text.styles.ts index 52458f5197d..e0e7606f782 100644 --- a/packages/agentic/components/src/components/text/text.styles.ts +++ b/packages/agentic/components/src/components/text/text.styles.ts @@ -5,7 +5,7 @@ import { themedStyleSheetFactory } from '@fluentui-react-native/design'; export const getTextStyles = themedStyleSheetFactory('Text.styles', ({ tokens }) => StyleSheet.create({ root: { - color: tokens.color.foregroundNeutralPrimary, + color: tokens.color.foregroundNeutralPrimary.rest, fontFamily: tokens.fontFamily.functional, fontSize: tokens.fontSize.functionalBodyMedium, fontWeight: tokens.fontWeight.functionalRegular, diff --git a/packages/agentic/design/AGENTS.md b/packages/agentic/design/AGENTS.md index d2a90ecdf5d..190617829ce 100644 --- a/packages/agentic/design/AGENTS.md +++ b/packages/agentic/design/AGENTS.md @@ -1,8 +1,8 @@ # Design agent instructions This is the instruction root for `@fluentui-react-native/design` and every descendant. The package owns Fluent UI React -Native's theming contract: theme sources and providers, structured appearance, Flex and legacy tokens, the token -mappings, themed style factories, the runtime color library, and test-only design fixtures. +Native's theming contract: theme sources and providers, ready-made Fluent and Flex themes, structured appearance, Flex +and legacy tokens, the token mappings, themed style factories, the runtime color library, and test-only design fixtures. ## Start here @@ -11,6 +11,7 @@ Read the [user guide](README.md), then select the narrowest topic in the [refere | Task | Read | | ------------------------------------------------------------------------- | ---------------------------------------------- | | Theme authoring, providers, appearance, theme hooks, or legacy projection | [Theming](references/theming.md) | +| Authoring, resolving, or reading Flex colors, or migrating flat colors | [Flex colors](references/flex-colors.md) | | Token sources, Flex token mapping, or the pinned x3 source | [Tokens](references/tokens.md) | | Themed style caches or state and color style factories | [Styling](references/styling.md) | | Runtime color parsing, contrast, or interaction colors | [Color library](references/color-lib.md) | @@ -28,11 +29,17 @@ repository reference `components.agentic.styles-and-tokens`. models, and neither hook constructs the model it does not return. - Key caches by source, revision, and resolved appearance, keep them outside author-owned objects, and give every new `ThemeState` a new style registry. -- Keep the root entry point free of the legacy projection, legacy token payloads, and the color library; legacy and - optional APIs stay behind their subpaths. +- Keep the root entry point free of the legacy projection, deprecated token data, and color compositing; it reaches + the color library's interaction algorithm only through the Flex interaction policy. Legacy and optional APIs stay + behind their subpaths. +- Keep color resolution lazy: resolving, merging, and reading rest never run the interaction algorithm, and a derived + state computes once per resolved color. - Treat `src/tokens/mappings/flex-token-map.yaml` as the canonical token mapping (R-DESIGN-001), and regenerate rather than edit generated token and projection files. - Production code must not depend on the `testing` entry point (R-DESIGN-002). +- Keep the Fluent 2 token JSON loaders and pipeline mappers in `src/deprecated/`. Only tests, other deprecated code, + build scripts, and the existing deprecated consumers may use them, and no other entry point may reach them + (R-DESIGN-003). - Update the owning reference with every behavior or API change, and record unfinished work only in `references/remaining-work.md` (R-PKGDOC-009). diff --git a/packages/agentic/design/README.md b/packages/agentic/design/README.md index 2ac38f9c4cd..904c3605122 100644 --- a/packages/agentic/design/README.md +++ b/packages/agentic/design/README.md @@ -1,8 +1,8 @@ # `@fluentui-react-native/design` -Core design system concepts, utilities, and types for Fluent UI React Native: theme sources and providers, structured -light, dark, high-contrast, and elevated appearance, Flex semantic tokens, themed style factories, and an opt-in runtime -color library. Legacy theme and token packages re-export their APIs from here. +Core design system concepts, utilities, and types for Fluent UI React Native: theme sources and providers, ready-made +Fluent and Flex themes, structured light, dark, high-contrast, and elevated appearance, Flex semantic tokens, themed +style factories, and an opt-in runtime color library. Legacy theme and token packages re-export their APIs from here. ## Quick start @@ -16,7 +16,7 @@ const theme = new FlexThemeReference({ appearance: { colorScheme: 'system' } }); const Title = () => { const { tokens } = useThemeState(); - return Hello; + return Hello; }; export const App = () => ( @@ -29,14 +29,43 @@ export const App = () => ( Existing `ThemeReference` themes and `useTheme` consumers keep working under the same provider; the [theming reference](references/theming.md) explains both authoring models and how they interoperate. +Fluent's own light, dark, and high-contrast themes ship in the `themes` entry point, and `fluentTheme` follows the +system appearance, including high contrast: + +```tsx +import { ThemedRoot } from '@fluentui-react-native/design'; +import { fluentTheme } from '@fluentui-react-native/design/themes'; + +export const App = () => ( + + + </ThemedRoot> +); +``` + +Use `fluentLightTheme` or `fluentDarkTheme` when you need one fixed `Theme` object, or `fluentHcTheme` to always use +high contrast. + +The same entry point ships the x3 Flex defaults as `flexTheme` (cool) and `flexWarmTheme` (warm). Each is a +`FlexThemeDescription` covering light and dark; use one as a `FlexThemeReference` base to start from that palette and +tone: + +```tsx +import { FlexThemeReference } from '@fluentui-react-native/design'; +import { flexWarmTheme } from '@fluentui-react-native/design/themes'; + +const theme = new FlexThemeReference({ base: flexWarmTheme, appearance: { colorScheme: 'system' } }); +``` + ## Documentation | Topic | Covers | | ---------------------------------------------- | --------------------------------------------------------------------- | | [Theming](references/theming.md) | Theme references, providers, appearance, hooks, and legacy projection | +| [Flex colors](references/flex-colors.md) | Authoring and reading Flex colors, and migrating from flat colors | | [Tokens](references/tokens.md) | Token sources and Flex token mapping maintenance | | [Styling](references/styling.md) | Themed style caches and state or color style factories | -| [Color library](references/color-lib.md) | The opt-in `color-lib` runtime color engine | +| [Color library](references/color-lib.md) | Raw `color-lib` algorithms and the Flex interaction-color policy | | [Testing helpers](references/testing.md) | Test-only fixtures and contrast validation | | [Entry points](references/entry-points.md) | Every subpath and the legacy compatibility packages | | [Contributing](references/contributing.md) | Source ownership, generated files, tests, and validation | diff --git a/packages/agentic/design/package.json b/packages/agentic/design/package.json index b815f10ec79..ca549cbb5a4 100644 --- a/packages/agentic/design/package.json +++ b/packages/agentic/design/package.json @@ -39,12 +39,6 @@ "import": "./lib/tokens/global.generated.js", "default": "./src/tokens/global.generated.ts" }, - "./tokens/legacy": { - "types": "./lib/tokens/legacy/index.d.ts", - "react-native": "./src/tokens/legacy/index.ts", - "import": "./lib/tokens/legacy/index.js", - "default": "./src/tokens/legacy/index.ts" - }, "./color-lib": { "types": "./lib/color-lib/index.d.ts", "react-native": "./src/color-lib/index.ts", @@ -58,28 +52,34 @@ "default": "./src/theming/index.ts" }, "./theming/legacy-source": { - "types": "./lib/theming/legacySource.d.ts", - "react-native": "./src/theming/legacySource.ts", - "import": "./lib/theming/legacySource.js", - "default": "./src/theming/legacySource.ts" + "types": "./lib/fluent/legacySource.d.ts", + "react-native": "./src/fluent/legacySource.ts", + "import": "./lib/fluent/legacySource.js", + "default": "./src/fluent/legacySource.ts" }, "./theming/compat": { - "types": "./lib/theming/compat/index.d.ts", - "react-native": "./src/theming/compat/index.ts", - "import": "./lib/theming/compat/index.js", - "default": "./src/theming/compat/index.ts" + "types": "./lib/fluent/compat/index.d.ts", + "react-native": "./src/fluent/compat/index.ts", + "import": "./lib/fluent/compat/index.js", + "default": "./src/fluent/compat/index.ts" }, - "./theming/compat/defaults": { - "types": "./lib/theming/compat/defaultLegacyTheme.d.ts", - "react-native": "./src/theming/compat/defaultLegacyTheme.ts", - "import": "./lib/theming/compat/defaultLegacyTheme.js", - "default": "./src/theming/compat/defaultLegacyTheme.ts" + "./themes": { + "types": "./lib/themes/index.d.ts", + "react-native": "./src/themes/index.ts", + "import": "./lib/themes/index.js", + "default": "./src/themes/index.ts" }, "./testing": { - "types": "./lib/testing/index.d.ts", - "react-native": "./src/testing/index.ts", - "import": "./lib/testing/index.js", - "default": "./src/testing/index.ts" + "types": "./lib/test/index.d.ts", + "react-native": "./src/test/index.ts", + "import": "./lib/test/index.js", + "default": "./src/test/index.ts" + }, + "./deprecated": { + "types": "./lib/deprecated/index.d.ts", + "react-native": "./src/deprecated/index.ts", + "import": "./lib/deprecated/index.js", + "default": "./src/deprecated/index.ts" }, "./styling": { "types": "./lib/styling/index.d.ts", @@ -88,22 +88,23 @@ "default": "./src/styling/index.ts" }, "./styling/stylesheet": { - "types": "./lib/styling/stylesheet/index.d.ts", - "react-native": "./src/styling/stylesheet/index.ts", - "import": "./lib/styling/stylesheet/index.js", - "default": "./src/styling/stylesheet/index.ts" + "types": "./lib/fluent/styling/stylesheet/index.d.ts", + "react-native": "./src/fluent/styling/stylesheet/index.ts", + "import": "./lib/fluent/styling/stylesheet/index.js", + "default": "./src/fluent/styling/stylesheet/index.ts" }, "./styling/tokens": { - "types": "./lib/styling/tokens/index.d.ts", - "react-native": "./src/styling/tokens/index.ts", - "import": "./lib/styling/tokens/index.js", - "default": "./src/styling/tokens/index.ts" + "types": "./lib/fluent/styling/tokens/index.d.ts", + "react-native": "./src/fluent/styling/tokens/index.ts", + "import": "./lib/fluent/styling/tokens/index.js", + "default": "./src/fluent/styling/tokens/index.ts" }, "./package.json": "./package.json" }, "scripts": { "build": "tsc -b", "check:mappings": "node ./scripts/token-mappings/check-mappings.cjs", + "gen:flex-defaults": "node ./scripts/flex-defaults/generate-defaults.mjs", "clean": "fluentui-scripts clean", "format": "fluentui-scripts format", "gen:upstream-drift": "node ./scripts/token-mappings/upstream-drift.cjs", diff --git a/packages/agentic/design/references/README.md b/packages/agentic/design/references/README.md index 360ac884f7d..59ba137b4da 100644 --- a/packages/agentic/design/references/README.md +++ b/packages/agentic/design/references/README.md @@ -9,7 +9,8 @@ owner_paths: | ID | Document | Read when | | ----------------------- | ----------------------------------- | -------------------------------------------------------------------------------- | -| `design.theming` | [Theming](theming.md) | Authoring themes, providers, appearance, theme hooks, or the legacy projection | +| `design.theming` | [Theming](theming.md) | Choosing or authoring themes, providers, appearance, hooks, or legacy projection | +| `design.flex-colors` | [Flex colors](flex-colors.md) | Authoring, resolving, or reading Flex colors, or migrating from flat colors | | `design.tokens` | [Tokens](tokens.md) | Choosing token sources, mapping Flex tokens, or updating mappings and the x3 pin | | `design.styling` | [Styling](styling.md) | Using or changing themed style caches and state or color style factories | | `design.color-lib` | [Color library](color-lib.md) | Parsing, converting, compositing, or generating interaction colors at runtime | diff --git a/packages/agentic/design/references/color-lib.md b/packages/agentic/design/references/color-lib.md index b0e50643923..766f2d72d7e 100644 --- a/packages/agentic/design/references/color-lib.md +++ b/packages/agentic/design/references/color-lib.md @@ -3,18 +3,20 @@ id: design.color-lib kind: instruction-reference owner_paths: - packages/agentic/design/src/color-lib + - packages/agentic/design/src/flex/colors --- # Color library -`@fluentui-react-native/design/color-lib` is the opt-in runtime color engine. -It groups public utilities by responsibility: +`@fluentui-react-native/design/color-lib` exposes the raw color algorithms for +direct use. Theme authors do not need it: resolved Flex colors compute omitted +interaction states on first read (see `flex-colors.md`). It groups public utilities +by responsibility: - `parsing.ts` parses literal React Native colors and formats RGBA values; - `conversion.ts` converts between normalized sRGB and OKLCH; - `compositing.ts` composites alpha colors and calculates WCAG contrast; -- `interaction.ts` generates hover and pressed colors with the default or - Bebop Warm algorithm. +- `interaction.ts` generates one hover or pressed color from a rest color. Native and dynamic color objects cannot be resolved in JavaScript, so parsing and interaction APIs return structured diagnostics instead of fabricated @@ -22,24 +24,36 @@ colors. Direct compositing and contrast operations throw descriptive errors for unsupported values. The algorithms are ported from -[`x3-design/fluent-design@d334acf5cbad813f2b7cd554da942b09a7ff8f10`](https://github.com/x3-design/fluent-design/tree/d334acf5cbad813f2b7cd554da942b09a7ff8f10/dev/web/flex-themes). -The default variant preserves chroma. The `bebopWarm` variant adds the pinned -opacity-aware lightness, chroma, bounds, and translucent reference-backdrop -solve. +[`x3-design/fluent-design@206e890b645fb450ad7c5df2ff981765349a2b58`](https://github.com/x3-design/fluent-design/tree/206e890b645fb450ad7c5df2ff981765349a2b58/dev/web/flex-themes). +The interaction API knows nothing about Flex tokens. Its options select: + +| Option | Values | Effect | +| ------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| `colorTone` | `cool` (default), `warm` | `cool` shifts OKLCH lightness and preserves chroma; `warm` adds the pinned opacity-aware lightness, chroma, and bounds | +| `direction` | `standard` (default), `inverted` | `inverted` shifts lightness opposite the scheme's standard direction | +| `compositing` | `direct` (default), `backdrop` | For `warm` only, `backdrop` composites a translucent color over the scheme's reference backdrop and solves a source at the target alpha | ```ts import { getContrastRatio, getHoverColor } from '@fluentui-react-native/design/color-lib'; -const hover = getHoverColor('#c02e56', 'backgroundDangerLoud', 'light', { - variant: 'bebopWarm', -}); +const hover = getHoverColor('#c02e56', 'light', { colorTone: 'warm', direction: 'inverted' }); const ratio = getContrastRatio('#000000db', '#ffffff'); ``` +Token classification is Flex policy, not part of this library. +`INTERACTIVE_COLOR_TOKENS`, `isInteractiveColorToken`, and +`isInverseInteractionToken` are exported from the package root and owned by +`src/flex/colors/`, which maps each Flex token to a compositing mode and uses +the authored color type as the direction before calling `getInteractionColor`. +The inverse classification sets the type of package defaults and +legacy-projected colors; newly authored colors declare their type. + Keep the public exports narrow and add APIs only for demonstrated production needs. The public interaction surface is intentionally limited to generating one hover or pressed value at a time. Bulk fallback helpers and algorithm constants remain internal until a production consumer needs them. -The submodule is absent from the design root barrel and does not import the -test-only `testing` submodule. +The library imports only its own modules and shared types; it never reaches +Flex, Fluent, or the test-only `testing` submodule. The modern root reaches +`interaction.ts` and its parsing and conversion dependencies through the Flex +interaction policy, but not `compositing.ts`. diff --git a/packages/agentic/design/references/contributing.md b/packages/agentic/design/references/contributing.md index ef353ef42ca..09d0fb9dc47 100644 --- a/packages/agentic/design/references/contributing.md +++ b/packages/agentic/design/references/contributing.md @@ -9,38 +9,69 @@ owner_paths: ## Source map -| Path | Owns | -| ---------------------- | ----------------------------------------------------------------------------------------- | -| `src/theming/` | Theme sources, providers, boundaries, appearance, runtime caches, and legacy theme types | -| `src/theming/compat/` | The Flex-to-legacy projection and complete legacy defaults; never reachable from the root | -| `src/useThemeState.ts` | `useThemeState`, `useThemeAppearance`, and `themedStyleSheetFactory` | -| `src/tokens/` | Flex token types and defaults, the Theme-to-Flex adapter, and generated global tokens | -| `src/tokens/mappings/` | The canonical token map and its generated projections; see `tokens.md` | -| `src/tokens/legacy/` | Legacy alias, shadow, and global token data | -| `src/styling/` | State and color style factories plus the legacy styling subpaths; see `styling.md` | -| `src/color-lib/` | The runtime color engine; see `color-lib.md` | -| `src/testing/` | Test-only fixtures and color validation; see `testing.md` | -| `src/index.ts` | The modern root entry point; see `entry-points.md` for every subpath | - -The package's scripts directory holds `codegen.cts`, which runs before every build, and the token-mapping check and -upstream drift tools described in `tokens.md`. Generated token and projection files are committed; change their inputs -and rebuild rather than editing them. +| Path | Owns | +| ---------------------- | ----------------------------------------------------------------------------------------------------------- | +| `src/types/` | Type-only contracts shared by the Flex and Fluent models, such as appearance | +| `src/theming/` | Shared theme sources, providers, boundaries, appearance, runtime caches, and the `theming` facades | +| `src/flex/` | Flex token and theme state types, `FlexThemeReference`, `useThemeState`, layered shadows, and styles | +| `src/flex/defaults/` | The generated x3 cool and warm defaults and their parity tests; see `tokens.md` | +| `src/flex/adapters/` | The engine-free Theme-to-Flex adapter and its Fluent-native fallbacks | +| `src/flex/colors/` | Authored color normalization, the resolved color envelope, token classification, and the interaction policy | +| `src/fluent/` | Legacy Fluent theme types, `ThemeReference`, `useTheme`, platform utilities, and legacy styling | +| `src/fluent/compat/` | The Flex-to-legacy projection onto the Fluent themes; never reachable from the root | +| `src/themes/` | Ready-made Fluent themes from the generated Fluent 2 tokens and Flex themes from the x3 defaults | +| `src/tokens/` | Generated global tokens and shared token attributes | +| `src/tokens/mappings/` | The canonical token map and its generated projections; see `tokens.md` | +| `src/styling/` | Shared state style factories and the `styling` facade; see `styling.md` | +| `src/color-lib/` | Raw, token-free color algorithms; see `color-lib.md` | +| `src/deprecated/` | Fluent 2 token JSON loaders and pipeline mappers behind `./deprecated`; see `entry-points.md` | +| `src/test/` | Test-only fixtures, compatibility baselines, and color validation; see `testing.md` | +| `src/index.ts` | The modern root entry point; see `entry-points.md` for every subpath | + +Shared modules may import types from either model. At runtime, only the `theming` facade, the `themes` entry, and the +legacy subpaths reach `src/fluent/`; the root and `styling` graphs may reach `src/flex/` but never `src/fluent/`. +Dependencies point one way: `src/flex/colors/` may import `src/color-lib/`, but `src/color-lib/` imports only its own +modules and shared types. Production code never imports `src/test/`, and only `src/deprecated/` imports the Fluent 2 +token JSON packages. Source paths are private: consumers use the package subpaths in `entry-points.md`, never `src/` or +`lib/` paths. + +The package's scripts directory holds `codegen.cts`, which runs before every build, the token-mapping check and upstream +drift tools, and the x3 defaults generator, all described in `tokens.md`. The Fluent token generator applies the +deprecated pipeline mappers from `src/deprecated/` at build time. Generated token, projection, and default files are +committed; change their inputs and regenerate rather than editing them. ## Invariants -- Keep the root import graph modern: it must not reach `useTheme`, `src/theming/compat/`, legacy token payloads, or - `src/color-lib/`. Run the bundle-size scenarios when changing imports between these areas. +- Keep the root import graph modern: it must not reach `useTheme` or anything under `src/fluent/`. It reaches + `color-lib/interaction` (with its parsing and conversion dependencies) only through `src/flex/colors/`, never + `color-lib/compositing`. The legacy `ThemeReference`, `useTheme`, and `ThemeProvider` graphs must not reach + `src/flex/` or `src/color-lib/`, and the Theme-to-Flex adapter in `src/flex/adapters/` must not reach the interaction + policy, the x3 defaults, or `src/color-lib/`. `src/test/compatibility/importBoundaries.test.ts` checks these graphs; + run the bundle-size scenarios too when changing imports between these areas. +- Keep `src/themes/` a consumer of generated tokens. `src/themes/fluent/` may reach `ThemeReference`, the generated + Fluent tokens, and the generated global tokens, but never `src/flex/`, `src/color-lib/`, `useTheme`, + `src/fluent/compat/`, or `src/deprecated/`, and it authors no color value that the generated alias colors lack. + `src/themes/flex/` exposes the x3 default descriptions unchanged and never reaches `src/fluent/` or + `color-lib/compositing`. The tests under `src/themes/`, the import-boundary test, and the `design-fluent-*` and + `design-flex-*` bundle-size scenarios guard this. - Never mutate author-owned theme inputs; caches are external and keyed by source, revision, and resolved appearance. +- Keep color resolution lazy: resolving tokens, reading rest, merging, and copying the color map must not run the + interaction algorithm, and a derived state computes at most once per resolved color. `flex-colors.md` owns the color + contract, and `src/flex/colors/interactionLaziness.test.tsx` guards it. - Keep platform appearance listeners subscription-scoped; nothing subscribes at module import. - Keep the experimental native appearance modules and platform theme packages out of this package's dependencies; platform theme packages inject their sources. - Production code must not import the `testing` entry point (R-DESIGN-002). +- Keep the Fluent 2 token JSON behind `src/deprecated/`: only tests, other deprecated modules, build scripts, and the + existing deprecated consumers may use it, and no other production entry point may reach it (R-DESIGN-003). ## Tests -Jest runs with the macOS platform preset declared in `package.json`. A test named `*.test.<platform>.ts`, such as -`defaultLegacyTheme.test.ios.ts`, runs under that platform, so add one when a platform implementation file changes. +Jest runs with the macOS platform preset declared in `package.json`. A test named `*.test.<platform>.ts` runs under +that platform, so add one when a platform implementation file changes. Iterate with a focused selection, such as `yarn test themeRuntime` or `yarn test --findRelatedTests src/theming/appearance.ts`. +`src/test/compatibility/` holds the public-surface, legacy-runtime, and import-boundary baselines; update their +snapshots only for an intended compatibility change. ## Validation diff --git a/packages/agentic/design/references/entry-points.md b/packages/agentic/design/references/entry-points.md index b408e6c75d7..df9c54bc7fa 100644 --- a/packages/agentic/design/references/entry-points.md +++ b/packages/agentic/design/references/entry-points.md @@ -10,24 +10,53 @@ owner_paths: The package is `sideEffects: false` and exposes explicit subpaths so consumers load only the graph they use. Export public symbols by name from each entry point; do not add barrel re-exports. -| Subpath | Contents | -| --------------------------- | --------------------------------------------------------------------------------------------- | -| `.` (root) | Modern theming (`ThemeProvider`, `ThemedRoot`, `FlexThemeReference`, hooks), Flex token types | -| `./theming` | The complete modern and legacy theming API, including `ThemeReference` and `useTheme` | -| `./theming/legacy-source` | `ThemeReference` without the legacy consumption graph | -| `./theming/compat` | `themeFromFlexTokens` and `getDefaultLegacyTheme` | -| `./theming/compat/defaults` | `getDefaultLegacyTheme` alone, for platform theme packages | -| `./tokens/global` | Generated platform global token constants | -| `./tokens/legacy` | Legacy alias, shadow, and global token data | -| `./color-lib` | The opt-in runtime color engine; see `color-lib.md` | -| `./styling` | State and color style factories; see `styling.md` | -| `./styling/stylesheet` | The legacy `themedStyleSheet` helper | -| `./styling/tokens` | Legacy token-to-style builders | -| `./testing` | Test-only fixtures and validation; see `testing.md` | - -The `apps/bundle-size` `design-*` scenarios guard these boundaries: the modern root and legacy-source scenarios forbid -the compatibility, legacy-token, and (for the root) color-library modules, while the color-library and legacy-projection -scenarios require their expected modules. +| Subpath | Contents | +| ------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `.` (root) | Modern theming (`ThemeProvider`, `ThemedRoot`, `FlexThemeReference`, hooks), Flex token types | +| `./theming` | The complete modern and legacy theming API, including `ThemeReference` and `useTheme` | +| `./theming/legacy-source` | `ThemeReference` without the legacy consumption graph | +| `./theming/compat` | `themeFromFlexTokens`, which projects Flex tokens onto the Fluent theme for the appearance | +| `./themes` | Ready-made themes: `fluentLightTheme`, `fluentDarkTheme`, `fluentHcTheme`, `fluentTheme`, `flexTheme`, and `flexWarmTheme` | +| `./tokens/global` | Generated platform global token constants | +| `./color-lib` | Raw color parsing, conversion, compositing, and interaction algorithms; see `color-lib.md` | +| `./styling` | State and color style factories; see `styling.md` | +| `./styling/stylesheet` | The legacy `themedStyleSheet` helper | +| `./styling/tokens` | Legacy token-to-style builders | +| `./testing` | Test-only fixtures and validation; see `testing.md` | +| `./deprecated` | Fluent 2 token JSON loaders and pipeline mappers, restricted to existing consumers; see [below](#deprecated-entry-point) | + +The `apps/bundle-size` `design-*` scenarios guard these boundaries. Input patterns check the import graph and output +patterns check the modules a tree-shaken bundle retains. Every design scenario except the color-library one forbids +`src/deprecated/` from the import graph. The modern root and legacy-source scenarios forbid the compatibility modules +and `color-lib/compositing`. The modern root scenarios and the legacy-source scenario, which pairs a legacy +`ThemeReference` with `useThemeState`, require the retained Flex interaction policy and `color-lib/interaction`; the +legacy-source scenario also forbids a retained `FlexThemeReference`. Only the legacy theme scenario forbids any retained +`color-lib/` or `flex/` module. The Fluent theme scenarios forbid `useTheme` and the compatibility modules from the +import graph and any retained `flex/`, `color-lib/`, or Flex theme module, and a bundle that imports only +`fluentLightTheme` retains no other theme and no `ThemeReference`, while one that imports only `fluentHcTheme` retains +only the high-contrast themes. The Flex theme scenarios require the x3 defaults and forbid `fluent/` and +`color-lib/compositing`. The color-library scenario requires its algorithms, and the legacy-projection scenario requires +the projection, the Fluent theme selection, and the generated Fluent tokens it projects onto. Every scenario also +requires a module it is expected to load, so a moved file cannot make a forbidden pattern pass vacuously. + +The package specifiers above are the supported import surface. Source and build paths such as `src/fluent/...` or +`lib/...` are private implementation details that may move without a breaking change. + +## Deprecated entry point + +`./deprecated` is built from `src/deprecated/`, the only design source that imports the Fluent 2 token JSON from the +`@fluentui-react-native/design-tokens-*` packages. It exports the token loaders (`getAliasTokens`, `getShadowTokens`, +`globalTokens`, and `hcAliasTokens`) and the pipeline mappers that turn that JSON into theme values +(`mapPipelineToTheme`, `mapFontPipelineToTheme`, and `mapPipelineToShadow`). It has no replacement API: new code uses +the ready-made themes from `./themes`, whose generated tokens the build derives from the same JSON with these mappers. + +- **R-DESIGN-003:** Only tests, other `src/deprecated/` modules, and build scripts may use `src/deprecated/`, and only + the existing deprecated consumers may import `@fluentui-react-native/design/deprecated`: the `theme-tokens` and + `theming-utils` shims, the Android, Apple, and Win32 theme packages, and the private tester app. No other design + source imports a `design-tokens-*` package, and no other production entry point reaches `src/deprecated/`. + +`src/test/compatibility/importBoundaries.test.ts` enforces the rule inside this package, and the bundle-size scenarios +forbid `src/deprecated/` from the other design entry points. `remaining-work.md` tracks retiring the entry point. ## Compatibility packages @@ -35,16 +64,16 @@ scenarios require their expected modules. The legacy packages listed here are compatibility entry points and contain only explicit named re-exports. -| Legacy package | Exported symbols | Owning design entry point | Definition | -| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -| `@fluentui-react-native/theme` | `ThemeProvider`, `ThemeProviderProps`, `ThemeReference`, `OnThemeChange`, `ThemeRecipe`, `ThemeTransform` | `@fluentui-react-native/design/theming` | `src/theming/ThemeProvider.tsx`, `src/theming/themeReference.ts` | -| `@fluentui-react-native/theme-types` | `AliasColorTokens`, `AppearanceOptions`, `BaseShadowAliasTokens`, `Color`, `FabricWebPalette`, `FontDynamicTypeRamp`, `FontFamilies`, `FontFamily`, `FontFamilyValue`, `FontSize`, `FontSizeValuePoints`, `FontSizes`, `FontWeight`, `FontWeightValue`, `FontWeights`, `OfficePalette`, `Palette`, `PaletteBackgroundColors`, `PaletteTextColors`, `PartialPalette`, `PartialShadowDefinition`, `PartialTheme`, `PartialTypography`, `ShadowToken`, `ShadowValue`, `Spacing`, `TextStyling`, `Theme`, `ThemeColorDefinition`, `ThemeContext`, `ThemeOptions`, `ThemeShadowDefinition`, `Typography`, `Variant`, `VariantValue`, `Variants`, `useTheme` | `@fluentui-react-native/design/theming` | `src/theming/context.ts`, `src/theming/types/` | -| `@fluentui-react-native/theming-utils` | `getCurrentAppearance`, `isHighContrast`, `mapFontPipelineToTheme`, `mapPipelineToShadow`, `mapPipelineToTheme`, `setIsHighContrast` | `@fluentui-react-native/design/theming` | `src/theming/platformUtils.*.ts`, `src/theming/mapPipelineToShadow.ts`, `src/theming/mapPipelineToTheme*.ts` | -| `@fluentui-react-native/theme-tokens` | `getAliasTokens`, `getShadowTokens`, `globalTokens` | `@fluentui-react-native/design/tokens/legacy` | `src/tokens/legacy/` | -| `@fluentui-react-native/tokens` | `backgroundColorTokens`, `borderStyles`, `borderTokens`, `colorTokens`, `fontStyles`, `foregroundColorTokens`, `getPaletteFromTheme`, `layoutStyles`, `layoutTokens`, `shadowStyles`, `shadowTokens`, `styleFunction`, `textTokens`, `tokenBuilder`, `FontDecorationTokens`, `FontStyleTokens`, `FontTokens`, `FontVariantTokens`, `IBackgroundColorTokens`, `IBorderTokens`, `IColorTokens`, `IForegroundColorTokens`, `IShadowTokens`, `LayoutTokens`, `LookupThemePart`, `OperationSet`, `StyleFactoryFunction`, `StyleFactoryFunctionRaw`, `StyleFactoryOperation`, `TokenBuilder` | `@fluentui-react-native/design/styling/tokens` | `src/styling/tokens/` | -| `@fluentui-react-native/themed-stylesheet` | `NamedStyles`, `themedStyleSheet` | `@fluentui-react-native/design/styling/stylesheet` | `src/styling/stylesheet/themedStyleSheet.ts` | - -The three optional entry points (`tokens/legacy`, `styling/tokens`, and -`styling/stylesheet`) are intentionally absent from the design root barrel. -This keeps legacy token data and styling infrastructure out of consumers that +| Legacy package | Exported symbols | Owning design entry point | Definition | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| `@fluentui-react-native/theme` | `ThemeProvider`, `ThemeProviderProps`, `ThemeReference`, `OnThemeChange`, `ThemeRecipe`, `ThemeTransform` | `@fluentui-react-native/design/theming` | `src/theming/ThemeProvider.tsx`, `src/fluent/themeReference.ts` | +| `@fluentui-react-native/theme-types` | `AliasColorTokens`, `AppearanceOptions`, `BaseShadowAliasTokens`, `Color`, `FabricWebPalette`, `FontDynamicTypeRamp`, `FontFamilies`, `FontFamily`, `FontFamilyValue`, `FontSize`, `FontSizeValuePoints`, `FontSizes`, `FontWeight`, `FontWeightValue`, `FontWeights`, `OfficePalette`, `Palette`, `PaletteBackgroundColors`, `PaletteTextColors`, `PartialPalette`, `PartialShadowDefinition`, `PartialTheme`, `PartialTypography`, `ShadowToken`, `ShadowValue`, `Spacing`, `TextStyling`, `Theme`, `ThemeColorDefinition`, `ThemeContext`, `ThemeOptions`, `ThemeShadowDefinition`, `Typography`, `Variant`, `VariantValue`, `Variants`, `useTheme` | `@fluentui-react-native/design/theming` | `src/theming/context.ts`, `src/fluent/types/` | +| `@fluentui-react-native/theming-utils` | `getCurrentAppearance`, `isHighContrast`, `setIsHighContrast`; the deprecated `mapFontPipelineToTheme`, `mapPipelineToShadow`, and `mapPipelineToTheme` | `@fluentui-react-native/design/theming` and `@fluentui-react-native/design/deprecated` | `src/fluent/platformUtils.*.ts`, `src/deprecated/mapPipelineToShadow.ts`, `src/deprecated/mapPipelineToTheme*.ts` | +| `@fluentui-react-native/theme-tokens` | `getAliasTokens`, `getShadowTokens`, `globalTokens`, `hcAliasTokens` (deprecated) | `@fluentui-react-native/design/deprecated` | `src/deprecated/` | +| `@fluentui-react-native/tokens` | `backgroundColorTokens`, `borderStyles`, `borderTokens`, `colorTokens`, `fontStyles`, `foregroundColorTokens`, `getPaletteFromTheme`, `layoutStyles`, `layoutTokens`, `shadowStyles`, `shadowTokens`, `styleFunction`, `textTokens`, `tokenBuilder`, `FontDecorationTokens`, `FontStyleTokens`, `FontTokens`, `FontVariantTokens`, `IBackgroundColorTokens`, `IBorderTokens`, `IColorTokens`, `IForegroundColorTokens`, `IShadowTokens`, `LayoutTokens`, `LookupThemePart`, `OperationSet`, `StyleFactoryFunction`, `StyleFactoryFunctionRaw`, `StyleFactoryOperation`, `TokenBuilder` | `@fluentui-react-native/design/styling/tokens` | `src/fluent/styling/tokens/` | +| `@fluentui-react-native/themed-stylesheet` | `NamedStyles`, `themedStyleSheet` | `@fluentui-react-native/design/styling/stylesheet` | `src/fluent/styling/stylesheet/themedStyleSheet.ts` | + +The optional `deprecated`, `styling/tokens`, and `styling/stylesheet` entry +points are intentionally absent from the design root barrel. This keeps +deprecated token data and legacy styling infrastructure out of consumers that only use the current design APIs. diff --git a/packages/agentic/design/references/flex-colors.md b/packages/agentic/design/references/flex-colors.md new file mode 100644 index 00000000000..b688db90320 --- /dev/null +++ b/packages/agentic/design/references/flex-colors.md @@ -0,0 +1,133 @@ +--- +id: design.flex-colors +kind: instruction-reference +owner_paths: + - packages/agentic/design/src/flex/colors + - packages/agentic/design/src/flex/flexTokenDescription.ts + - packages/agentic/design/src/flex/tokens.types.ts +--- + +# Flex colors + +Every Flex semantic color is authored once and resolved per appearance into one envelope with its interaction states. +This reference covers the authored and resolved contracts, resolution and merge rules, and migration from the earlier +flat colors with separate `color.hover` and `color.pressed` maps. + +## Resolved colors + +`useThemeState().tokens.color.<name>` is a frozen `InteractiveColor` with `rest`, `hover`, and `pressed`. Every semantic +color uses the same envelope, including roles whose states equal rest. + +```ts +const { backgroundBrandLoud } = tokens.color; +const rest = backgroundBrandLoud.rest; +const hover = backgroundBrandLoud.hover; +``` + +An omitted state is computed on its first read and memoized for that resolved appearance. Read only the states a style +path needs; destructuring `hover` and `pressed` reads both. Resolved tokens are appearance-bound outputs: never author +them back into a theme. + +## Authored colors + +A `FlexColorInput` is one of: + +| Input | Meaning | +| ----------------------------------- | ----------------------------------------------------------- | +| A `ColorValue` | Rest for every color scheme | +| A `[light, dark]` tuple | Rest selected by the resolved `colorScheme` | +| `{ rest, hover?, pressed?, type? }` | Rest plus explicit states; each entry is a value or a tuple | + +`flexColor(value, type?)` normalizes an input into a new frozen description and never mutates its argument. The second +argument sets the interaction type unless `value.type` is supplied. `selectColorEntry(entry, appearance)` reads the +scheme-specific value from an authored entry. + +```ts +import { flexColor } from '@fluentui-react-native/design'; + +// The common case: rest colors only, derived states. +const brand = flexColor(['#345678', '#abcdef'], 'inverted'); + +// Explicit state exceptions. +const accent = flexColor({ rest: ['#345678', '#abcdef'], pressed: ['#123456', '#cdef01'], type: 'inverted' }); +``` + +| Type | Omitted interactive states | +| ---------- | --------------------------------------------------------------------------------------------------------------- | +| `standard` | Derived in the scheme's standard lightness direction; the type of a plain value | +| `inverted` | Derived in the opposite direction, as the default heavy, loud, and on-loud roles do | +| `fixed` | Not derived; outside high contrast, an interactive token with a mappable rest must author `hover` and `pressed` | + +## Resolution + +For each color and resolved appearance: + +1. A tuple selects light or dark. +2. An explicit state wins. +3. An omitted state of a token outside `INTERACTIVE_COLOR_TOKENS` (see `color-lib.md`) is rest. +4. In high contrast, an omitted state is rest, including for a `fixed` color. +5. A `fixed` interactive color throws while resolving if a state is omitted and JavaScript can map rest; with a rest it + cannot map, the omitted state is rest. +6. Otherwise the omitted state is derived from rest on first read with the `color-lib` interaction algorithm, using the + color's type as the direction, the appearance's `colorTone`, and the token's compositing mode. No import, provider + setting, or registration is required. When JavaScript cannot map rest, such as a `PlatformColor`, the state is the + identical rest value; unexpected algorithm failures still throw. + +The default descriptions are rest-first: they author a hover or pressed state only where the policy cannot reproduce the +x3 source (see `tokens.md`), so their other states are derived like any authored color. The Theme-to-Flex adapter never +derives states: its omitted states equal rest, so legacy-projected values are unchanged. + +## Merging and recipes + +`FlexThemeReference` merges the package defaults, its `base`, and its recipes in order; a `FlexThemeDescription` base +replaces the defaults instead (`theming.md`). A color override replaces the +previous color atomically, including its explicit states and type, so a stale state never survives a new rest. Shadow +overrides also replace the whole layered shadow. An `undefined` color or shadow is not an override. Other token groups +keep deep-merge semantics. + +Because replacement is atomic, a plain override uses the `standard` type even where the default color is inverted. +Use `flexColor(value, 'inverted')` when overriding a heavy, loud, or on-loud role that should keep inverted interaction +feedback. + +A `base` function receives the resolved appearance. A recipe function receives the accumulated authored description and +the resolved appearance, and returns overrides. Description colors are authored entries, not resolved envelopes. +Reusing a whole description keeps its type and explicit states; a value read with `selectColorEntry` is a plain color, +so restate the type when it overrides an inverted role: + +```ts +import { FlexThemeReference, flexColor, selectColorEntry } from '@fluentui-react-native/design'; + +const theme = new FlexThemeReference({}, (description, appearance) => ({ + color: { + strokeBrandLoud: description.color.backgroundBrandLoud, + backgroundBrandHeavy: flexColor(selectColorEntry(description.color.foregroundBrandPrimary.rest, appearance), 'inverted'), + }, +})); +``` + +Authoring rejects resolved `InteractiveColor` values, tuples without exactly two entries, unknown option keys, nested +options, and the removed `color.hover` and `color.pressed` maps. + +## Migrating from flat colors + +| Before | After | +| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `tokens.color.backgroundBrandLoud` | `tokens.color.backgroundBrandLoud.rest` | +| `tokens.color.hover.backgroundBrandLoud ?? tokens.color.backgroundBrandLoud` | `tokens.color.backgroundBrandLoud.hover` | +| `{ color: { x: rest, hover: { x: hover } } }` | `{ color: { x: { rest, hover } } }` | +| `{ color: { backgroundBrandLoud: '#…' } }` (implicitly inverted) | `{ color: { backgroundBrandLoud: flexColor('#…', 'inverted') } }` | +| A recipe branching on `appearance.colorScheme` for a color | A `[light, dark]` tuple | +| `(parent, appearance) => …parent.color.x…` | `(description) => …description.color.x…`, or `flexColor(selectColorEntry(description.color.x.rest, appearance), type)` for a selected value | +| `InteractiveColorOverrides` | `InteractiveColorOptions` or `PartialSemanticColors` | + +Other surfaces: + +- Style factories keep their key-based definitions. `colorStyleDef` and `getThemedColorStyleFactory` read + `.hover` and `.pressed` for inherited semantic keys; see `styling.md`. +- A custom `FlexThemeSource` must return resolved envelopes from `resolveFlexTokens`. Delegate to a + `FlexThemeReference` to get atomic merging and automatic states. +- `legacyFallback` is unchanged and still supplies values Flex cannot represent to the projected legacy `Theme`. +- `themeFromFlexTokens` accepts resolved tokens and still accepts the deprecated `FlatFlexTokens` shape. +- `validateContrastPairs` audits resolved colors at rest; pass a flat map of state values to audit hover or pressed. +- Legacy `ThemeReference` themes, `ThemeProvider`, and `useTheme` are unchanged. The legacy default theme is removed: + `themeFromFlexTokens` fills values Flex cannot represent from the generated Fluent theme. diff --git a/packages/agentic/design/references/remaining-work.md b/packages/agentic/design/references/remaining-work.md index 544a702c50f..ac05b1c6ca7 100644 --- a/packages/agentic/design/references/remaining-work.md +++ b/packages/agentic/design/references/remaining-work.md @@ -37,10 +37,31 @@ behavior is documented in `theming.md`, `tokens.md`, and `entry-points.md`. - **Issue:** [#4263](https://github.com/microsoft/fluentui-react-native/issues/4263) - **Outcome:** default Flex tokens vary by resolved color scheme, contrast, and interface level. -- **Current state:** `FlexThemeReference` resolves every appearance from the same `defaultFlexTokens`. Authors must - supply appearance-aware bases or recipes for dark or high-contrast values. -- **Done when:** generated defaults exist for each supported appearance and `FlexThemeReference` selects them by the - resolved appearance without changing its laziness or identity guarantees. +- **Current state:** the generated x3 defaults vary by color scheme and color tone. The pinned x3 sources define no + high-contrast or elevated values, so those appearances use the light or dark defaults, and high contrast only + suppresses derived interaction states. Authors must supply appearance-aware bases or recipes for high-contrast or + elevated values. +- **Done when:** x3 publishes, or the owner approves, high-contrast and elevated values, the defaults generator emits + them, and `FlexThemeReference` selects them by the resolved appearance without changing its laziness or identity + guarantees. + +## Fixed interactive color derivation + +- **Outcome:** an omitted state of a `fixed` interactive color with a mappable rest derives from an authoritative, + scheme-independent rule. +- **Current state:** the pinned x3 sources define no such rule, so resolving that state throws until the author + supplies `hover` and `pressed` (see `flex-colors.md`). No default color uses the `fixed` type. +- **Done when:** x3 publishes, or the owner approves, the rule, the interaction policy implements it with conformance + fixtures, and `fixed` colors no longer require explicit states. + +## Native layered shadows and motion + +- **Outcome:** components render Flex layered shadows and motion tokens with qualified native behavior. +- **Current state:** `tokens.shadow` and `tokens.motion` carry the pinned x3 values (see `tokens.md`), but no agentic + component reads them, and no native story qualifies how each platform and renderer draws every shadow layer or + applies the durations and easing curves. +- **Done when:** the first consuming component defines that behavior for each supported platform and renderer, and + native stories qualify it in light and dark appearances. ## Flex authoring migration guide @@ -50,10 +71,28 @@ behavior is documented in `theming.md`, `tokens.md`, and `entry-points.md`. repository's user documentation covers `ThemedRoot` but still teaches custom themes only through `ThemeReference`. - **Done when:** the user documentation includes the migration example and links to this package's theming reference. +## Fluent elevated themes + +- **Outcome:** `fluentTheme` selects distinct themes for elevated appearances. +- **Current state:** `themes` provides light, dark, and high-contrast Fluent themes. The generated Fluent tokens already + supply `lightElevated` and `darkElevated` color and shadow sets (`tokens.md`), but `fluentTheme` and the Flex-to-legacy + projection, which share `selectFluentTheme`, resolve elevated requests by color scheme alone. +- **Done when:** the owner approves how elevated appearances map to those sets, and `selectFluentTheme` selects the + matching theme by the resolved interface level. + +## Retire the deprecated entry point + +- **Outcome:** no package reads the Fluent 2 token JSON at runtime, and `@fluentui-react-native/design/deprecated`, + `src/deprecated/`, and the runtime `design-tokens-*` dependencies are removed. +- **Current state:** the Android, Apple, and Win32 theme packages build their legacy themes from the JSON through + `./deprecated`, the `theme-tokens` and `theming-utils` shims re-export it, and the private tester app reads the + `globalTokens` palettes (R-DESIGN-003). The generated Fluent sets already provide each platform's alias colors, + shadows, and font aliases (`tokens.md`), and the build still derives them from the JSON with the deprecated mappers. +- **Done when:** the platform themes and the tester read the generated Fluent sets, generated global tokens, or Flex + tokens instead, the shims drop the deprecated re-exports in a release that permits the break, and the build reads the + JSON without runtime modules. + ## Dependent work owned by other packages -- `@fluentui-react-native/storybook-desktop-runtime` still offers fixed light, dark, and high-contrast legacy themes; - [#4269](https://github.com/microsoft/fluentui-react-native/issues/4269) moves Storybook to the unified provider with - structured appearance controls. - `@fluentui-react-native/apple-theme` still authors a legacy `Theme`; [#4261](https://github.com/microsoft/fluentui-react-native/issues/4261) re-authors it on Flex tokens. diff --git a/packages/agentic/design/references/styling.md b/packages/agentic/design/references/styling.md index dd88ddd8fd7..a8f68b038b9 100644 --- a/packages/agentic/design/references/styling.md +++ b/packages/agentic/design/references/styling.md @@ -3,7 +3,8 @@ id: design.styling kind: instruction-reference owner_paths: - packages/agentic/design/src/styling - - packages/agentic/design/src/useThemeState.ts + - packages/agentic/design/src/flex/styling + - packages/agentic/design/src/flex/useThemeState.ts --- # Styling @@ -46,8 +47,8 @@ states come from deeper levels. `getActiveState` picks the first active state in `interactiveStatePriority` is `disabled`, `pressed`, then `hovered`. `getThemedColorStyleFactory` and `colorStyleDef` accept semantic color keys in place of colors. They synthesize hovered -and pressed nodes wherever those states are declared, resolving `tokens.color.hover` and `tokens.color.pressed` for the -inherited key. An interaction branch may still select a different semantic key explicitly. +and pressed nodes wherever those states are declared, reading the inherited key's resolved `hover` or `pressed` state +only when that node is built. An interaction branch may still select a different semantic key explicitly. ## Value helpers diff --git a/packages/agentic/design/references/testing.md b/packages/agentic/design/references/testing.md index 21bfcb8fc2d..9f06ce82c3f 100644 --- a/packages/agentic/design/references/testing.md +++ b/packages/agentic/design/references/testing.md @@ -2,7 +2,7 @@ id: design.testing kind: instruction-reference owner_paths: - - packages/agentic/design/src/testing + - packages/agentic/design/src/test --- # Testing helpers @@ -12,7 +12,7 @@ owner_paths: `@fluentui-react-native/design/testing` is the test-only entry point for fixtures and validation helpers associated with the design package. It exports: -- the generated `defaultFlexTokens` fixture and default resolved appearance; +- the x3 cool `defaultFlexTokens` and the default resolved appearance; - `mockTheme` for tests that need a legacy-compatible theme; - WCAG thresholds and canonical semantic color pairings; - structured contrast audits and filters for failed or unresolvable pairs. @@ -21,9 +21,11 @@ The color validation helpers build on `color-lib`, but are not designed for component render paths or other production runtime code. Production consumers that need parsing, conversion, interaction generation, compositing, or a direct contrast ratio should import `@fluentui-react-native/design/color-lib`. -Color validation policy, semantic pairings, audit helpers, and conformance -fixtures belong under `src/testing`; export them from the `testing` entry point -when they are generally useful to tests. Testing-only validation is +Color validation policy, semantic pairings, and audit helpers belong under +`src/test/color-validation`, and conformance fixtures under `src/test/fixtures`; +export them from the `testing` entry point when they are generally useful to +tests. `src/test/compatibility` holds the public-surface, legacy-runtime, and +import-boundary baselines. Testing-only validation is intentionally omitted from production bundle-size scenarios. ```ts @@ -33,5 +35,15 @@ const failures = getContrastFailures(validateContrastPairs(defaultFlexTokens.col ``` The package's internal validation suite audits rest, hover, and pressed values -for both default and Bebop Warm interaction variants. Its pinned conformance -fixtures are implementation evidence rather than public testing exports. +for both the cool and warm color tones. Its pinned conformance fixtures and the +bulk `getInteractionColorOverrides` helper under `src/test/fixtures` are +implementation evidence rather than public testing exports. +`x3InteractionConformance` and `x3WarmInteractionConformance` record each +tone's x3 rest, hover, and pressed values, and `x3CoolExplicitStates` records +the cool states the interaction policy does not reproduce, with the reason each +default authors them. The x3 default parity tests under `src/flex/defaults` are +described in `tokens.md`. + +`validateContrastPairs` accepts a flat map of color values or resolved +`InteractiveColor` envelopes, which it audits at rest. To audit an interaction +state, pass a flat map of that state's values. diff --git a/packages/agentic/design/references/theming.md b/packages/agentic/design/references/theming.md index 684d79fecfb..f38db516f89 100644 --- a/packages/agentic/design/references/theming.md +++ b/packages/agentic/design/references/theming.md @@ -3,7 +3,12 @@ id: design.theming kind: instruction-reference owner_paths: - packages/agentic/design/src/theming - - packages/agentic/design/src/useThemeState.ts + - packages/agentic/design/src/types + - packages/agentic/design/src/flex/flexThemeReference.ts + - packages/agentic/design/src/flex/themeState.types.ts + - packages/agentic/design/src/flex/useThemeState.ts + - packages/agentic/design/src/fluent + - packages/agentic/design/src/themes --- # Theming @@ -20,16 +25,30 @@ both models. Modern consumers read Flex tokens through `useThemeState`; legacy c | `ThemeReference` | `legacy` | One legacy `Theme` per resolved appearance | `@fluentui-react-native/design/theming` or `@fluentui-react-native/design/theming/legacy-source` | `FlexThemeReference` accepts `base`, `appearance`, `fallbackAppearance`, `appearanceSource`, and `legacyFallback` -options followed by recipes. It resolves the design package's default Flex tokens, then the base input, then recipes in -declaration order. A base or recipe may be a function of the resolved appearance. `PartialFlexTokens` is shape-aware so -opaque React Native colors stay leaves. +options followed by recipes. It merges the design package's x3 default Flex token description for the resolved +`colorTone`, then the base input, then recipes in declaration order, and resolves the result once per appearance. A base +may be a function of the resolved appearance, which always has a concrete `colorTone`. A recipe receives the accumulated +authored description and the resolved appearance. `PartialFlexTokens` is shape-aware so opaque React Native colors stay +leaves. `tokens.md` describes the defaults. + +A base may instead be a `FlexThemeDescription`: a complete `FlexTokenDescription` in `tokens` and an optional +`colorTone`. Its tokens replace the package defaults for every appearance, and its tone becomes the reference's default +`appearance.colorTone` when the `appearance` option sets none. A provider's `appearance` request still wins, and it +changes only the interaction algorithm, not the description's palette. The Flex themes below are descriptions. + +Each color is authored as a value, a `[light, dark]` tuple, or `flexColor` options with explicit states and an +interaction type, and replaces the previous color atomically. Each resolved color is an `InteractiveColor` with `rest`, +`hover`, and `pressed`. Omitted states of interactive tokens are derived from rest with the `color-lib` interaction +algorithm on first read; no import, provider setting, or registration is required. `flex-colors.md` owns the authoring, +resolution, and merge rules and the migration from flat colors. ```ts import { FlexThemeReference } from '@fluentui-react-native/design'; -const theme = new FlexThemeReference({ appearance: { colorScheme: 'system' } }, (_parent, appearance) => ({ - color: { surfaceNeutralNear: appearance.colorScheme === 'dark' ? '#1f1f1f' : '#ffffff' }, -})); +const theme = new FlexThemeReference({ + appearance: { colorScheme: 'system' }, + base: { color: { surfaceNeutralNear: ['#ffffff', '#1f1f1f'] } }, +}); ``` `ThemeReference` keeps its constructor, one-argument recipes, `theme` accessor, `update`, `invalidate`, and listeners. @@ -87,9 +106,14 @@ back to an appearance reuses its entry within a revision, and a revision change ## Appearance A request has `colorScheme` (`light`, `dark`, or `system`), `contrast` (`standard`, `highContrast`, or `system`), and -`interfaceLevel` (`base`, `elevated`, or `system`). The resolved appearance is always concrete. A -`ThemeAppearanceSource` provides a stable `getSnapshot()` and a `subscribe()` that installs native listeners only while -subscribed; create one with `createThemeAppearanceSource`. +`interfaceLevel` (`base`, `elevated`, or `system`), plus an optional `colorTone` (`cool` or `warm`). The resolved +appearance is always concrete. `colorTone` is a design choice rather than a platform setting, so appearance sources +never supply it: it resolves from the provider or root request, then the source's `appearance` option, then the fallback +appearance, then `cool`. A nested `ThemedRoot` inherits it with the other requested axes, and a raw legacy +`ThemeContext` boundary resolves to `cool`. Caches key a warm appearance separately; cool keeps the existing +`colorScheme|contrast|interfaceLevel` key, and the Fluent theme that backs the legacy projection does not vary by tone. +A `ThemeAppearanceSource` provides a stable `getSnapshot()` and a `subscribe()` that installs native listeners only +while subscribed; create one with `createThemeAppearanceSource`. | Platform | Platform appearance source | | -------------- | --------------------------------------------------------------------------------------------- | @@ -103,19 +127,80 @@ subscribed; create one with `createThemeAppearanceSource`. including `darkElevated`, `highContrast`, and `dynamic`. `getCurrentAppearance`, `isHighContrast`, and `setIsHighContrast` remain for existing callers. +## Fluent themes + +The `themes` entry point provides legacy `Theme` objects authored from the generated Fluent 2 tokens (`tokens.md`): + +| Export | Kind | Contents | +| ------------------ | ---------------- | ---------------------------------------------------------------------- | +| `fluentLightTheme` | `Theme` | The light theme | +| `fluentDarkTheme` | `Theme` | The dark theme | +| `fluentHcTheme` | `ThemeReference` | The high-contrast light and dark themes, chosen by the resolved scheme | +| `fluentTheme` | `ThemeReference` | Every Fluent theme, chosen by the resolved contrast and color scheme | + +Each theme carries every platform alias color unchanged, plus the legacy palette keys (`bodyText`, `buttonBackground`, +and so on) that existing components still read. `src/themes/fluent/legacyPalette.ts` points each legacy key at the alias +color that plays the same role, so the palette adds no color values of its own, and its type is complete: a legacy key +without a mapping fails to compile. Shadows and font variants are the generated Fluent shadows and font aliases; font +families, sizes, weights, and spacing come from the global tokens. All of these are generated per platform, so each +platform's theme carries that platform's values. Fluent 2 defines no serif or cursive family, so those slots use the base +family. The themes carry no component token overrides. + +`fluentTheme` requests `system` for every appearance axis, so a `ThemeProvider` or `ThemedRoot` follows the platform +appearance source and re-resolves when the system changes; pass `appearance` to pin a color scheme or contrast. High +contrast selects the high-contrast theme for the color scheme. `fluentHcTheme` always requests high contrast and follows +the system color scheme. Interface level does not select separate themes yet: elevated requests resolve by color scheme +(`remaining-work.md`). Import `fluentLightTheme` or `fluentDarkTheme` alone to keep the other themes and `ThemeReference` +out of a bundle, or use one as the base of your own `ThemeReference` to extend it. Flex consumers read these themes +through `useThemeState`, which adapts their alias colors like any legacy source. + +```tsx +import { ThemedRoot } from '@fluentui-react-native/design'; +import { fluentTheme } from '@fluentui-react-native/design/themes'; + +const App = () => <ThemedRoot theme={fluentTheme}>{/* scene */}</ThemedRoot>; +``` + +## Flex themes + +The `themes` entry point also provides the x3 Flex defaults (`tokens.md`) as `FlexThemeDescription` data: + +| Export | Kind | Contents | +| --------------- | ---------------------- | -------------------------------------------------- | +| `flexTheme` | `FlexThemeDescription` | The cool light and dark defaults, with tone `cool` | +| `flexWarmTheme` | `FlexThemeDescription` | The warm light and dark defaults, with tone `warm` | + +Each is a theme description rather than a source: pass it as a `FlexThemeReference` base, alone or under recipes. A +reference built on `flexTheme` or `flexWarmTheme` resolves the same tokens as a default `FlexThemeReference` requesting +that tone. Both descriptions are the shared default objects, so treat them as read-only; author changes as recipes or a +new description. + +```ts +import { FlexThemeReference } from '@fluentui-react-native/design'; +import { flexWarmTheme } from '@fluentui-react-native/design/themes'; + +const theme = new FlexThemeReference({ base: flexWarmTheme, appearance: { colorScheme: 'system' } }); +``` + ## Legacy projection and bundle boundary The package root exports only the modern authoring and consumption APIs. It reaches the forward Theme-to-Flex adapter, -which `useThemeState` needs for legacy sources, but not `useTheme`, the reverse converter, the complete legacy -defaults, or legacy token payloads. `entry-points.md` lists every subpath. +which `useThemeState` needs for legacy sources, and the Flex interaction policy with the raw `color-lib` interaction +algorithm, but not `useTheme`, the reverse converter, the Fluent themes it projects onto, or deprecated token data. The +legacy `ThemeReference`, `useTheme`, and `ThemeProvider` graphs reach neither Flex nor `color-lib`. An app that pairs a +legacy `ThemeReference` with `useThemeState` reaches the forward adapter and, through the default theme state, the x3 +defaults and the interaction policy with `color-lib/interaction`, but not `FlexThemeReference`, `color-lib/compositing`, +or the compatibility projection. `entry-points.md` lists every subpath. `themeFromFlexTokens` in `theming/compat` builds a complete `Theme` in this order: -1. the appearance-specific complete legacy base from `getDefaultLegacyTheme`; +1. the generated Fluent theme for the platform and appearance, selected as `fluentTheme` selects it, which supplies + every value Flex cannot represent; 2. the source's `legacyFallback`, which preserves component recipes, custom colors, and host metadata that Flex cannot represent; 3. the generated Flex projection, so mapped Flex values are authoritative; 4. `host.appearance` metadata derived from the resolved appearance. The reverse projection is intentionally lossy; `tokens.md` describes how the mapping chooses one canonical Flex value per +legacy path. A layered shadow keeps only its first and last layers as `ambient` and `key`, and motion tokens have no legacy path. The `apps/bundle-size` `design-*` scenarios guard this module boundary. diff --git a/packages/agentic/design/references/tokens.md b/packages/agentic/design/references/tokens.md index 0907bdb36bc..3401cc4be99 100644 --- a/packages/agentic/design/references/tokens.md +++ b/packages/agentic/design/references/tokens.md @@ -3,6 +3,10 @@ id: design.tokens kind: instruction-reference owner_paths: - packages/agentic/design/src/tokens + - packages/agentic/design/src/flex/tokens.types.ts + - packages/agentic/design/src/flex/defaults + - packages/agentic/design/src/flex/adapters + - packages/agentic/design/src/deprecated - packages/agentic/design/scripts --- @@ -17,18 +21,81 @@ owner_paths: | Tokens | Entry point | Source | | ------------------------------ | ------------------------------------------------- | --------------------------------------------------------------------------- | -| Flex semantic tokens | `FlexTokens` from `@fluentui-react-native/design` | `src/tokens/flex.types.ts`; defaults in `src/tokens/defaultTokens.ts` | +| Flex semantic tokens | `FlexTokens` from `@fluentui-react-native/design` | `src/flex/tokens.types.ts`; x3 defaults in `src/flex/defaults/` | | Platform global tokens | `@fluentui-react-native/design/tokens/global` | Generated into `src/tokens/global.generated.ts` and `src/tokens/generated/` | -| Legacy alias and shadow tokens | `@fluentui-react-native/design/tokens/legacy` | `src/tokens/legacy/`, for legacy themes only | +| Deprecated Fluent 2 token data | `@fluentui-react-native/design/deprecated` | `src/deprecated/`, for existing platform themes only (R-DESIGN-003) | -`FlexTokens` groups `color` (with `hover` and `pressed` overrides), `shadow`, `fontWeight`, `fontFamily`, `fontSize`, -`lineHeight`, `borderRadius`, `spacing`, and `strokeWidth`. Components read the active values from -`useThemeState().tokens`; `theming.md` explains how they are resolved. The defaults currently do not vary by -appearance; see `remaining-work.md`. +`FlexTokens` groups `color` (one `InteractiveColor` with `rest`, `hover`, and `pressed` per semantic color; see +`flex-colors.md`), `shadow`, `fontWeight`, `fontFamily`, `fontSize`, `lineHeight`, `borderRadius`, `spacing`, +`strokeWidth`, and `motion`. Components read the active values from `useThemeState().tokens`; `theming.md` explains how +they are resolved. + +Each shadow is a `FlexShadow`: an array of `{ x, y, blur, color }` layers in CSS `box-shadow` order, from the contour +layer to the key shadow, with offsets and blur in density-independent pixels. The tokens keep every source layer. An +authored shadow is one layered shadow or a `[light, dark]` tuple of them; `selectShadowEntry` selects the shadow for an +appearance. A shadow override replaces the whole entry, and an `undefined` entry keeps the base. A legacy +`{ ambient, key }` shadow is authored as `[ambient, key]`, and the former `ambient` and `key` are the first and last +layers. Motion durations are milliseconds, and each easing is an `[x1, y1, x2, y2]` tuple for `Easing.bezier`. Only +colors and shadows vary by color scheme. The package's `prebuild` script (`codegen.cts`) generates the global token files from the platform -`@fluentui-react-native/design-tokens-*` packages and regenerates both mapping projections. Do not edit generated files; -change their inputs and rebuild. +`@fluentui-react-native/design-tokens-*` packages and regenerates both mapping projections. It also generates +`src/fluent/defaults/fluentTokens.generated.ts` (Win32) and its Windows, macOS, iOS, and Android variants. These modules +contain complete Fluent alias colors, shadows, and font aliases, which the `themes` entry point consumes (`theming.md`). +The generator applies the deprecated pipeline mappers from `src/deprecated/` at build time, so runtime code outside that +directory reads Fluent 2 values only from these generated modules (R-DESIGN-003). Do not edit generated files; change +their inputs and rebuild. + +Every generated platform module exports `light`, `dark`, `lightElevated`, `darkElevated`, `hcLight`, and `hcDark` color +and shadow sets, plus `fontAliasTokens`. Colors satisfy `Required<AliasColorTokens>` (including deprecated red +aliases, mapped to danger), fonts satisfy `Required<Variants>`, and shadows satisfy `BaseShadowAliasTokens`. +The generator preserves defined runtime-mapped values and additional native color states that those mappers omit. +Missing colors use same-platform semantic equivalents first, with absent interaction states falling back to rest. +Remaining gaps use portable light/dark defaults assembled from the Win32 and mobile palettes, never another +platform's system colors. Explicit equivalents live in the [Fluent token generator](../scripts/fluent-tokens.cts). + +An appearance without platform data inherits the nearest supported set: an elevated set uses its color scheme's +standard set, a single high-contrast set serves both color schemes, and a platform without high-contrast data uses +light and dark. Win32's Dark Gray palette is its elevated dark set, and its single `hc` palette of system colors is +`hcDark`. Windows has no high-contrast palette, so it uses the Win32 `hc` palette as `SystemColor…Color` Windows +brushes. iOS's high-contrast files contain fonts but no colors, so they inherit the matching standard colors; this is +coverage, not a synthesized or accessibility-qualified high-contrast palette. Native shadow +sets remain intact. Missing font aliases use native equivalents, or the platform's global typography ramp when no +aliases exist (macOS and Windows); legacy variant names alias the completed Fluent variants. Tests compare all +platforms against the full token interfaces and reject missing or undefined entries. + +Generated token modules emit their values through the scripts package's `ValuePool`, which minimizes the minified size: +values that repeat are hoisted into constants, and entries that several declarations share are emitted once in ancestor +objects that the declarations spread. The emitted key order is therefore not meaningful. + +## Default tokens + +`src/flex/defaults/defaultTokens.generated.ts` holds the cool and warm x3 defaults, and `defaultTokens.ts` normalizes +them. `FlexThemeReference` merges the default for the resolved `colorTone` under its base and recipes, and the `themes` +entry point exposes the two defaults as `flexTheme` and `flexWarmTheme` (`theming.md`). The x3 sources +define no high-contrast or elevated values, so those appearances use the light or dark default. Defaults do not +otherwise vary by contrast or interface level; see `remaining-work.md`. Tests that assert default values should read +them from `defaultFlexTokens` in the `testing` entry point rather than repeating literals. + +The defaults are rest-first. The generator omits a hover or pressed state when the runtime interaction policy +reproduces its source value in both schemes, and authors the state otherwise, so changing the policy can change which +states are explicit. The coverage ledger, `coverage.generated.json` beside the generator in the package's +`flex-defaults` scripts directory, records for every Flex destination the x3 variable, each tone's light and dark +values, whether each interaction state is computed or explicit, and any native adaptation. Adaptations convert `rem` to +16 density-independent pixels, durations to milliseconds, `cubic-bezier()` to tuples, variable font weights to native +static weights, and relative `oklch` shadow alphas to `#rrggbbaa`. Opaque colors are emitted as `#rrggbb`. + +Regenerate both files from the pinned snapshots, or verify that they are current: + +```sh +yarn workspace @fluentui-react-native/design gen:flex-defaults +yarn workspace @fluentui-react-native/design gen:flex-defaults --check +``` + +The generator imports the interaction policy's TypeScript source and requires Node 22.18 or later. `--check` exits 1 +when an output is stale. `src/flex/defaults/generateDefaults.test.ts` runs the check, and `x3Defaults.test.ts` +independently parses the pinned CSS to verify every resolved default for each tone and scheme, that each explicit state +differs from the policy's result, and that every x3 variable has a Flex destination. ## Flex token mapping @@ -40,14 +107,22 @@ canonical Flex value back to each representable legacy Theme path. The reverse projection is intentionally lossy. When several Flex roles share one legacy Theme path, `reverse.canonical` names the selected source, lists every omitted candidate, and records why that choice is stable. Interactive reverse -entries fall back to their rest value when the authored hover or pressed map -does not override that token. `reverse.transforms` owns any value conversion +entries read the resolved color's `hover` or `pressed` state; for the +deprecated `FlatFlexTokens` input they fall back to rest when the state map has +no entry for that token. `reverse.transforms` owns any value conversion required by a target path. -`nonFluentFlexTokens` supplies values for supported Flex destinations without a -Theme source. A complete legacy Theme also requires values that Flex cannot -represent; those values are supplied by the lazy compatibility base under -`src/theming/compat`. +`src/flex/adapters/fluentFallbackTokens.ts` holds the forward adapter's +Fluent-native fallbacks, not the x3 defaults. `nonFluentFlexTokens` supplies +values for supported Flex destinations without a Theme source, and +`fluentFallbackFlexTokens` supplies mapped values a Theme omits. The adapter +never derives states: a state that neither the Theme nor a fallback supplies +equals rest. X3 default changes therefore never alter projected legacy themes. +Legacy +`{ ambient, key }` Theme shadows become `[ambient, key]` layers. A complete +legacy Theme also requires values that Flex cannot represent; the Flex-to-legacy +projection takes those values from the Fluent theme for the appearance +(`theming.md`). ### Internal consistency @@ -94,10 +169,12 @@ without changing the pin, pass `--ref <commit>`. yarn workspace @fluentui-react-native/design update:upstream-snapshots ``` - The command refreshes the three snapshots and their `blobSha` values. + The command refreshes every snapshot listed in `files` and its `blobSha`. 3. Run `gen:upstream-drift --offline` and confirm that `hasDrift` is `false` and every `snapshotIntegrity` entry reports `matches: true`. -4. Run `check:mappings` and the design package test suite. -5. Commit the pin record, all three refreshed snapshots, and a changeset - describing the upstream change together. +4. Run `gen:flex-defaults`, then `check:mappings` and the design package test + suite. Review value changes in the coverage ledger, and update source-commit + citations in code comments and references. +5. Commit the pin record, the refreshed snapshots, the regenerated defaults and + ledger, and a changeset describing the upstream change together. diff --git a/packages/agentic/design/scripts/codegen.cts b/packages/agentic/design/scripts/codegen.cts index c65bf676ea5..3895b5205fa 100644 --- a/packages/agentic/design/scripts/codegen.cts +++ b/packages/agentic/design/scripts/codegen.cts @@ -1,6 +1,7 @@ const { processPlatformJsonFiles, outputCodegenFile } = require('@fluentui-react-native/scripts'); const path = require('node:path'); const { assertMappingsConsistent, writeMappingProjections } = require('./token-mappings/check-mappings.cjs'); +const { codegenFluentTokens } = require('./fluent-tokens.cts'); const globalHeader = `WARNING: This file is auto-generated. Do not edit it manually. @@ -38,6 +39,7 @@ function main() { writeMappingProjections(); assertMappingsConsistent(); processGlobals(); + codegenFluentTokens(); } main(); diff --git a/packages/agentic/design/scripts/design-token.types.ts b/packages/agentic/design/scripts/design-token.types.ts new file mode 100644 index 00000000000..035c0a84fba --- /dev/null +++ b/packages/agentic/design/scripts/design-token.types.ts @@ -0,0 +1,23 @@ +export type ShadowLayer = { + color: string; + x: number; + y: number; + blur: number; +}; + +export type ShadowDefinition = [ShadowLayer, ShadowLayer]; + +export type ShadowTokens = { + shadow16: ShadowDefinition; + shadow2: ShadowDefinition; + shadow28: ShadowDefinition; + shadow4: ShadowDefinition; + shadow64: ShadowDefinition; + shadow8: ShadowDefinition; + shadowBrand16: ShadowDefinition; + shadowBrand2: ShadowDefinition; + shadowBrand28: ShadowDefinition; + shadowBrand4: ShadowDefinition; + shadowBrand64: ShadowDefinition; + shadowBrand8: ShadowDefinition; +}; diff --git a/packages/agentic/design/scripts/flex-defaults/coverage.generated.json b/packages/agentic/design/scripts/flex-defaults/coverage.generated.json new file mode 100644 index 00000000000..baa3bc8a485 --- /dev/null +++ b/packages/agentic/design/scripts/flex-defaults/coverage.generated.json @@ -0,0 +1,531 @@ +{ + "generator": "scripts/flex-defaults/generate-defaults.mjs", + "source": { + "repository": "x3-design/fluent-design", + "commit": "206e890b645fb450ad7c5df2ff981765349a2b58", + "files": { + "cool": [ + "dev/web/flex-themes/css/semantic.css", + "dev/web/flex-themes/css/interaction-fallback.css" + ], + "warm": [ + "dev/web/flex-themes/css/warm/semantic.css", + "dev/web/flex-themes/css/warm/interaction-fallback.css" + ] + } + }, + "mapping": "src/tokens/mappings/flex-token-map.yaml", + "notes": [ + "Each tone records the light and dark source values after resolving light-dark() and [data-theme] overrides.", + "computed: the runtime interaction policy reproduces the source state from rest, so the default omits it. explicit: the default authors the source state.", + "Computed states equal rest in high contrast; explicit states apply in every contrast.", + "The x3 semantic sources define no native high-contrast or elevated values; those appearances reuse the light or dark defaults.", + "native: the emitted value; adaptation: how the source value converts to it.", + "Theme shadows project to legacy { ambient, key } pairs from the first and last layers; that projection is lossy." + ], + "destinations": [ + {"path":"color.surfaceNeutralFarther.rest","source":"--gnrc-color-surface-neutral-farther","type":"standard","cool":{"light":"#ebebeb","dark":"#1b1b1b"},"warm":{"light":"#f0eae5","dark":"#1e1916"}}, + {"path":"color.surfaceNeutralFarther.hover","source":"--gnrc-color-surface-neutral-farther-hover","cool":{"light":"#e1e1e1","dark":"#2f2f2f","state":"computed"},"warm":{"light":"#e8e0d9","dark":"#342d29","state":"computed"}}, + {"path":"color.surfaceNeutralFarther.pressed","source":"--gnrc-color-surface-neutral-farther-pressed","cool":{"light":"#d7d7d7","dark":"#454545","state":"computed"},"warm":{"light":"#dfd6ce","dark":"#4b423d","state":"computed"}}, + {"path":"color.surfaceNeutralFar.rest","source":"--gnrc-color-surface-neutral-far","type":"standard","cool":{"light":"#f2f2f2","dark":"#1f1f1f"},"warm":{"light":"#faf4f0","dark":"#231e1a"}}, + {"path":"color.surfaceNeutralFar.hover","source":"--gnrc-color-surface-neutral-far-hover","cool":{"light":"#e8e8e8","dark":"#323232","state":"computed"},"warm":{"light":"#f2eae4","dark":"#38312b","state":"computed"}}, + {"path":"color.surfaceNeutralFar.pressed","source":"--gnrc-color-surface-neutral-far-pressed","cool":{"light":"#dedede","dark":"#464646","state":"computed"},"warm":{"light":"#e9dfd9","dark":"#4d453e","state":"computed"}}, + {"path":"color.surfaceNeutralNear.rest","source":"--gnrc-color-surface-neutral-near","type":"standard","cool":{"light":"#fcfcfc","dark":"#181818"},"warm":{"light":"#f6f1ec","dark":"#1c1714"}}, + {"path":"color.surfaceNeutralNear.hover","source":"--gnrc-color-surface-neutral-near-hover","cool":{"light":"#f2f2f2","dark":"#2d2d2d","state":"computed"},"warm":{"light":"#ede7e0","dark":"#322b27","state":"computed"}}, + {"path":"color.surfaceNeutralNear.pressed","source":"--gnrc-color-surface-neutral-near-pressed","cool":{"light":"#e8e8e8","dark":"#434343","state":"computed"},"warm":{"light":"#e5ddd4","dark":"#4b413c","state":"computed"}}, + {"path":"color.surfaceNeutralNearer.rest","source":"--gnrc-color-surface-neutral-nearer","type":"standard","cool":{"light":"#ffffff","dark":"#292929"},"warm":{"light":"#ffffff","dark":"#2e2823"}}, + {"path":"color.surfaceNeutralNearer.hover","source":"--gnrc-color-surface-neutral-nearer-hover","cool":{"light":"#f5f5f5","dark":"#3a3a3a","state":"computed"},"warm":{"light":"#f6f5f3","dark":"#403832","state":"computed"}}, + {"path":"color.surfaceNeutralNearer.pressed","source":"--gnrc-color-surface-neutral-nearer-pressed","cool":{"light":"#ebebeb","dark":"#4b4b4b","state":"computed"},"warm":{"light":"#edebe7","dark":"#534941","state":"computed"}}, + {"path":"color.surfaceNeutralTranslucent.rest","source":"--gnrc-color-surface-neutral-translucent","type":"standard","cool":{"light":"#ffffff80","dark":"#3c3c3c80"},"warm":{"light":"#ffffff80","dark":"#00000080"}}, + {"path":"color.surfaceNeutralTranslucent.hover","source":"--gnrc-color-surface-neutral-translucent-hover","cool":{"light":"#f5f5f58a","dark":"#47474788","state":"computed"},"warm":{"light":"#f7f6f48a","dark":"#02010188","state":"computed"}}, + {"path":"color.surfaceNeutralTranslucent.pressed","source":"--gnrc-color-surface-neutral-translucent-pressed","cool":{"light":"#ebebeb94","dark":"#5353538f","state":"computed"},"warm":{"light":"#f0eeea94","dark":"#0e0b0c8f","state":"computed"}}, + {"path":"color.backgroundNeutralHeavy.rest","source":"--gnrc-color-background-neutral-heavy","type":"inverted","cool":{"light":"#242424","dark":"#ffffff"},"warm":{"light":"#28231e","dark":"#ffffff"}}, + {"path":"color.backgroundNeutralHeavy.hover","source":"--gnrc-color-background-neutral-heavy-hover","cool":{"light":"#363636","dark":"#f5f5f5","state":"computed"},"warm":{"light":"#3b352e","dark":"#f6f5f3","state":"computed"}}, + {"path":"color.backgroundNeutralHeavy.pressed","source":"--gnrc-color-background-neutral-heavy-pressed","cool":{"light":"#494949","dark":"#ebebeb","state":"computed"},"warm":{"light":"#50473f","dark":"#edebe7","state":"computed"}}, + {"path":"color.backgroundNeutralLoud.rest","source":"--gnrc-color-background-neutral-loud","type":"inverted","cool":{"light":"#6f6f6f","dark":"#929292"},"warm":{"light":"#1e0d009a","dark":"#ffeee39a"}}, + {"path":"color.backgroundNeutralLoud.hover","source":"--gnrc-color-background-neutral-loud-hover","cool":{"light":"#787878","dark":"#898989","state":"computed"},"warm":{"light":"#2e1a0a9a","dark":"#f3dfd29a","state":"computed"}}, + {"path":"color.backgroundNeutralLoud.pressed","source":"--gnrc-color-background-neutral-loud-pressed","cool":{"light":"#818181","dark":"#808080","state":"computed"},"warm":{"light":"#3f28169a","dark":"#e6d0c09a","state":"computed"}}, + {"path":"color.backgroundNeutralSoft.rest","source":"--gnrc-color-background-neutral-soft","type":"standard","cool":{"light":"#00000014","dark":"#ffffff1f"},"warm":{"light":"#4d200028","dark":"#ffe3cb40"}}, + {"path":"color.backgroundNeutralSoft.hover","source":"--gnrc-color-background-neutral-soft-hover","cool":{"light":"#0000001e","dark":"#ffffff27","state":"computed"},"warm":{"light":"#61330f32","dark":"#fde1c548","state":"computed"}}, + {"path":"color.backgroundNeutralSoft.pressed","source":"--gnrc-color-background-neutral-soft-pressed","cool":{"light":"#00000028","dark":"#ffffff2e","state":"computed"},"warm":{"light":"#6a3b193c","dark":"#ffdec44f","state":"computed"}}, + {"path":"color.backgroundNeutralSubtle.rest","source":"--gnrc-color-background-neutral-subtle","type":"standard","cool":{"light":"#0000000d","dark":"#ffffff14"},"warm":{"light":"#6c31001a","dark":"#fff4ef14"}}, + {"path":"color.backgroundNeutralSubtle.hover","source":"--gnrc-color-background-neutral-subtle-hover","cool":{"light":"#00000017","dark":"#ffffff1c","state":"computed"},"warm":{"light":"#7f471c24","dark":"#ffe8e81c","state":"computed"}}, + {"path":"color.backgroundNeutralSubtle.pressed","source":"--gnrc-color-background-neutral-subtle-pressed","cool":{"light":"#00000021","dark":"#ffffff23","state":"computed"},"warm":{"light":"#8b53272e","dark":"#ffdfdf23","state":"computed"}}, + {"path":"color.backgroundNeutralTransparent.rest","source":"--gnrc-color-background-neutral-transparent","type":"standard","cool":{"light":"#24242400","dark":"#ffffff00"},"warm":{"light":"#28231e00","dark":"#ffffff00"}}, + {"path":"color.backgroundNeutralTransparent.hover","source":"--gnrc-color-background-neutral-transparent-hover","cool":{"light":"#1313130a","dark":"#ffffff08","state":"computed"},"warm":{"light":"#231d170a","dark":"#fbfaf808","state":"computed"}}, + {"path":"color.backgroundNeutralTransparent.pressed","source":"--gnrc-color-background-neutral-transparent-pressed","cool":{"light":"#05050514","dark":"#ffffff0f","state":"computed"},"warm":{"light":"#1e170f14","dark":"#fefcf80f","state":"computed"}}, + {"path":"color.backgroundNeutralTranslucent.rest","source":"--gnrc-color-background-neutral-translucent","type":"standard","cool":{"light":"#e9e9e980","dark":"#3c3c3c80"},"warm":{"light":"#e9e9e980","dark":"#3c3c3c80"}}, + {"path":"color.backgroundNeutralTranslucent.hover","source":"--gnrc-color-background-neutral-translucent-hover","cool":{"light":"#d8d8d88a","dark":"#56565688","state":"explicit"},"warm":{"light":"#dcdcd68a","dark":"#52524e88","state":"computed"}}, + {"path":"color.backgroundNeutralTranslucent.pressed","source":"--gnrc-color-background-neutral-translucent-pressed","cool":{"light":"#cacaca94","dark":"#6d6d6d8f","state":"explicit"},"warm":{"light":"#d2cfc894","dark":"#67665e8f","state":"computed"}}, + {"path":"color.backgroundBrandHeavy.rest","source":"--gnrc-color-background-brand-heavy","type":"inverted","cool":{"light":"#242424","dark":"#ffffff"},"warm":{"light":"#28231e","dark":"#ffffff"}}, + {"path":"color.backgroundBrandHeavy.hover","source":"--gnrc-color-background-brand-heavy-hover","cool":{"light":"#363636","dark":"#f5f5f5","state":"computed"},"warm":{"light":"#3b352e","dark":"#f6f5f3","state":"computed"}}, + {"path":"color.backgroundBrandHeavy.pressed","source":"--gnrc-color-background-brand-heavy-pressed","cool":{"light":"#494949","dark":"#ebebeb","state":"computed"},"warm":{"light":"#50473f","dark":"#edebe7","state":"computed"}}, + {"path":"color.backgroundBrandLoud.rest","source":"--gnrc-color-background-brand-loud","type":"inverted","cool":{"light":"#6f6f6f","dark":"#929292"},"warm":{"light":"#1e0d009a","dark":"#ffeee39a"}}, + {"path":"color.backgroundBrandLoud.hover","source":"--gnrc-color-background-brand-loud-hover","cool":{"light":"#787878","dark":"#898989","state":"computed"},"warm":{"light":"#2e1a0a9a","dark":"#f3dfd29a","state":"computed"}}, + {"path":"color.backgroundBrandLoud.pressed","source":"--gnrc-color-background-brand-loud-pressed","cool":{"light":"#818181","dark":"#808080","state":"computed"},"warm":{"light":"#3f28169a","dark":"#e6d0c09a","state":"computed"}}, + {"path":"color.backgroundBrandSoft.rest","source":"--gnrc-color-background-brand-soft","type":"standard","cool":{"light":"#00000014","dark":"#ffffff1f"},"warm":{"light":"#4d200028","dark":"#ffe3cb40"}}, + {"path":"color.backgroundBrandSoft.hover","source":"--gnrc-color-background-brand-soft-hover","cool":{"light":"#0000001e","dark":"#ffffff27","state":"computed"},"warm":{"light":"#61330f32","dark":"#fde1c548","state":"computed"}}, + {"path":"color.backgroundBrandSoft.pressed","source":"--gnrc-color-background-brand-soft-pressed","cool":{"light":"#00000028","dark":"#ffffff2e","state":"computed"},"warm":{"light":"#6a3b193c","dark":"#ffdec44f","state":"computed"}}, + {"path":"color.backgroundBrandSubtle.rest","source":"--gnrc-color-background-brand-subtle","type":"standard","cool":{"light":"#0000000a","dark":"#ffffff14"},"warm":{"light":"#6c31001a","dark":"#fff4ef14"}}, + {"path":"color.backgroundBrandSubtle.hover","source":"--gnrc-color-background-brand-subtle-hover","cool":{"light":"#00000014","dark":"#ffffff1c","state":"computed"},"warm":{"light":"#7f471c24","dark":"#ffe8e81c","state":"computed"}}, + {"path":"color.backgroundBrandSubtle.pressed","source":"--gnrc-color-background-brand-subtle-pressed","cool":{"light":"#0000001e","dark":"#ffffff23","state":"computed"},"warm":{"light":"#8b53272e","dark":"#ffdfdf23","state":"computed"}}, + {"path":"color.backgroundBrandTransparent.rest","source":"--gnrc-color-background-brand-transparent","type":"standard","cool":{"light":"#24242400","dark":"#ffffff00"},"warm":{"light":"#28231e00","dark":"#ffffff00"}}, + {"path":"color.backgroundBrandTransparent.hover","source":"--gnrc-color-background-brand-transparent-hover","cool":{"light":"#1313130a","dark":"#ffffff08","state":"computed"},"warm":{"light":"#231d170a","dark":"#fbfaf808","state":"computed"}}, + {"path":"color.backgroundBrandTransparent.pressed","source":"--gnrc-color-background-brand-transparent-pressed","cool":{"light":"#05050514","dark":"#ffffff0f","state":"computed"},"warm":{"light":"#1e170f14","dark":"#fefcf80f","state":"computed"}}, + {"path":"color.backgroundDangerLoud.rest","source":"--gnrc-color-background-danger-loud","type":"inverted","cool":{"light":"#c02e56","dark":"#e55e7a"},"warm":{"light":"#c02e56","dark":"#e55e7a"}}, + {"path":"color.backgroundDangerLoud.hover","source":"--gnrc-color-background-danger-loud-hover","cool":{"light":"#cb395e","dark":"#da5471","state":"computed"},"warm":{"light":"#cd355e","dark":"#dd5170","state":"computed"}}, + {"path":"color.backgroundDangerLoud.pressed","source":"--gnrc-color-background-danger-loud-pressed","cool":{"light":"#d54467","dark":"#d04b69","state":"computed"},"warm":{"light":"#da3c65","dark":"#d54467","state":"computed"}}, + {"path":"color.backgroundDangerSoft.rest","source":"--gnrc-color-background-danger-soft","type":"standard","cool":{"light":"#ffe3e6","dark":"#5a2932"},"warm":{"light":"#ffe3e6","dark":"#5a2932"}}, + {"path":"color.backgroundDangerSoft.hover","source":"--gnrc-color-background-danger-soft-hover","cool":{"light":"#f5d9dc","dark":"#67353e","state":"computed"},"warm":{"light":"#f7d8dc","dark":"#68343d","state":"computed"}}, + {"path":"color.backgroundDangerSoft.pressed","source":"--gnrc-color-background-danger-soft-pressed","cool":{"light":"#ebcfd2","dark":"#754149","state":"computed"},"warm":{"light":"#efced1","dark":"#773f49","state":"computed"}}, + {"path":"color.backgroundDangerSubtle.rest","source":"--gnrc-color-background-danger-subtle","type":"standard","cool":{"light":"#fff1f3","dark":"#402529"},"warm":{"light":"#fff1f3","dark":"#402529"}}, + {"path":"color.backgroundDangerSubtle.hover","source":"--gnrc-color-background-danger-subtle-hover","cool":{"light":"#f5e7e9","dark":"#503438","state":"computed"},"warm":{"light":"#f7e6e9","dark":"#523338","state":"computed"}}, + {"path":"color.backgroundDangerSubtle.pressed","source":"--gnrc-color-background-danger-subtle-pressed","cool":{"light":"#ebdddf","dark":"#614448","state":"computed"},"warm":{"light":"#efdcde","dark":"#644247","state":"computed"}}, + {"path":"color.backgroundWarningLoud.rest","source":"--gnrc-color-background-warning-loud","type":"inverted","cool":{"light":"#bb4001","dark":"#e56738"},"warm":{"light":"#bb4001","dark":"#e56738"}}, + {"path":"color.backgroundWarningLoud.hover","source":"--gnrc-color-background-warning-loud-hover","cool":{"light":"#c54a14","dark":"#da5d2e","state":"computed"},"warm":{"light":"#c84709","dark":"#dd5b28","state":"computed"}}, + {"path":"color.backgroundWarningLoud.pressed","source":"--gnrc-color-background-warning-loud-pressed","cool":{"light":"#d05321","dark":"#d05422","state":"computed"},"warm":{"light":"#d54e11","dark":"#d54f13","state":"computed"}}, + {"path":"color.backgroundWarningSoft.rest","source":"--gnrc-color-background-warning-soft","type":"standard","cool":{"light":"#ffe5dc","dark":"#592c1c"},"warm":{"light":"#ffe5dc","dark":"#592c1c"}}, + {"path":"color.backgroundWarningSoft.hover","source":"--gnrc-color-background-warning-soft-hover","cool":{"light":"#f5dbd2","dark":"#663828","state":"computed"},"warm":{"light":"#f7dbd1","dark":"#673726","state":"computed"}}, + {"path":"color.backgroundWarningSoft.pressed","source":"--gnrc-color-background-warning-soft-pressed","cool":{"light":"#ebd1c9","dark":"#744434","state":"computed"},"warm":{"light":"#eed0c6","dark":"#764331","state":"computed"}}, + {"path":"color.backgroundWarningSubtle.rest","source":"--gnrc-color-background-warning-subtle","type":"standard","cool":{"light":"#fff2ee","dark":"#40261d"},"warm":{"light":"#fff2ee","dark":"#40261d"}}, + {"path":"color.backgroundWarningSubtle.hover","source":"--gnrc-color-background-warning-subtle-hover","cool":{"light":"#f5e8e4","dark":"#51352c","state":"computed"},"warm":{"light":"#f7e7e3","dark":"#52352b","state":"computed"}}, + {"path":"color.backgroundWarningSubtle.pressed","source":"--gnrc-color-background-warning-subtle-pressed","cool":{"light":"#ebdeda","dark":"#62453b","state":"computed"},"warm":{"light":"#efddd7","dark":"#644439","state":"computed"}}, + {"path":"color.backgroundSuccessLoud.rest","source":"--gnrc-color-background-success-loud","type":"inverted","cool":{"light":"#008455","dark":"#05ad72"},"warm":{"light":"#008455","dark":"#05ad72"}}, + {"path":"color.backgroundSuccessLoud.hover","source":"--gnrc-color-background-success-loud-hover","cool":{"light":"#188d5d","dark":"#00a369","state":"computed"},"warm":{"light":"#088e5c","dark":"#00a468","state":"computed"}}, + {"path":"color.backgroundSuccessLoud.pressed","source":"--gnrc-color-background-success-loud-pressed","cool":{"light":"#279666","dark":"#009a60","state":"computed"},"warm":{"light":"#119864","dark":"#009c5e","state":"computed"}}, + {"path":"color.backgroundSuccessSoft.rest","source":"--gnrc-color-background-success-soft","type":"standard","cool":{"light":"#c9f8dd","dark":"#0c462d"},"warm":{"light":"#c9f8dd","dark":"#0c462d"}}, + {"path":"color.backgroundSuccessSoft.hover","source":"--gnrc-color-background-success-soft-hover","cool":{"light":"#bfeed3","dark":"#1c5238","state":"computed"},"warm":{"light":"#bdefd3","dark":"#185338","state":"computed"}}, + {"path":"color.backgroundSuccessSoft.pressed","source":"--gnrc-color-background-success-soft-pressed","cool":{"light":"#b6e4ca","dark":"#295f44","state":"computed"},"warm":{"light":"#b2e5c8","dark":"#246043","state":"computed"}}, + {"path":"color.backgroundSuccessSubtle.rest","source":"--gnrc-color-background-success-subtle","type":"standard","cool":{"light":"#e3fcee","dark":"#193426"},"warm":{"light":"#e3fcee","dark":"#193426"}}, + {"path":"color.backgroundSuccessSubtle.hover","source":"--gnrc-color-background-success-subtle-hover","cool":{"light":"#d9f2e4","dark":"#294435","state":"computed"},"warm":{"light":"#d7f3e3","dark":"#274435","state":"computed"}}, + {"path":"color.backgroundSuccessSubtle.pressed","source":"--gnrc-color-background-success-subtle-pressed","cool":{"light":"#cfe8da","dark":"#385445","state":"computed"},"warm":{"light":"#cce9d9","dark":"#355544","state":"computed"}}, + {"path":"color.strokeNeutralHeavy.rest","source":"--gnrc-color-stroke-neutral-heavy","type":"inverted","cool":{"light":"#242424","dark":"#dedede"},"warm":{"light":"#28231e","dark":"#e3dcd7"}}, + {"path":"color.strokeNeutralHeavy.hover","source":"--gnrc-color-stroke-neutral-heavy-hover","cool":{"light":"#363636","dark":"#d4d4d4","state":"computed"},"warm":{"light":"#3b352e","dark":"#dbd2cb","state":"computed"}}, + {"path":"color.strokeNeutralHeavy.pressed","source":"--gnrc-color-stroke-neutral-heavy-pressed","cool":{"light":"#494949","dark":"#cbcbcb","state":"computed"},"warm":{"light":"#50473f","dark":"#d3c8c0","state":"computed"}}, + {"path":"color.strokeNeutralLoud.rest","source":"--gnrc-color-stroke-neutral-loud","type":"inverted","cool":{"light":"#6f6f6f","dark":"#929292"},"warm":{"light":"#776d65","dark":"#9a9089"}}, + {"path":"color.strokeNeutralLoud.hover","source":"--gnrc-color-stroke-neutral-loud-hover","cool":{"light":"#787878","dark":"#898989","state":"computed"},"warm":{"light":"#81756c","dark":"#92877e","state":"computed"}}, + {"path":"color.strokeNeutralLoud.pressed","source":"--gnrc-color-stroke-neutral-loud-pressed","cool":{"light":"#818181","dark":"#808080","state":"computed"},"warm":{"light":"#8c7e73","dark":"#8b7d74","state":"computed"}}, + {"path":"color.strokeNeutralSoft.rest","source":"--gnrc-color-stroke-neutral-soft","type":"standard","cool":{"light":"#0000006d","dark":"#ffffff61"},"warm":{"light":"#250f0076","dark":"#ffe6d35c"}}, + {"path":"color.strokeNeutralSoft.hover","source":"--gnrc-color-stroke-neutral-soft-hover","cool":{"light":"#02020277","dark":"#ffffff69","state":"explicit"},"warm":{"light":"#2a120280","dark":"#ffe6cf64","state":"computed"}}, + {"path":"color.strokeNeutralSoft.pressed","source":"--gnrc-color-stroke-neutral-soft-pressed","cool":{"light":"#04040481","dark":"#ffffff70","state":"explicit"},"warm":{"light":"#2e16048a","dark":"#ffe8d06b","state":"computed"}}, + {"path":"color.strokeNeutralSubtle.rest","source":"--gnrc-color-stroke-neutral-subtle","type":"standard","cool":{"light":"#00000021","dark":"#ffffff48"},"warm":{"light":"#4d200028","dark":"#ffe3cb40"}}, + {"path":"color.strokeNeutralSubtle.hover","source":"--gnrc-color-stroke-neutral-subtle-hover","cool":{"light":"#0000002b","dark":"#ffffff50","state":"computed"},"warm":{"light":"#61330f32","dark":"#fde1c548","state":"computed"}}, + {"path":"color.strokeNeutralSubtle.pressed","source":"--gnrc-color-stroke-neutral-subtle-pressed","cool":{"light":"#05050535","dark":"#ffffff57","state":"explicit"},"warm":{"light":"#6a3b193c","dark":"#ffdec44f","state":"computed"}}, + {"path":"color.strokeNeutralTransparent.rest","source":"--gnrc-color-stroke-neutral-transparent","type":"standard","cool":{"light":"#24242400","dark":"#ffffff00"},"warm":{"light":"#28231e00","dark":"#ffffff00"}}, + {"path":"color.strokeNeutralTransparent.hover","source":"--gnrc-color-stroke-neutral-transparent-hover","cool":{"light":"#1313130a","dark":"#ffffff08","state":"computed"},"warm":{"light":"#231d170a","dark":"#fbfaf808","state":"computed"}}, + {"path":"color.strokeNeutralTransparent.pressed","source":"--gnrc-color-stroke-neutral-transparent-pressed","cool":{"light":"#05050514","dark":"#ffffff0f","state":"computed"},"warm":{"light":"#1e170f14","dark":"#fefcf80f","state":"computed"}}, + {"path":"color.strokeNeutralOnloud.rest","source":"--gnrc-color-stroke-neutral-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#000000db"},"warm":{"light":"#ffffff","dark":"#0b0600e1"}}, + {"path":"color.strokeNeutralOnloud.hover","source":"--gnrc-color-stroke-neutral-onloud-hover","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffd","dark":"#000000e1","state":"computed"}}, + {"path":"color.strokeNeutralOnloud.pressed","source":"--gnrc-color-stroke-neutral-onloud-pressed","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffb","dark":"#000000e1","state":"computed"}}, + {"path":"color.strokeBrandLoud.rest","source":"--gnrc-color-stroke-brand-loud","type":"inverted","cool":{"light":"#6f6f6f","dark":"#929292"},"warm":{"light":"#776d65","dark":"#9a9089"}}, + {"path":"color.strokeBrandLoud.hover","source":"--gnrc-color-stroke-brand-loud-hover","cool":{"light":"#787878","dark":"#898989","state":"computed"},"warm":{"light":"#81756c","dark":"#92877e","state":"computed"}}, + {"path":"color.strokeBrandLoud.pressed","source":"--gnrc-color-stroke-brand-loud-pressed","cool":{"light":"#818181","dark":"#808080","state":"computed"},"warm":{"light":"#8c7e73","dark":"#8b7d74","state":"computed"}}, + {"path":"color.strokeBrandSoft.rest","source":"--gnrc-color-stroke-brand-soft","type":"standard","cool":{"light":"#0000006d","dark":"#ffffff61"},"warm":{"light":"#250f0076","dark":"#ffe6d35c"}}, + {"path":"color.strokeBrandSoft.hover","source":"--gnrc-color-stroke-brand-soft-hover","cool":{"light":"#02020277","dark":"#ffffff69","state":"explicit"},"warm":{"light":"#2a120280","dark":"#ffe6cf64","state":"computed"}}, + {"path":"color.strokeBrandSoft.pressed","source":"--gnrc-color-stroke-brand-soft-pressed","cool":{"light":"#04040481","dark":"#ffffff70","state":"explicit"},"warm":{"light":"#2e16048a","dark":"#ffe8d06b","state":"computed"}}, + {"path":"color.strokeBrandSubtle.rest","source":"--gnrc-color-stroke-brand-subtle","type":"standard","cool":{"light":"#00000021","dark":"#ffffff48"},"warm":{"light":"#4d200028","dark":"#ffe3cb40"}}, + {"path":"color.strokeBrandSubtle.hover","source":"--gnrc-color-stroke-brand-subtle-hover","cool":{"light":"#0000002b","dark":"#ffffff50","state":"computed"},"warm":{"light":"#61330f32","dark":"#fde1c548","state":"computed"}}, + {"path":"color.strokeBrandSubtle.pressed","source":"--gnrc-color-stroke-brand-subtle-pressed","cool":{"light":"#05050535","dark":"#ffffff57","state":"explicit"},"warm":{"light":"#6a3b193c","dark":"#ffdec44f","state":"computed"}}, + {"path":"color.strokeBrandOnloud.rest","source":"--gnrc-color-stroke-brand-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#242424"},"warm":{"light":"#ffffff","dark":"#0b0600e1"}}, + {"path":"color.strokeBrandOnloud.hover","source":"--gnrc-color-stroke-brand-onloud-hover","cool":{"light":"#ffffff","dark":"#131313","state":"computed"},"warm":{"light":"#fffffd","dark":"#000000e1","state":"computed"}}, + {"path":"color.strokeBrandOnloud.pressed","source":"--gnrc-color-stroke-brand-onloud-pressed","cool":{"light":"#ffffff","dark":"#050505","state":"computed"},"warm":{"light":"#fffffb","dark":"#000000e1","state":"computed"}}, + {"path":"color.strokeDangerLoud.rest","source":"--gnrc-color-stroke-danger-loud","type":"inverted","cool":{"light":"#c02e56","dark":"#e55e7a"},"warm":{"light":"#c02e56","dark":"#e55e7a"}}, + {"path":"color.strokeDangerLoud.hover","source":"--gnrc-color-stroke-danger-loud-hover","cool":{"light":"#cb395e","dark":"#da5471","state":"computed"},"warm":{"light":"#cd355e","dark":"#dd5170","state":"computed"}}, + {"path":"color.strokeDangerLoud.pressed","source":"--gnrc-color-stroke-danger-loud-pressed","cool":{"light":"#d54467","dark":"#d04b69","state":"computed"},"warm":{"light":"#da3c65","dark":"#d54467","state":"computed"}}, + {"path":"color.strokeDangerSoft.rest","source":"--gnrc-color-stroke-danger-soft","type":"standard","cool":{"light":"#e55e7a","dark":"#d14164"},"warm":{"light":"#e55e7a","dark":"#d14164"}}, + {"path":"color.strokeDangerSoft.hover","source":"--gnrc-color-stroke-danger-soft-hover","cool":{"light":"#da5471","dark":"#dc4b6d","state":"computed"},"warm":{"light":"#dd5170","dark":"#de486c","state":"computed"}}, + {"path":"color.strokeDangerSoft.pressed","source":"--gnrc-color-stroke-danger-soft-pressed","cool":{"light":"#d04b69","dark":"#e65575","state":"computed"},"warm":{"light":"#d54467","dark":"#eb4f74","state":"computed"}}, + {"path":"color.strokeDangerSubtle.rest","source":"--gnrc-color-stroke-danger-subtle","type":"standard","cool":{"light":"#ffd0d6","dark":"#76293a"},"warm":{"light":"#ffd0d6","dark":"#76293a"}}, + {"path":"color.strokeDangerSubtle.hover","source":"--gnrc-color-stroke-danger-subtle-hover","cool":{"light":"#f5c6cc","dark":"#803242","state":"computed"},"warm":{"light":"#f7c5cc","dark":"#813041","state":"computed"}}, + {"path":"color.strokeDangerSubtle.pressed","source":"--gnrc-color-stroke-danger-subtle-pressed","cool":{"light":"#ebbdc3","dark":"#893a4a","state":"computed"},"warm":{"light":"#eebbc2","dark":"#8c3749","state":"computed"}}, + {"path":"color.strokeDangerOnloud.rest","source":"--gnrc-color-stroke-danger-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#242424"},"warm":{"light":"#ffffff","dark":"#242424"}}, + {"path":"color.strokeDangerOnloud.hover","source":"--gnrc-color-stroke-danger-onloud-hover","cool":{"light":"#ffffff","dark":"#131313","state":"computed"},"warm":{"light":"#fffffd","dark":"#141312","state":"computed"}}, + {"path":"color.strokeDangerOnloud.pressed","source":"--gnrc-color-stroke-danger-onloud-pressed","cool":{"light":"#ffffff","dark":"#050505","state":"computed"},"warm":{"light":"#fffffb","dark":"#060504","state":"computed"}}, + {"path":"color.strokeWarningLoud.rest","source":"--gnrc-color-stroke-warning-loud","type":"inverted","cool":{"light":"#cd4808","dark":"#e56738"},"warm":{"light":"#cd4808","dark":"#e56738"}}, + {"path":"color.strokeWarningLoud.hover","source":"--gnrc-color-stroke-warning-loud-hover","cool":{"light":"#d8521a","dark":"#da5d2e","state":"computed"},"warm":{"light":"#da4f11","dark":"#dd5b28","state":"computed"}}, + {"path":"color.strokeWarningLoud.pressed","source":"--gnrc-color-stroke-warning-loud-pressed","cool":{"light":"#e25c27","dark":"#d05422","state":"computed"},"warm":{"light":"#e75618","dark":"#d54f13","state":"computed"}}, + {"path":"color.strokeWarningSoft.rest","source":"--gnrc-color-stroke-warning-soft","type":"standard","cool":{"light":"#fc9571","dark":"#cd4808"},"warm":{"light":"#fc9571","dark":"#cd4808"}}, + {"path":"color.strokeWarningSoft.hover","source":"--gnrc-color-stroke-warning-soft-hover","cool":{"light":"#f28c68","dark":"#d8521a","state":"computed"},"warm":{"light":"#f48a65","dark":"#da4f11","state":"computed"}}, + {"path":"color.strokeWarningSoft.pressed","source":"--gnrc-color-stroke-warning-soft-pressed","cool":{"light":"#e7825f","dark":"#e25c27","state":"computed"},"warm":{"light":"#ec7f58","dark":"#e75618","state":"computed"}}, + {"path":"color.strokeWarningSubtle.rest","source":"--gnrc-color-stroke-warning-subtle","type":"standard","cool":{"light":"#ffd3c4","dark":"#762e12"},"warm":{"light":"#ffd3c4","dark":"#762e12"}}, + {"path":"color.strokeWarningSubtle.hover","source":"--gnrc-color-stroke-warning-subtle-hover","cool":{"light":"#f5c9ba","dark":"#7f371b","state":"computed"},"warm":{"light":"#f7c9b9","dark":"#813518","state":"computed"}}, + {"path":"color.strokeWarningSubtle.pressed","source":"--gnrc-color-stroke-warning-subtle-pressed","cool":{"light":"#ebc0b1","dark":"#893f24","state":"computed"},"warm":{"light":"#eebeae","dark":"#8c3c1e","state":"computed"}}, + {"path":"color.strokeWarningOnloud.rest","source":"--gnrc-color-stroke-warning-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#242424"},"warm":{"light":"#ffffff","dark":"#242424"}}, + {"path":"color.strokeWarningOnloud.hover","source":"--gnrc-color-stroke-warning-onloud-hover","cool":{"light":"#ffffff","dark":"#131313","state":"computed"},"warm":{"light":"#fffffd","dark":"#141312","state":"computed"}}, + {"path":"color.strokeWarningOnloud.pressed","source":"--gnrc-color-stroke-warning-onloud-pressed","cool":{"light":"#ffffff","dark":"#050505","state":"computed"},"warm":{"light":"#fffffb","dark":"#060504","state":"computed"}}, + {"path":"color.strokeSuccessLoud.rest","source":"--gnrc-color-stroke-success-loud","type":"inverted","cool":{"light":"#008455","dark":"#05ad72"},"warm":{"light":"#008455","dark":"#05ad72"}}, + {"path":"color.strokeSuccessLoud.hover","source":"--gnrc-color-stroke-success-loud-hover","cool":{"light":"#188d5d","dark":"#00a369","state":"computed"},"warm":{"light":"#088e5c","dark":"#00a468","state":"computed"}}, + {"path":"color.strokeSuccessLoud.pressed","source":"--gnrc-color-stroke-success-loud-pressed","cool":{"light":"#279666","dark":"#009a60","state":"computed"},"warm":{"light":"#119864","dark":"#009c5e","state":"computed"}}, + {"path":"color.strokeSuccessSoft.rest","source":"--gnrc-color-stroke-success-soft","type":"standard","cool":{"light":"#5dce97","dark":"#008e5c"},"warm":{"light":"#5dce97","dark":"#008e5c"}}, + {"path":"color.strokeSuccessSoft.hover","source":"--gnrc-color-stroke-success-soft-hover","cool":{"light":"#52c48e","dark":"#1a9765","state":"computed"},"warm":{"light":"#4cc58d","dark":"#089863","state":"computed"}}, + {"path":"color.strokeSuccessSoft.pressed","source":"--gnrc-color-stroke-success-soft-pressed","cool":{"light":"#47bb85","dark":"#2aa16d","state":"computed"},"warm":{"light":"#39bc82","dark":"#11a26b","state":"computed"}}, + {"path":"color.strokeSuccessSubtle.rest","source":"--gnrc-color-stroke-success-subtle","type":"standard","cool":{"light":"#b1efcc","dark":"#025636"},"warm":{"light":"#b1efcc","dark":"#025636"}}, + {"path":"color.strokeSuccessSubtle.hover","source":"--gnrc-color-stroke-success-subtle-hover","cool":{"light":"#a7e5c2","dark":"#125f3e","state":"computed"},"warm":{"light":"#a5e6c2","dark":"#0a5f3d","state":"computed"}}, + {"path":"color.strokeSuccessSubtle.pressed","source":"--gnrc-color-stroke-success-subtle-pressed","cool":{"light":"#9edbb9","dark":"#1e6746","state":"computed"},"warm":{"light":"#9adcb7","dark":"#136844","state":"computed"}}, + {"path":"color.strokeSuccessOnloud.rest","source":"--gnrc-color-stroke-success-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#242424"},"warm":{"light":"#ffffff","dark":"#242424"}}, + {"path":"color.strokeSuccessOnloud.hover","source":"--gnrc-color-stroke-success-onloud-hover","cool":{"light":"#ffffff","dark":"#131313","state":"computed"},"warm":{"light":"#fffffd","dark":"#141312","state":"computed"}}, + {"path":"color.strokeSuccessOnloud.pressed","source":"--gnrc-color-stroke-success-onloud-pressed","cool":{"light":"#ffffff","dark":"#050505","state":"computed"},"warm":{"light":"#fffffb","dark":"#060504","state":"computed"}}, + {"path":"color.foregroundNeutralPrimary.rest","source":"--gnrc-color-foreground-neutral-primary","type":"standard","cool":{"light":"#000000db","dark":"#ffffffde"},"warm":{"light":"#0b0600e1","dark":"#fff7f2e3"}}, + {"path":"color.foregroundNeutralPrimary.hover","source":"--gnrc-color-foreground-neutral-primary-hover","cool":{"light":"#000000e5","dark":"#ffffffe6","state":"computed"},"warm":{"light":"#060300eb","dark":"#fff8f2eb","state":"computed"}}, + {"path":"color.foregroundNeutralPrimary.pressed","source":"--gnrc-color-foreground-neutral-primary-pressed","cool":{"light":"#000000ef","dark":"#ffffffed","state":"computed"},"warm":{"light":"#040100f5","dark":"#fffaf2f2","state":"computed"}}, + {"path":"color.foregroundNeutralSecondary.rest","source":"--gnrc-color-foreground-neutral-secondary","type":"standard","cool":{"light":"#000000a2","dark":"#ffffffa1"},"warm":{"light":"#190c00ab","dark":"#fff2e8b5"}}, + {"path":"color.foregroundNeutralSecondary.hover","source":"--gnrc-color-foreground-neutral-secondary-hover","cool":{"light":"#000000ac","dark":"#ffffffa9","state":"computed"},"warm":{"light":"#0a0100b5","dark":"#fff7ebbd","state":"computed"}}, + {"path":"color.foregroundNeutralSecondary.pressed","source":"--gnrc-color-foreground-neutral-secondary-pressed","cool":{"light":"#000000b6","dark":"#ffffffb0","state":"computed"},"warm":{"light":"#060000bf","dark":"#fff9ecc4","state":"computed"}}, + {"path":"color.foregroundNeutralTertiary.rest","source":"--gnrc-color-foreground-neutral-tertiary","type":"standard","cool":{"light":"#00000090","dark":"#ffffff80"},"warm":{"light":"#1e0d009a","dark":"#ffeee39a"}}, + {"path":"color.foregroundNeutralTertiary.hover","source":"--gnrc-color-foreground-neutral-tertiary-hover","cool":{"light":"#0000009a","dark":"#ffffff88","state":"computed"},"warm":{"light":"#0c0100a4","dark":"#fff6eaa2","state":"computed"}}, + {"path":"color.foregroundNeutralTertiary.pressed","source":"--gnrc-color-foreground-neutral-tertiary-pressed","cool":{"light":"#000000a4","dark":"#ffffff8f","state":"computed"},"warm":{"light":"#080000ae","dark":"#fff8eaa9","state":"computed"}}, + {"path":"color.foregroundNeutralOnloud.rest","source":"--gnrc-color-foreground-neutral-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#000000db"},"warm":{"light":"#ffffff","dark":"#0b0600e1"}}, + {"path":"color.foregroundNeutralOnloud.hover","source":"--gnrc-color-foreground-neutral-onloud-hover","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffd","dark":"#010000e1","state":"computed"}}, + {"path":"color.foregroundNeutralOnloud.pressed","source":"--gnrc-color-foreground-neutral-onloud-pressed","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffb","dark":"#000000e1","state":"computed"}}, + {"path":"color.foregroundBrandPrimary.rest","source":"--gnrc-color-foreground-brand-primary","type":"standard","cool":{"light":"#242424","dark":"#dedede"},"warm":{"light":"#0b0600e1","dark":"#fff7f2e3"}}, + {"path":"color.foregroundBrandPrimary.hover","source":"--gnrc-color-foreground-brand-primary-hover","cool":{"light":"#131313","dark":"#e8e8e8","state":"computed"},"warm":{"light":"#060300eb","dark":"#fff8f2eb","state":"computed"}}, + {"path":"color.foregroundBrandPrimary.pressed","source":"--gnrc-color-foreground-brand-primary-pressed","cool":{"light":"#050505","dark":"#f2f2f2","state":"computed"},"warm":{"light":"#040100f5","dark":"#fffaf2f2","state":"computed"}}, + {"path":"color.foregroundBrandOnloud.rest","source":"--gnrc-color-foreground-brand-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#000000db"},"warm":{"light":"#ffffff","dark":"#0b0600e1"}}, + {"path":"color.foregroundBrandOnloud.hover","source":"--gnrc-color-foreground-brand-onloud-hover","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffd","dark":"#010000e1","state":"computed"}}, + {"path":"color.foregroundBrandOnloud.pressed","source":"--gnrc-color-foreground-brand-onloud-pressed","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffb","dark":"#000000e1","state":"computed"}}, + {"path":"color.foregroundDangerPrimary.rest","source":"--gnrc-color-foreground-danger-primary","type":"standard","cool":{"light":"#a62147","dark":"#fd8ea1"},"warm":{"light":"#a62147","dark":"#fd8ea1"}}, + {"path":"color.foregroundDangerPrimary.hover","source":"--gnrc-color-foreground-danger-primary-hover","cool":{"light":"#9c133f","dark":"#ff97aa","state":"computed"},"warm":{"light":"#9e0b3e","dark":"#ff96aa","state":"computed"}}, + {"path":"color.foregroundDangerPrimary.pressed","source":"--gnrc-color-foreground-danger-primary-pressed","cool":{"light":"#910037","dark":"#ffa1b4","state":"computed"},"warm":{"light":"#950035","dark":"#ff9db2","state":"computed"}}, + {"path":"color.foregroundDangerOnloud.rest","source":"--gnrc-color-foreground-danger-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#000000db"},"warm":{"light":"#ffffff","dark":"#000000db"}}, + {"path":"color.foregroundDangerOnloud.hover","source":"--gnrc-color-foreground-danger-onloud-hover","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffd","dark":"#000000db","state":"computed"}}, + {"path":"color.foregroundDangerOnloud.pressed","source":"--gnrc-color-foreground-danger-onloud-pressed","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffb","dark":"#000000db","state":"computed"}}, + {"path":"color.foregroundWarningPrimary.rest","source":"--gnrc-color-foreground-warning-primary","type":"standard","cool":{"light":"#a93901","dark":"#fc9571"},"warm":{"light":"#a93901","dark":"#fc9571"}}, + {"path":"color.foregroundWarningPrimary.hover","source":"--gnrc-color-foreground-warning-primary-hover","cool":{"light":"#9f2f00","dark":"#ff9f7a","state":"computed"},"warm":{"light":"#a12c00","dark":"#ff9d77","state":"computed"}}, + {"path":"color.foregroundWarningPrimary.pressed","source":"--gnrc-color-foreground-warning-primary-pressed","cool":{"light":"#952500","dark":"#ffa884","state":"computed"},"warm":{"light":"#991c00","dark":"#ffa57d","state":"computed"}}, + {"path":"color.foregroundWarningOnloud.rest","source":"--gnrc-color-foreground-warning-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#000000db"},"warm":{"light":"#ffffff","dark":"#000000db"}}, + {"path":"color.foregroundWarningOnloud.hover","source":"--gnrc-color-foreground-warning-onloud-hover","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffd","dark":"#000000db","state":"computed"}}, + {"path":"color.foregroundWarningOnloud.pressed","source":"--gnrc-color-foreground-warning-onloud-pressed","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffb","dark":"#000000db","state":"computed"}}, + {"path":"color.foregroundSuccessPrimary.rest","source":"--gnrc-color-foreground-success-primary","type":"standard","cool":{"light":"#017048","dark":"#5dce97"},"warm":{"light":"#017048","dark":"#5dce97"}}, + {"path":"color.foregroundSuccessPrimary.hover","source":"--gnrc-color-foreground-success-primary-hover","cool":{"light":"#006740","dark":"#67d8a0","state":"computed"},"warm":{"light":"#00683f","dark":"#62d99f","state":"computed"}}, + {"path":"color.foregroundSuccessPrimary.pressed","source":"--gnrc-color-foreground-success-primary-pressed","cool":{"light":"#005f38","dark":"#72e2aa","state":"computed"},"warm":{"light":"#006036","dark":"#67e4a7","state":"computed"}}, + {"path":"color.foregroundSuccessOnloud.rest","source":"--gnrc-color-foreground-success-onloud","type":"inverted","cool":{"light":"#ffffff","dark":"#000000db"},"warm":{"light":"#ffffff","dark":"#000000db"}}, + {"path":"color.foregroundSuccessOnloud.hover","source":"--gnrc-color-foreground-success-onloud-hover","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffd","dark":"#000000db","state":"computed"}}, + {"path":"color.foregroundSuccessOnloud.pressed","source":"--gnrc-color-foreground-success-onloud-pressed","cool":{"light":"#ffffff","dark":"#000000db","state":"computed"},"warm":{"light":"#fffffb","dark":"#000000db","state":"computed"}}, + {"path":"color.fixedWhite.rest","source":"--gnrc-color-fixed-white","cool":{"light":"#ffffff","dark":"#ffffff"},"warm":{"light":"#ffffff","dark":"#ffffff"}}, + {"path":"color.fixedWhite.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.fixedWhite.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.fixedBlack.rest","source":"--gnrc-color-fixed-black","cool":{"light":"#000000","dark":"#000000"},"warm":{"light":"#000000","dark":"#000000"}}, + {"path":"color.fixedBlack.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.fixedBlack.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentHeavy.rest","source":"--gnrc-color-expression-accent-heavy","cool":{"light":"#242424","dark":"#ffffff"},"warm":{"light":"#28231e","dark":"#ffffff"}}, + {"path":"color.expressionAccentHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentLoud.rest","source":"--gnrc-color-expression-accent-loud","cool":{"light":"#6f6f6f","dark":"#929292"},"warm":{"light":"#1e0d009a","dark":"#ffeee39a"}}, + {"path":"color.expressionAccentLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentSoft.rest","source":"--gnrc-color-expression-accent-soft","cool":{"light":"#00000014","dark":"#ffffff1f"},"warm":{"light":"#4d200028","dark":"#ffe3cb40"}}, + {"path":"color.expressionAccentSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentSubtle.rest","source":"--gnrc-color-expression-accent-subtle","cool":{"light":"#0000000d","dark":"#ffffff14"},"warm":{"light":"#6c31001a","dark":"#fff4ef14"}}, + {"path":"color.expressionAccentSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAccentSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAchromaticHeavy.rest","source":"--gnrc-color-expression-achromatic-heavy","cool":{"light":"#000000","dark":"#ffffff"},"warm":{"light":"#000000","dark":"#ffffff"}}, + {"path":"color.expressionAchromaticHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAchromaticHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAchromaticSubtle.rest","source":"--gnrc-color-expression-achromatic-subtle","cool":{"light":"#ffffff","dark":"#000000"},"warm":{"light":"#ffffff","dark":"#000000"}}, + {"path":"color.expressionAchromaticSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionAchromaticSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGrayHeavy.rest","source":"--gnrc-color-expression-gray-heavy","cool":{"light":"#484848","dark":"#f5f5f5"},"warm":{"light":"#484848","dark":"#f5f5f5"}}, + {"path":"color.expressionGrayHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGrayHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGrayLoud.rest","source":"--gnrc-color-expression-gray-loud","cool":{"light":"#929292","dark":"#dedede"},"warm":{"light":"#929292","dark":"#dedede"}}, + {"path":"color.expressionGrayLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGrayLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGraySoft.rest","source":"--gnrc-color-expression-gray-soft","cool":{"light":"#dedede","dark":"#929292"},"warm":{"light":"#dedede","dark":"#929292"}}, + {"path":"color.expressionGraySoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGraySoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGraySubtle.rest","source":"--gnrc-color-expression-gray-subtle","cool":{"light":"#f5f5f5","dark":"#484848"},"warm":{"light":"#f5f5f5","dark":"#484848"}}, + {"path":"color.expressionGraySubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGraySubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavyHeavy.rest","source":"--gnrc-color-expression-navy-heavy","cool":{"light":"#294482","dark":"#f0f5ff"},"warm":{"light":"#294482","dark":"#f0f5ff"}}, + {"path":"color.expressionNavyHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavyHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavyLoud.rest","source":"--gnrc-color-expression-navy-loud","cool":{"light":"#5c8df8","dark":"#cedeff"},"warm":{"light":"#5c8df8","dark":"#cedeff"}}, + {"path":"color.expressionNavyLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavyLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavySoft.rest","source":"--gnrc-color-expression-navy-soft","cool":{"light":"#cedeff","dark":"#5c8df8"},"warm":{"light":"#cedeff","dark":"#5c8df8"}}, + {"path":"color.expressionNavySoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavySoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavySubtle.rest","source":"--gnrc-color-expression-navy-subtle","cool":{"light":"#f0f5ff","dark":"#294482"},"warm":{"light":"#f0f5ff","dark":"#294482"}}, + {"path":"color.expressionNavySubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionNavySubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueHeavy.rest","source":"--gnrc-color-expression-blue-heavy","cool":{"light":"#0b497f","dark":"#eef6ff"},"warm":{"light":"#0b497f","dark":"#eef6ff"}}, + {"path":"color.expressionBlueHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueLoud.rest","source":"--gnrc-color-expression-blue-loud","cool":{"light":"#2f95f4","dark":"#c6e1ff"},"warm":{"light":"#2f95f4","dark":"#c6e1ff"}}, + {"path":"color.expressionBlueLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueSoft.rest","source":"--gnrc-color-expression-blue-soft","cool":{"light":"#c6e1ff","dark":"#2f95f4"},"warm":{"light":"#c6e1ff","dark":"#2f95f4"}}, + {"path":"color.expressionBlueSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueSubtle.rest","source":"--gnrc-color-expression-blue-subtle","cool":{"light":"#eef6ff","dark":"#0b497f"},"warm":{"light":"#eef6ff","dark":"#0b497f"}}, + {"path":"color.expressionBlueSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionBlueSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenHeavy.rest","source":"--gnrc-color-expression-green-heavy","cool":{"light":"#0c5722","dark":"#e7fce9"},"warm":{"light":"#0c5722","dark":"#e7fce9"}}, + {"path":"color.expressionGreenHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenLoud.rest","source":"--gnrc-color-expression-green-loud","cool":{"light":"#32ad52","dark":"#baedc1"},"warm":{"light":"#32ad52","dark":"#baedc1"}}, + {"path":"color.expressionGreenLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenSoft.rest","source":"--gnrc-color-expression-green-soft","cool":{"light":"#baedc1","dark":"#32ad52"},"warm":{"light":"#baedc1","dark":"#32ad52"}}, + {"path":"color.expressionGreenSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenSubtle.rest","source":"--gnrc-color-expression-green-subtle","cool":{"light":"#e7fce9","dark":"#0c5722"},"warm":{"light":"#e7fce9","dark":"#0c5722"}}, + {"path":"color.expressionGreenSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionGreenSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeHeavy.rest","source":"--gnrc-color-expression-lime-heavy","cool":{"light":"#345200","dark":"#e6ffcf"},"warm":{"light":"#345200","dark":"#e6ffcf"}}, + {"path":"color.expressionLimeHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeLoud.rest","source":"--gnrc-color-expression-lime-loud","cool":{"light":"#6da603","dark":"#cbff93"},"warm":{"light":"#6da603","dark":"#cbff93"}}, + {"path":"color.expressionLimeLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeSoft.rest","source":"--gnrc-color-expression-lime-soft","cool":{"light":"#cbff93","dark":"#6da603"},"warm":{"light":"#cbff93","dark":"#6da603"}}, + {"path":"color.expressionLimeSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeSubtle.rest","source":"--gnrc-color-expression-lime-subtle","cool":{"light":"#e6ffcf","dark":"#345200"},"warm":{"light":"#e6ffcf","dark":"#345200"}}, + {"path":"color.expressionLimeSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionLimeSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowHeavy.rest","source":"--gnrc-color-expression-yellow-heavy","cool":{"light":"#524800","dark":"#fff7c4"},"warm":{"light":"#524800","dark":"#fff7c4"}}, + {"path":"color.expressionYellowHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowLoud.rest","source":"--gnrc-color-expression-yellow-loud","cool":{"light":"#fbdf06","dark":"#ffed85"},"warm":{"light":"#fbdf06","dark":"#ffed85"}}, + {"path":"color.expressionYellowLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowSoft.rest","source":"--gnrc-color-expression-yellow-soft","cool":{"light":"#ffed85","dark":"#fbdf06"},"warm":{"light":"#ffed85","dark":"#fbdf06"}}, + {"path":"color.expressionYellowSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowSubtle.rest","source":"--gnrc-color-expression-yellow-subtle","cool":{"light":"#fff7c4","dark":"#524800"},"warm":{"light":"#fff7c4","dark":"#524800"}}, + {"path":"color.expressionYellowSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionYellowSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinHeavy.rest","source":"--gnrc-color-expression-pumpkin-heavy","cool":{"light":"#762f0e","dark":"#fef2ee"},"warm":{"light":"#762f0e","dark":"#fef2ee"}}, + {"path":"color.expressionPumpkinHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinLoud.rest","source":"--gnrc-color-expression-pumpkin-loud","cool":{"light":"#fb966e","dark":"#ffd3c2"},"warm":{"light":"#fb966e","dark":"#ffd3c2"}}, + {"path":"color.expressionPumpkinLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinSoft.rest","source":"--gnrc-color-expression-pumpkin-soft","cool":{"light":"#ffd3c2","dark":"#fb966e"},"warm":{"light":"#ffd3c2","dark":"#fb966e"}}, + {"path":"color.expressionPumpkinSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinSubtle.rest","source":"--gnrc-color-expression-pumpkin-subtle","cool":{"light":"#fef2ee","dark":"#762f0e"},"warm":{"light":"#fef2ee","dark":"#762f0e"}}, + {"path":"color.expressionPumpkinSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPumpkinSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedHeavy.rest","source":"--gnrc-color-expression-red-heavy","cool":{"light":"#772b28","dark":"#fff2f0"},"warm":{"light":"#772b28","dark":"#fff2f0"}}, + {"path":"color.expressionRedHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedLoud.rest","source":"--gnrc-color-expression-red-loud","cool":{"light":"#e7615b","dark":"#ffd2cd"},"warm":{"light":"#e7615b","dark":"#ffd2cd"}}, + {"path":"color.expressionRedLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedSoft.rest","source":"--gnrc-color-expression-red-soft","cool":{"light":"#ffd2cd","dark":"#e7615b"},"warm":{"light":"#ffd2cd","dark":"#e7615b"}}, + {"path":"color.expressionRedSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedSubtle.rest","source":"--gnrc-color-expression-red-subtle","cool":{"light":"#fff2f0","dark":"#772b28"},"warm":{"light":"#fff2f0","dark":"#772b28"}}, + {"path":"color.expressionRedSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionRedSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkHeavy.rest","source":"--gnrc-color-expression-pink-heavy","cool":{"light":"#6f2b53","dark":"#fff1f7"},"warm":{"light":"#6f2b53","dark":"#fff1f7"}}, + {"path":"color.expressionPinkHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkLoud.rest","source":"--gnrc-color-expression-pink-loud","cool":{"light":"#d961a6","dark":"#ffcee6"},"warm":{"light":"#d961a6","dark":"#ffcee6"}}, + {"path":"color.expressionPinkLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkSoft.rest","source":"--gnrc-color-expression-pink-soft","cool":{"light":"#ffcee6","dark":"#d961a6"},"warm":{"light":"#ffcee6","dark":"#d961a6"}}, + {"path":"color.expressionPinkSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkSubtle.rest","source":"--gnrc-color-expression-pink-subtle","cool":{"light":"#fff1f7","dark":"#6f2b53"},"warm":{"light":"#fff1f7","dark":"#6f2b53"}}, + {"path":"color.expressionPinkSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPinkSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleHeavy.rest","source":"--gnrc-color-expression-purple-heavy","cool":{"light":"#523778","dark":"#f7f3ff"},"warm":{"light":"#523778","dark":"#f7f3ff"}}, + {"path":"color.expressionPurpleHeavy.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleHeavy.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleLoud.rest","source":"--gnrc-color-expression-purple-loud","cool":{"light":"#a575e8","dark":"#e4d6ff"},"warm":{"light":"#a575e8","dark":"#e4d6ff"}}, + {"path":"color.expressionPurpleLoud.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleLoud.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleSoft.rest","source":"--gnrc-color-expression-purple-soft","cool":{"light":"#e4d6ff","dark":"#a575e8"},"warm":{"light":"#e4d6ff","dark":"#a575e8"}}, + {"path":"color.expressionPurpleSoft.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleSoft.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleSubtle.rest","source":"--gnrc-color-expression-purple-subtle","cool":{"light":"#f7f3ff","dark":"#523778"},"warm":{"light":"#f7f3ff","dark":"#523778"}}, + {"path":"color.expressionPurpleSubtle.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.expressionPurpleSubtle.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.overlayNeutralTranslucent.rest","source":"--gnrc-color-overlay-neutral-translucent","cool":{"light":"#00000026","dark":"#00000099"},"warm":{"light":"#00000026","dark":"#00000099"}}, + {"path":"color.overlayNeutralTranslucent.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.overlayNeutralTranslucent.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.materialBackgroundThick.rest","source":"--gnrc-material-background-thick","cool":{"light":"#fffffff1","dark":"#262626ea"},"warm":{"light":"#fffffff1","dark":"#262626ea"}}, + {"path":"color.materialBackgroundThick.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.materialBackgroundThick.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.materialBackgroundRegular.rest","source":"--gnrc-material-background-regular","cool":{"light":"#ffffffd7","dark":"#2f2f2fd1"},"warm":{"light":"#ffffffd7","dark":"#2f2f2fd1"}}, + {"path":"color.materialBackgroundRegular.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.materialBackgroundRegular.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.materialBackgroundThin.rest","source":"--gnrc-material-background-thin","cool":{"light":"#ffffff7e","dark":"#3434348b"},"warm":{"light":"#ffffff7e","dark":"#3434348b"}}, + {"path":"color.materialBackgroundThin.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.materialBackgroundThin.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.backgroundNeutralDisabled.rest","source":"--gnrc-color-background-neutral-disabled","cool":{"light":"#00000008","dark":"#ffffff07"},"warm":{"light":"#00000008","dark":"#ffffff07"}}, + {"path":"color.backgroundNeutralDisabled.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.backgroundNeutralDisabled.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.backgroundNeutralHeavyDisabled.rest","source":"--gnrc-color-background-neutral-heavy-disabled","cool":{"light":"#0000001a","dark":"#ffffff20"},"warm":{"light":"#0000001a","dark":"#ffffff20"}}, + {"path":"color.backgroundNeutralHeavyDisabled.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.backgroundNeutralHeavyDisabled.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.backgroundNeutralSubtleDisabled.rest","source":"--gnrc-color-background-neutral-subtle-disabled","cool":{"light":"#00000008","dark":"#ffffff07"},"warm":{"light":"#0000000d","dark":"#ffffff1b"}}, + {"path":"color.backgroundNeutralSubtleDisabled.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.backgroundNeutralSubtleDisabled.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.strokeNeutralDisabled.rest","source":"--gnrc-color-stroke-neutral-disabled","cool":{"light":"#00000014","dark":"#ffffff24"},"warm":{"light":"#00000014","dark":"#ffffff24"}}, + {"path":"color.strokeNeutralDisabled.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.strokeNeutralDisabled.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.foregroundNeutralDisabled.rest","source":"--gnrc-color-foreground-neutral-disabled","cool":{"light":"#0000006d","dark":"#ffffff61"},"warm":{"light":"#0000006d","dark":"#ffffff61"}}, + {"path":"color.foregroundNeutralDisabled.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.foregroundNeutralDisabled.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.strokeFocusInner.rest","source":"--gnrc-color-stroke-focus-inner","cool":{"light":"#ffffff","dark":"#000000"},"warm":{"light":"#ffffff","dark":"#000000"}}, + {"path":"color.strokeFocusInner.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.strokeFocusInner.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.strokeFocusOuter.rest","source":"--gnrc-color-stroke-focus-outer","cool":{"light":"#000000","dark":"#ffffff"},"warm":{"light":"#000000","dark":"#ffffff"}}, + {"path":"color.strokeFocusOuter.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.strokeFocusOuter.pressed","state":"rest","reason":"non-interactive"}, + {"path":"color.shadow.rest","source":"--gnrc-color-shadow","cool":{"light":"#000000","dark":"#000000"},"warm":{"light":"#000000","dark":"#000000"}}, + {"path":"color.shadow.hover","state":"rest","reason":"non-interactive"}, + {"path":"color.shadow.pressed","state":"rest","reason":"non-interactive"}, + {"path":"shadow.lowest","source":"--gnrc-shadow-lowest","adaptation":"Relative oklch alpha resolves to #rrggbbaa; every layer is preserved.","cool":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 5%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":1,"blur":2,"color":"#0000000d"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":1,"blur":2,"color":"#0000001a"}]]},"warm":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 5%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":1,"blur":2,"color":"#0000000d"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":1,"blur":2,"color":"#0000001a"}]]}}, + {"path":"shadow.lower","source":"--gnrc-shadow-lower","adaptation":"Relative oklch alpha resolves to #rrggbbaa; every layer is preserved.","cool":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 8%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 16%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":2,"blur":4,"color":"#00000014"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":2,"blur":4,"color":"#00000029"}]]},"warm":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 8%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 16%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":2,"blur":4,"color":"#00000014"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":2,"blur":4,"color":"#00000029"}]]}}, + {"path":"shadow.low","source":"--gnrc-shadow-low","adaptation":"Relative oklch alpha resolves to #rrggbbaa; every layer is preserved.","cool":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 8%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 16%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":2,"blur":4,"color":"#00000008"},{"x":0,"y":4,"blur":8,"color":"#00000014"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":2,"blur":4,"color":"#0000001f"},{"x":0,"y":4,"blur":8,"color":"#00000029"}]]},"warm":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 8%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 16%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":2,"blur":4,"color":"#00000008"},{"x":0,"y":4,"blur":8,"color":"#00000014"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":2,"blur":4,"color":"#0000001f"},{"x":0,"y":4,"blur":8,"color":"#00000029"}]]}}, + {"path":"shadow.high","source":"--gnrc-shadow-high","adaptation":"Relative oklch alpha resolves to #rrggbbaa; every layer is preserved.","cool":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 6%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":4,"blur":8,"color":"#00000008"},{"x":0,"y":8,"blur":16,"color":"#0000000f"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":4,"blur":8,"color":"#0000001f"},{"x":0,"y":8,"blur":16,"color":"#0000001f"}]]},"warm":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 6%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":4,"blur":8,"color":"#00000008"},{"x":0,"y":8,"blur":16,"color":"#0000000f"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":4,"blur":8,"color":"#0000001f"},{"x":0,"y":8,"blur":16,"color":"#0000001f"}]]}}, + {"path":"shadow.higher","source":"--gnrc-shadow-higher","adaptation":"Relative oklch alpha resolves to #rrggbbaa; every layer is preserved.","cool":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 6%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 12%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":8,"blur":16,"color":"#00000008"},{"x":0,"y":16,"blur":32,"color":"#0000000f"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":8,"blur":16,"color":"#0000001f"},{"x":0,"y":16,"blur":32,"color":"#0000001f"}]]},"warm":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 6%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 12%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":8,"blur":16,"color":"#00000008"},{"x":0,"y":16,"blur":32,"color":"#0000000f"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":8,"blur":16,"color":"#0000001f"},{"x":0,"y":16,"blur":32,"color":"#0000001f"}]]}}, + {"path":"shadow.highest","source":"--gnrc-shadow-highest","adaptation":"Relative oklch alpha resolves to #rrggbbaa; every layer is preserved.","cool":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 6%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 12%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":8,"blur":16,"color":"#00000008"},{"x":0,"y":32,"blur":64,"color":"#0000000f"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":8,"blur":16,"color":"#0000001f"},{"x":0,"y":32,"blur":64,"color":"#0000001f"}]]},"warm":{"light":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 6%)","dark":"0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 12%)","native":[[{"x":0,"y":0,"blur":2,"color":"#0000001a"},{"x":0,"y":8,"blur":16,"color":"#00000008"},{"x":0,"y":32,"blur":64,"color":"#0000000f"}],[{"x":0,"y":0,"blur":2,"color":"#00000033"},{"x":0,"y":8,"blur":16,"color":"#0000001f"},{"x":0,"y":32,"blur":64,"color":"#0000001f"}]]}}, + {"path":"fontWeight.functionalRegular","source":"--gnrc-font-weight-functional-regular","adaptation":"The x3 variable weight 420 uses the native static regular weight.","cool":{"light":"420","dark":"420","native":"fontWeightRegular ('400')"},"warm":{"light":"420","dark":"420","native":"fontWeightRegular ('400')"}}, + {"path":"fontWeight.functionalMedium","source":"--gnrc-font-weight-functional-medium","adaptation":"The x3 variable weight 550 uses the native static medium weight.","cool":{"light":"550","dark":"550","native":"fontWeightMedium ('500')"},"warm":{"light":"550","dark":"550","native":"fontWeightMedium ('500')"}}, + {"path":"fontWeight.functionalSemibold","source":"--gnrc-font-weight-functional-semibold","adaptation":"The x3 variable weight 600 uses the native static semibold weight.","cool":{"light":"600","dark":"600","native":"fontWeightSemibold ('600')"},"warm":{"light":"600","dark":"600","native":"fontWeightSemibold ('600')"}}, + {"path":"fontWeight.functionalBold","source":"--gnrc-font-weight-functional-bold","adaptation":"The x3 variable weight 625 uses the native static bold weight.","cool":{"light":"625","dark":"625","native":"fontWeightBold ('700')"},"warm":{"light":"625","dark":"625","native":"fontWeightBold ('700')"}}, + {"path":"fontWeight.contentRegular","source":"--gnrc-font-weight-content-regular","adaptation":"The x3 variable weight 420 uses the native static regular weight.","cool":{"light":"420","dark":"420","native":"fontWeightRegular ('400')"},"warm":{"light":"420","dark":"420","native":"fontWeightRegular ('400')"}}, + {"path":"fontWeight.contentMedium","source":"--gnrc-font-weight-content-medium","adaptation":"The x3 variable weight 550 uses the native static medium weight.","cool":{"light":"550","dark":"550","native":"fontWeightMedium ('500')"},"warm":{"light":"550","dark":"550","native":"fontWeightMedium ('500')"}}, + {"path":"fontWeight.contentSemibold","source":"--gnrc-font-weight-content-semibold","adaptation":"The x3 variable weight 600 uses the native static semibold weight.","cool":{"light":"600","dark":"600","native":"fontWeightSemibold ('600')"},"warm":{"light":"600","dark":"600","native":"fontWeightSemibold ('600')"}}, + {"path":"fontWeight.contentBold","source":"--gnrc-font-weight-content-bold","adaptation":"The x3 variable weight 625 uses the native static bold weight.","cool":{"light":"625","dark":"625","native":"fontWeightBold ('700')"},"warm":{"light":"625","dark":"625","native":"fontWeightBold ('700')"}}, + {"path":"fontWeight.contentEditorialRegular","source":"--gnrc-font-weight-content-editorial-regular","adaptation":"The x3 variable weight 420 uses the native static regular weight.","cool":{"light":"420","dark":"420","native":"fontWeightRegular ('400')"},"warm":{"light":"420","dark":"420","native":"fontWeightRegular ('400')"}}, + {"path":"fontWeight.contentEditorialMedium","source":"--gnrc-font-weight-content-editorial-medium","adaptation":"The x3 variable weight 550 uses the native static medium weight.","cool":{"light":"550","dark":"550","native":"fontWeightMedium ('500')"},"warm":{"light":"550","dark":"550","native":"fontWeightMedium ('500')"}}, + {"path":"fontWeight.contentEditorialSemibold","source":"--gnrc-font-weight-content-editorial-semibold","adaptation":"The x3 variable weight 600 uses the native static semibold weight.","cool":{"light":"600","dark":"600","native":"fontWeightSemibold ('600')"},"warm":{"light":"600","dark":"600","native":"fontWeightSemibold ('600')"}}, + {"path":"fontWeight.contentEditorialBold","source":"--gnrc-font-weight-content-editorial-bold","adaptation":"The x3 variable weight 625 uses the native static bold weight.","cool":{"light":"625","dark":"625","native":"fontWeightBold ('700')"},"warm":{"light":"625","dark":"625","native":"fontWeightBold ('700')"}}, + {"path":"fontFamily.functional","source":"--gnrc-font-family-functional","adaptation":"The x3 sans-serif stack uses the native platform base family.","cool":{"light":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","dark":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","native":"fontFamilyBase"},"warm":{"light":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","dark":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","native":"fontFamilyBase"}}, + {"path":"fontFamily.content","source":"--gnrc-font-family-content","adaptation":"The x3 sans-serif stack uses the native platform base family.","cool":{"light":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","dark":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","native":"fontFamilyBase"},"warm":{"light":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","dark":"'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif","native":"fontFamilyBase"}}, + {"path":"fontFamily.contentEditorial","source":"--gnrc-font-family-content-editorial","adaptation":"The x3 serif stack has no portable native serif family, so it uses the platform base family.","cool":{"light":"'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif","dark":"'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif","native":"fontFamilyBase"},"warm":{"light":"'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif","dark":"'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif","native":"fontFamilyBase"}}, + {"path":"fontFamily.contentCode","source":"--gnrc-font-family-content-code","adaptation":"The x3 monospace stack uses the native platform monospace family.","cool":{"light":"'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace","dark":"'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace","native":"fontFamilyMonospace"},"warm":{"light":"'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace","dark":"'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace","native":"fontFamilyMonospace"}}, + {"path":"fontSize.functionalDisplay","source":"--gnrc-font-size-functional-display","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"4.25rem","dark":"4.25rem","native":68},"warm":{"light":"4.25rem","dark":"4.25rem","native":68}}, + {"path":"fontSize.functionalPagetitle","source":"--gnrc-font-size-functional-pagetitle","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"2.5rem","dark":"2.5rem","native":40},"warm":{"light":"2.5rem","dark":"2.5rem","native":40}}, + {"path":"fontSize.functionalTitleLarge","source":"--gnrc-font-size-functional-title-large","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"2rem","dark":"2rem","native":32},"warm":{"light":"2rem","dark":"2rem","native":32}}, + {"path":"fontSize.functionalTitleMedium","source":"--gnrc-font-size-functional-title-medium","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.75rem","dark":"1.75rem","native":28},"warm":{"light":"1.75rem","dark":"1.75rem","native":28}}, + {"path":"fontSize.functionalTitleSmall","source":"--gnrc-font-size-functional-title-small","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.5rem","dark":"1.5rem","native":24},"warm":{"light":"1.5rem","dark":"1.5rem","native":24}}, + {"path":"fontSize.functionalSubtitle","source":"--gnrc-font-size-functional-subtitle","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.25rem","dark":"1.25rem","native":20},"warm":{"light":"1.25rem","dark":"1.25rem","native":20}}, + {"path":"fontSize.functionalBodyLarge","source":"--gnrc-font-size-functional-body-large","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1rem","dark":"1rem","native":16},"warm":{"light":"1rem","dark":"1rem","native":16}}, + {"path":"fontSize.functionalBodyMedium","source":"--gnrc-font-size-functional-body-medium","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"0.875rem","dark":"0.875rem","native":14},"warm":{"light":"0.875rem","dark":"0.875rem","native":14}}, + {"path":"fontSize.functionalBodySmall","source":"--gnrc-font-size-functional-body-small","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"0.75rem","dark":"0.75rem","native":12},"warm":{"light":"0.75rem","dark":"0.75rem","native":12}}, + {"path":"fontSize.functionalCaption","source":"--gnrc-font-size-functional-caption","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"0.625rem","dark":"0.625rem","native":10},"warm":{"light":"0.625rem","dark":"0.625rem","native":10}}, + {"path":"fontSize.contentStatement","source":"--gnrc-font-size-content-statement","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"3.5rem","dark":"3.5rem","native":56},"warm":{"light":"3.5rem","dark":"3.5rem","native":56}}, + {"path":"fontSize.contentExpressiveLarge","source":"--gnrc-font-size-content-expressive-large","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"3rem","dark":"3rem","native":48},"warm":{"light":"3rem","dark":"3rem","native":48}}, + {"path":"fontSize.contentExpressiveMedium","source":"--gnrc-font-size-content-expressive-medium","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"2.25rem","dark":"2.25rem","native":36},"warm":{"light":"2.25rem","dark":"2.25rem","native":36}}, + {"path":"fontSize.contentExpressiveSmall","source":"--gnrc-font-size-content-expressive-small","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.75rem","dark":"1.75rem","native":28},"warm":{"light":"1.75rem","dark":"1.75rem","native":28}}, + {"path":"fontSize.contentH1","source":"--gnrc-font-size-content-h1","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"2.25rem","dark":"2.25rem","native":36},"warm":{"light":"2.25rem","dark":"2.25rem","native":36}}, + {"path":"fontSize.contentH2","source":"--gnrc-font-size-content-h2","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"2rem","dark":"2rem","native":32},"warm":{"light":"2rem","dark":"2rem","native":32}}, + {"path":"fontSize.contentH3","source":"--gnrc-font-size-content-h3","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.75rem","dark":"1.75rem","native":28},"warm":{"light":"1.75rem","dark":"1.75rem","native":28}}, + {"path":"fontSize.contentH4","source":"--gnrc-font-size-content-h4","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.5rem","dark":"1.5rem","native":24},"warm":{"light":"1.5rem","dark":"1.5rem","native":24}}, + {"path":"fontSize.contentH5","source":"--gnrc-font-size-content-h5","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.25rem","dark":"1.25rem","native":20},"warm":{"light":"1.25rem","dark":"1.25rem","native":20}}, + {"path":"fontSize.contentSubheadline","source":"--gnrc-font-size-content-subheadline","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1rem","dark":"1rem","native":16},"warm":{"light":"1rem","dark":"1rem","native":16}}, + {"path":"fontSize.contentParagraphLarge","source":"--gnrc-font-size-content-paragraph-large","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1.25rem","dark":"1.25rem","native":20},"warm":{"light":"1.25rem","dark":"1.25rem","native":20}}, + {"path":"fontSize.contentParagraphMedium","source":"--gnrc-font-size-content-paragraph-medium","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1rem","dark":"1rem","native":16},"warm":{"light":"1rem","dark":"1rem","native":16}}, + {"path":"fontSize.contentParagraphSmall","source":"--gnrc-font-size-content-paragraph-small","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"0.75rem","dark":"0.75rem","native":12},"warm":{"light":"0.75rem","dark":"0.75rem","native":12}}, + {"path":"fontSize.contentSubtext","source":"--gnrc-font-size-content-subtext","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"0.625rem","dark":"0.625rem","native":10},"warm":{"light":"0.625rem","dark":"0.625rem","native":10}}, + {"path":"fontSize.contentTable","source":"--gnrc-font-size-content-table","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1rem","dark":"1rem","native":16},"warm":{"light":"1rem","dark":"1rem","native":16}}, + {"path":"fontSize.contentCode","source":"--gnrc-font-size-content-code","adaptation":"1rem is 16 density-independent pixels.","cool":{"light":"1rem","dark":"1rem","native":16},"warm":{"light":"1rem","dark":"1rem","native":16}}, + {"path":"lineHeight.functionalDisplay","source":"--gnrc-line-height-functional-display","adaptation":"Resolved against fontSize.functionalDisplay (68).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":82},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":82}}, + {"path":"lineHeight.functionalPagetitle","source":"--gnrc-line-height-functional-pagetitle","adaptation":"Resolved against fontSize.functionalPagetitle (40).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":48},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":48}}, + {"path":"lineHeight.functionalTitleLarge","source":"--gnrc-line-height-functional-title-large","adaptation":"Resolved against fontSize.functionalTitleLarge (32).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":38},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":38}}, + {"path":"lineHeight.functionalTitleMedium","source":"--gnrc-line-height-functional-title-medium","adaptation":"Resolved against fontSize.functionalTitleMedium (28).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":34},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":34}}, + {"path":"lineHeight.functionalTitleSmall","source":"--gnrc-line-height-functional-title-small","adaptation":"Resolved against fontSize.functionalTitleSmall (24).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":28},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":28}}, + {"path":"lineHeight.functionalSubtitle","source":"--gnrc-line-height-functional-subtitle","adaptation":"Resolved against fontSize.functionalSubtitle (20).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":28},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":28}}, + {"path":"lineHeight.functionalBodyLarge","source":"--gnrc-line-height-functional-body-large","adaptation":"Resolved against fontSize.functionalBodyLarge (16).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22}}, + {"path":"lineHeight.functionalBodyMedium","source":"--gnrc-line-height-functional-body-medium","adaptation":"Resolved against fontSize.functionalBodyMedium (14).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":20},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":20}}, + {"path":"lineHeight.functionalBodySmall","source":"--gnrc-line-height-functional-body-small","adaptation":"Resolved against fontSize.functionalBodySmall (12).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":16},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":16}}, + {"path":"lineHeight.functionalCaption","source":"--gnrc-line-height-functional-caption","adaptation":"Resolved against fontSize.functionalCaption (10).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":14},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":14}}, + {"path":"lineHeight.contentStatement","source":"--gnrc-line-height-content-statement","adaptation":"Resolved against fontSize.contentStatement (56).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":68},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":68}}, + {"path":"lineHeight.contentExpressiveLarge","source":"--gnrc-line-height-content-expressive-large","adaptation":"Resolved against fontSize.contentExpressiveLarge (48).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":58},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":58}}, + {"path":"lineHeight.contentExpressiveMedium","source":"--gnrc-line-height-content-expressive-medium","adaptation":"Resolved against fontSize.contentExpressiveMedium (36).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":44},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":44}}, + {"path":"lineHeight.contentExpressiveSmall","source":"--gnrc-line-height-content-expressive-small","adaptation":"Resolved against fontSize.contentExpressiveSmall (28).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":34},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":34}}, + {"path":"lineHeight.contentH1","source":"--gnrc-line-height-content-h1","adaptation":"Resolved against fontSize.contentH1 (36).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":44},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":44}}, + {"path":"lineHeight.contentH2","source":"--gnrc-line-height-content-h2","adaptation":"Resolved against fontSize.contentH2 (32).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":38},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":38}}, + {"path":"lineHeight.contentH3","source":"--gnrc-line-height-content-h3","adaptation":"Resolved against fontSize.contentH3 (28).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":34},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":34}}, + {"path":"lineHeight.contentH4","source":"--gnrc-line-height-content-h4","adaptation":"Resolved against fontSize.contentH4 (24).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":28},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":28}}, + {"path":"lineHeight.contentH5","source":"--gnrc-line-height-content-h5","adaptation":"Resolved against fontSize.contentH5 (20).","cool":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":24},"warm":{"light":"round(120%, 2px)","dark":"round(120%, 2px)","native":24}}, + {"path":"lineHeight.contentSubheadline","source":"--gnrc-line-height-content-subheadline","adaptation":"Resolved against fontSize.contentSubheadline (16).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22}}, + {"path":"lineHeight.contentParagraphLarge","source":"--gnrc-line-height-content-paragraph-large","adaptation":"Resolved against fontSize.contentParagraphLarge (20).","cool":{"light":"round(170%, 2px)","dark":"round(170%, 2px)","native":34},"warm":{"light":"round(170%, 2px)","dark":"round(170%, 2px)","native":34}}, + {"path":"lineHeight.contentParagraphMedium","source":"--gnrc-line-height-content-paragraph-medium","adaptation":"Resolved against fontSize.contentParagraphMedium (16).","cool":{"light":"round(170%, 2px)","dark":"round(170%, 2px)","native":28},"warm":{"light":"round(170%, 2px)","dark":"round(170%, 2px)","native":28}}, + {"path":"lineHeight.contentParagraphSmall","source":"--gnrc-line-height-content-paragraph-small","adaptation":"Resolved against fontSize.contentParagraphSmall (12).","cool":{"light":"round(170%, 2px)","dark":"round(170%, 2px)","native":20},"warm":{"light":"round(170%, 2px)","dark":"round(170%, 2px)","native":20}}, + {"path":"lineHeight.contentSubtext","source":"--gnrc-line-height-content-subtext","adaptation":"Resolved against fontSize.contentSubtext (10).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":14},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":14}}, + {"path":"lineHeight.contentTable","source":"--gnrc-line-height-content-table","adaptation":"Resolved against fontSize.contentTable (16).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22}}, + {"path":"lineHeight.contentCode","source":"--gnrc-line-height-content-code","adaptation":"Resolved against fontSize.contentCode (16).","cool":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22},"warm":{"light":"round(140%, 2px)","dark":"round(140%, 2px)","native":22}}, + {"path":"borderRadius.base100","source":"--gnrc-border-radius-base-100","adaptation":"CSS px are density-independent pixels.","cool":{"light":"4px","dark":"4px","native":4},"warm":{"light":"4px","dark":"4px","native":4}}, + {"path":"borderRadius.base200","source":"--gnrc-border-radius-base-200","adaptation":"CSS px are density-independent pixels.","cool":{"light":"8px","dark":"8px","native":8},"warm":{"light":"8px","dark":"8px","native":8}}, + {"path":"borderRadius.base300","source":"--gnrc-border-radius-base-300","adaptation":"CSS px are density-independent pixels.","cool":{"light":"12px","dark":"12px","native":12},"warm":{"light":"12px","dark":"12px","native":12}}, + {"path":"borderRadius.base400","source":"--gnrc-border-radius-base-400","adaptation":"CSS px are density-independent pixels.","cool":{"light":"16px","dark":"16px","native":16},"warm":{"light":"16px","dark":"16px","native":16}}, + {"path":"borderRadius.base600","source":"--gnrc-border-radius-base-600","adaptation":"CSS px are density-independent pixels.","cool":{"light":"24px","dark":"24px","native":24},"warm":{"light":"24px","dark":"24px","native":24}}, + {"path":"borderRadius.base700","source":"--gnrc-border-radius-base-700","adaptation":"CSS px are density-independent pixels.","cool":{"light":"28px","dark":"28px","native":28},"warm":{"light":"28px","dark":"28px","native":28}}, + {"path":"borderRadius.circular","source":"--gnrc-border-radius-circular","adaptation":"CSS px are density-independent pixels.","cool":{"light":"9999px","dark":"9999px","native":9999},"warm":{"light":"9999px","dark":"9999px","native":9999}}, + {"path":"spacing.componentBase50","source":"--gnrc-spacing-component-base-50","adaptation":"CSS px are density-independent pixels.","cool":{"light":"2px","dark":"2px","native":2},"warm":{"light":"2px","dark":"2px","native":2}}, + {"path":"spacing.componentBase100","source":"--gnrc-spacing-component-base-100","adaptation":"CSS px are density-independent pixels.","cool":{"light":"4px","dark":"4px","native":4},"warm":{"light":"4px","dark":"4px","native":4}}, + {"path":"spacing.componentBase150","source":"--gnrc-spacing-component-base-150","adaptation":"CSS px are density-independent pixels.","cool":{"light":"6px","dark":"6px","native":6},"warm":{"light":"6px","dark":"6px","native":6}}, + {"path":"spacing.componentBase200","source":"--gnrc-spacing-component-base-200","adaptation":"CSS px are density-independent pixels.","cool":{"light":"8px","dark":"8px","native":8},"warm":{"light":"8px","dark":"8px","native":8}}, + {"path":"spacing.componentBase250","source":"--gnrc-spacing-component-base-250","adaptation":"CSS px are density-independent pixels.","cool":{"light":"10px","dark":"10px","native":10},"warm":{"light":"10px","dark":"10px","native":10}}, + {"path":"spacing.componentBase300","source":"--gnrc-spacing-component-base-300","adaptation":"CSS px are density-independent pixels.","cool":{"light":"12px","dark":"12px","native":12},"warm":{"light":"12px","dark":"12px","native":12}}, + {"path":"spacing.componentBase400","source":"--gnrc-spacing-component-base-400","adaptation":"CSS px are density-independent pixels.","cool":{"light":"16px","dark":"16px","native":16},"warm":{"light":"16px","dark":"16px","native":16}}, + {"path":"spacing.componentBase500","source":"--gnrc-spacing-component-base-500","adaptation":"CSS px are density-independent pixels.","cool":{"light":"20px","dark":"20px","native":20},"warm":{"light":"20px","dark":"20px","native":20}}, + {"path":"spacing.componentBase600","source":"--gnrc-spacing-component-base-600","adaptation":"CSS px are density-independent pixels.","cool":{"light":"24px","dark":"24px","native":24},"warm":{"light":"24px","dark":"24px","native":24}}, + {"path":"spacing.componentBase700","source":"--gnrc-spacing-component-base-700","adaptation":"CSS px are density-independent pixels.","cool":{"light":"28px","dark":"28px","native":28},"warm":{"light":"28px","dark":"28px","native":28}}, + {"path":"spacing.componentBase800","source":"--gnrc-spacing-component-base-800","adaptation":"CSS px are density-independent pixels.","cool":{"light":"32px","dark":"32px","native":32},"warm":{"light":"32px","dark":"32px","native":32}}, + {"path":"spacing.layoutBase100","source":"--gnrc-spacing-layout-base-100","adaptation":"CSS px are density-independent pixels.","cool":{"light":"8px","dark":"8px","native":8},"warm":{"light":"8px","dark":"8px","native":8}}, + {"path":"spacing.layoutBase200","source":"--gnrc-spacing-layout-base-200","adaptation":"CSS px are density-independent pixels.","cool":{"light":"16px","dark":"16px","native":16},"warm":{"light":"16px","dark":"16px","native":16}}, + {"path":"spacing.layoutBase300","source":"--gnrc-spacing-layout-base-300","adaptation":"CSS px are density-independent pixels.","cool":{"light":"24px","dark":"24px","native":24},"warm":{"light":"24px","dark":"24px","native":24}}, + {"path":"spacing.layoutBase400","source":"--gnrc-spacing-layout-base-400","adaptation":"CSS px are density-independent pixels.","cool":{"light":"32px","dark":"32px","native":32},"warm":{"light":"32px","dark":"32px","native":32}}, + {"path":"spacing.layoutBase450","source":"--gnrc-spacing-layout-base-450","adaptation":"CSS px are density-independent pixels.","cool":{"light":"36px","dark":"36px","native":36},"warm":{"light":"36px","dark":"36px","native":36}}, + {"path":"spacing.layoutBase500","source":"--gnrc-spacing-layout-base-500","adaptation":"CSS px are density-independent pixels.","cool":{"light":"40px","dark":"40px","native":40},"warm":{"light":"40px","dark":"40px","native":40}}, + {"path":"spacing.layoutBase600","source":"--gnrc-spacing-layout-base-600","adaptation":"CSS px are density-independent pixels.","cool":{"light":"48px","dark":"48px","native":48},"warm":{"light":"48px","dark":"48px","native":48}}, + {"path":"spacing.layoutBase700","source":"--gnrc-spacing-layout-base-700","adaptation":"CSS px are density-independent pixels.","cool":{"light":"56px","dark":"56px","native":56},"warm":{"light":"56px","dark":"56px","native":56}}, + {"path":"spacing.layoutBase800","source":"--gnrc-spacing-layout-base-800","adaptation":"CSS px are density-independent pixels.","cool":{"light":"64px","dark":"64px","native":64},"warm":{"light":"64px","dark":"64px","native":64}}, + {"path":"spacing.layoutBase1000","source":"--gnrc-spacing-layout-base-1000","adaptation":"CSS px are density-independent pixels.","cool":{"light":"80px","dark":"80px","native":80},"warm":{"light":"80px","dark":"80px","native":80}}, + {"path":"spacing.layoutBase1200","source":"--gnrc-spacing-layout-base-1200","adaptation":"CSS px are density-independent pixels.","cool":{"light":"96px","dark":"96px","native":96},"warm":{"light":"96px","dark":"96px","native":96}}, + {"path":"strokeWidth.thin","source":"--gnrc-stroke-width-thin","adaptation":"CSS px are density-independent pixels.","cool":{"light":"1px","dark":"1px","native":1},"warm":{"light":"1px","dark":"1px","native":1}}, + {"path":"strokeWidth.thick","source":"--gnrc-stroke-width-thick","adaptation":"CSS px are density-independent pixels.","cool":{"light":"2px","dark":"2px","native":2},"warm":{"light":"2px","dark":"2px","native":2}}, + {"path":"strokeWidth.thicker","source":"--gnrc-stroke-width-thicker","adaptation":"CSS px are density-independent pixels.","cool":{"light":"3px","dark":"3px","native":3},"warm":{"light":"3px","dark":"3px","native":3}}, + {"path":"strokeWidth.thickest","source":"--gnrc-stroke-width-thickest","adaptation":"CSS px are density-independent pixels.","cool":{"light":"4px","dark":"4px","native":4},"warm":{"light":"4px","dark":"4px","native":4}}, + {"path":"motion.durationBase50","source":"--gnrc-motion-duration-base-50","adaptation":"Durations are milliseconds.","cool":{"light":"50ms","dark":"50ms","native":50},"warm":{"light":"50ms","dark":"50ms","native":50}}, + {"path":"motion.durationBase100","source":"--gnrc-motion-duration-base-100","adaptation":"Durations are milliseconds.","cool":{"light":"100ms","dark":"100ms","native":100},"warm":{"light":"100ms","dark":"100ms","native":100}}, + {"path":"motion.durationBase200","source":"--gnrc-motion-duration-base-200","adaptation":"Durations are milliseconds.","cool":{"light":"200ms","dark":"200ms","native":200},"warm":{"light":"200ms","dark":"200ms","native":200}}, + {"path":"motion.durationBase300","source":"--gnrc-motion-duration-base-300","adaptation":"Durations are milliseconds.","cool":{"light":"300ms","dark":"300ms","native":300},"warm":{"light":"300ms","dark":"300ms","native":300}}, + {"path":"motion.durationBase500","source":"--gnrc-motion-duration-base-500","adaptation":"Durations are milliseconds.","cool":{"light":"500ms","dark":"500ms","native":500},"warm":{"light":"500ms","dark":"500ms","native":500}}, + {"path":"motion.durationBase1000","source":"--gnrc-motion-duration-base-1000","adaptation":"Durations are milliseconds.","cool":{"light":"1000ms","dark":"1000ms","native":1000},"warm":{"light":"1000ms","dark":"1000ms","native":1000}}, + {"path":"motion.easingFunctionalEnter","source":"--gnrc-motion-easing-functional-enter","adaptation":"cubic-bezier() becomes [x1, y1, x2, y2].","cool":{"light":"cubic-bezier(0, 0, 0, 1)","dark":"cubic-bezier(0, 0, 0, 1)","native":[0,0,0,1]},"warm":{"light":"cubic-bezier(0, 0, 0, 1)","dark":"cubic-bezier(0, 0, 0, 1)","native":[0,0,0,1]}}, + {"path":"motion.easingFunctionalExit","source":"--gnrc-motion-easing-functional-exit","adaptation":"cubic-bezier() becomes [x1, y1, x2, y2].","cool":{"light":"cubic-bezier(0.6, 0, 0.75, 0.4)","dark":"cubic-bezier(0.6, 0, 0.75, 0.4)","native":[0.6,0,0.75,0.4]},"warm":{"light":"cubic-bezier(0.6, 0, 0.75, 0.4)","dark":"cubic-bezier(0.6, 0, 0.75, 0.4)","native":[0.6,0,0.75,0.4]}}, + {"path":"motion.easingFunctionalTransition","source":"--gnrc-motion-easing-functional-transition","adaptation":"cubic-bezier() becomes [x1, y1, x2, y2].","cool":{"light":"cubic-bezier(0.33, 0, 0, 1)","dark":"cubic-bezier(0.33, 0, 0, 1)","native":[0.33,0,0,1]},"warm":{"light":"cubic-bezier(0.33, 0, 0, 1)","dark":"cubic-bezier(0.33, 0, 0, 1)","native":[0.33,0,0,1]}}, + {"path":"motion.easingFunctionalLinear","source":"--gnrc-motion-easing-functional-linear","adaptation":"cubic-bezier() becomes [x1, y1, x2, y2].","cool":{"light":"cubic-bezier(0, 0, 1, 1)","dark":"cubic-bezier(0, 0, 1, 1)","native":[0,0,1,1]},"warm":{"light":"cubic-bezier(0, 0, 1, 1)","dark":"cubic-bezier(0, 0, 1, 1)","native":[0,0,1,1]}}, + {"path":"motion.easingExpressiveEnter","source":"--gnrc-motion-easing-expressive-enter","adaptation":"cubic-bezier() becomes [x1, y1, x2, y2].","cool":{"light":"cubic-bezier(0, 0, 0, 1)","dark":"cubic-bezier(0, 0, 0, 1)","native":[0,0,0,1]},"warm":{"light":"cubic-bezier(0, 0, 0, 1)","dark":"cubic-bezier(0, 0, 0, 1)","native":[0,0,0,1]}}, + {"path":"motion.easingExpressiveExit","source":"--gnrc-motion-easing-expressive-exit","adaptation":"cubic-bezier() becomes [x1, y1, x2, y2].","cool":{"light":"cubic-bezier(0.6, 0, 0.75, 0.4)","dark":"cubic-bezier(0.6, 0, 0.75, 0.4)","native":[0.6,0,0.75,0.4]},"warm":{"light":"cubic-bezier(0.6, 0, 0.75, 0.4)","dark":"cubic-bezier(0.6, 0, 0.75, 0.4)","native":[0.6,0,0.75,0.4]}}, + {"path":"motion.easingExpressiveTransition","source":"--gnrc-motion-easing-expressive-transition","adaptation":"cubic-bezier() becomes [x1, y1, x2, y2].","cool":{"light":"cubic-bezier(0.33, 0, 0, 1)","dark":"cubic-bezier(0.33, 0, 0, 1)","native":[0.33,0,0,1]},"warm":{"light":"cubic-bezier(0.33, 0, 0, 1)","dark":"cubic-bezier(0.33, 0, 0, 1)","native":[0.33,0,0,1]}}, + {"path":"letterSpacing.functionalDisplay","source":"--gnrc-letter-spacing-functional-display","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0075em","dark":"-0.0075em"},"warm":{"light":"-0.0075em","dark":"-0.0075em"}}, + {"path":"letterSpacing.functionalPagetitle","source":"--gnrc-letter-spacing-functional-pagetitle","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0075em","dark":"-0.0075em"},"warm":{"light":"-0.0075em","dark":"-0.0075em"}}, + {"path":"letterSpacing.functionalTitleLarge","source":"--gnrc-letter-spacing-functional-title-large","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.functionalTitleMedium","source":"--gnrc-letter-spacing-functional-title-medium","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.functionalTitleSmall","source":"--gnrc-letter-spacing-functional-title-small","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.functionalSubtitle","source":"--gnrc-letter-spacing-functional-subtitle","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.functionalBodyLarge","source":"--gnrc-letter-spacing-functional-body-large","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.functionalBodyMedium","source":"--gnrc-letter-spacing-functional-body-medium","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.functionalBodySmall","source":"--gnrc-letter-spacing-functional-body-small","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.functionalCaption","source":"--gnrc-letter-spacing-functional-caption","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.contentStatement","source":"--gnrc-letter-spacing-content-statement","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0075em","dark":"-0.0075em"},"warm":{"light":"-0.0075em","dark":"-0.0075em"}}, + {"path":"letterSpacing.contentExpressiveLarge","source":"--gnrc-letter-spacing-content-expressive-large","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0075em","dark":"-0.0075em"},"warm":{"light":"-0.0075em","dark":"-0.0075em"}}, + {"path":"letterSpacing.contentExpressiveMedium","source":"--gnrc-letter-spacing-content-expressive-medium","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.contentExpressiveSmall","source":"--gnrc-letter-spacing-content-expressive-small","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.contentH1","source":"--gnrc-letter-spacing-content-h1","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.contentH2","source":"--gnrc-letter-spacing-content-h2","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.contentH3","source":"--gnrc-letter-spacing-content-h3","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.contentH4","source":"--gnrc-letter-spacing-content-h4","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.contentH5","source":"--gnrc-letter-spacing-content-h5","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"-0.0015em","dark":"-0.0015em"},"warm":{"light":"-0.0015em","dark":"-0.0015em"}}, + {"path":"letterSpacing.contentSubheadline","source":"--gnrc-letter-spacing-content-subheadline","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.contentParagraphLarge","source":"--gnrc-letter-spacing-content-paragraph-large","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.contentParagraphMedium","source":"--gnrc-letter-spacing-content-paragraph-medium","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.contentParagraphSmall","source":"--gnrc-letter-spacing-content-paragraph-small","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.contentSubtext","source":"--gnrc-letter-spacing-content-subtext","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.contentTable","source":"--gnrc-letter-spacing-content-table","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}}, + {"path":"letterSpacing.contentCode","source":"--gnrc-letter-spacing-content-code","status":"unsupported","reason":"The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.","cool":{"light":"0em","dark":"0em"},"warm":{"light":"0em","dark":"0em"}} + ] +} diff --git a/packages/agentic/design/scripts/flex-defaults/generate-defaults.mjs b/packages/agentic/design/scripts/flex-defaults/generate-defaults.mjs new file mode 100644 index 00000000000..cfd19fafe76 --- /dev/null +++ b/packages/agentic/design/scripts/flex-defaults/generate-defaults.mjs @@ -0,0 +1,689 @@ +// Generates the x3 Flex token defaults and their coverage ledger from the pinned x3 snapshots. +// +// node ./scripts/flex-defaults/generate-defaults.mjs write the outputs +// node ./scripts/flex-defaults/generate-defaults.mjs --check exit 1 when an output is stale +// +// Each supported Flex destination reads the generic custom property declared in flex-token-map.yaml. +// Interaction states are omitted wherever the runtime interaction policy reproduces the source value, +// so the generator imports that policy's TypeScript sources and requires Node TypeScript type stripping. +import { existsSync, readFileSync, writeFileSync } from 'node:fs'; +import * as nodeModule from 'node:module'; +import path from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; + +const scriptDir = path.dirname(fileURLToPath(import.meta.url)); +const packageRoot = path.resolve(scriptDir, '../..'); +const outputPaths = { + defaults: path.join(packageRoot, 'src/flex/defaults/defaultTokens.generated.ts'), + ledger: path.join(scriptDir, 'coverage.generated.json'), +}; +const pinPath = path.join(packageRoot, 'src/tokens/mappings/upstream-pin.json'); +const globalTokensPath = path.join(packageRoot, 'src/tokens/global.generated.ts'); +const mappingPath = 'src/tokens/mappings/flex-token-map.yaml'; +const generatorPath = 'scripts/flex-defaults/generate-defaults.mjs'; +const printWidth = 140; + +if (typeof nodeModule.registerHooks !== 'function' || !process.features.typescript) { + throw new Error(`${generatorPath} requires Node 22.18 or later with TypeScript type stripping; found ${process.version}.`); +} + +const scriptExtension = /\.[cm]?[jt]sx?$/; +// Package sources use extensionless relative imports, which Node ESM does not resolve. +nodeModule.registerHooks({ + resolve(specifier, context, nextResolve) { + if ( + (specifier.startsWith('./') || specifier.startsWith('../')) && + !scriptExtension.test(specifier) && + context.parentURL?.endsWith('.ts') + ) { + const candidate = new URL(`${specifier}.ts`, context.parentURL); + if (existsSync(fileURLToPath(candidate))) { + return nextResolve(candidate.href, context); + } + } + return nextResolve(specifier, context); + }, +}); + +const require = nodeModule.createRequire(import.meta.url); +const { createMappingProjections, loadMappingInputs } = require('../token-mappings/check-mappings.cjs'); +// The scripts package is TypeScript source, so it loads only after the Node version check. +const { CodeExpression, expression, GeneratedFile, makeComment, ValuePool } = await import('@fluentui-react-native/scripts'); +const { getInteractionColor } = await import(pathToFileURL(path.join(packageRoot, 'src/color-lib/interaction.ts')).href); +const { getInteractionCompositing, getInteractionDirection, isInteractiveColorToken } = await import( + pathToFileURL(path.join(packageRoot, 'src/flex/colors/interactiveTokens.ts')).href +); + +const tones = [ + { name: 'cool', exportName: 'coolFlexTokenInput', semantic: 'semanticCss', fallback: 'interactionFallbackCss' }, + { name: 'warm', exportName: 'warmFlexTokenInput', semantic: 'warmSemanticCss', fallback: 'warmInteractionFallbackCss' }, +]; +const schemes = ['light', 'dark']; +const interactionStates = ['hover', 'pressed']; + +// CSS parsing. Every scan is linear; no regular expression runs over source text. + +function stripComments(text) { + let result = ''; + let index = 0; + while (index < text.length) { + const start = text.indexOf('/*', index); + if (start === -1) { + return result + text.slice(index); + } + const end = text.indexOf('*/', start + 2); + if (end === -1) { + throw new Error('Unterminated CSS comment.'); + } + result += text.slice(index, start); + index = end + 2; + } + return result; +} + +function parseRules(text) { + const rules = []; + let depth = 0; + let selectorStart = 0; + let bodyStart = 0; + let selector = ''; + for (let index = 0; index < text.length; index++) { + const character = text[index]; + if (character === '{') { + if (depth === 0) { + selector = text.slice(selectorStart, index).trim(); + bodyStart = index + 1; + } + depth++; + } else if (character === '}') { + depth--; + if (depth < 0) { + throw new Error('Unbalanced CSS braces.'); + } + if (depth === 0) { + rules.push({ selector, body: text.slice(bodyStart, index) }); + selectorStart = index + 1; + } + } + } + if (depth !== 0 || text.slice(selectorStart).trim() !== '') { + throw new Error('Unbalanced CSS braces.'); + } + return rules; +} + +function parseDeclarations(body) { + const declarations = new Map(); + for (const part of body.split(';')) { + const text = part.trim(); + if (text === '') { + continue; + } + const colon = text.indexOf(':'); + if (colon === -1) { + throw new Error(`Malformed CSS declaration: ${text}`); + } + const name = text.slice(0, colon).trim(); + if (name.startsWith('--')) { + declarations.set(name, text.slice(colon + 1).trim()); + } + } + return declarations; +} + +function findClosingParenthesis(text, from) { + let depth = 1; + for (let index = from; index < text.length; index++) { + if (text[index] === '(') { + depth++; + } else if (text[index] === ')') { + depth--; + if (depth === 0) { + return index; + } + } + } + throw new Error(`Unbalanced parentheses in CSS value: ${text}`); +} + +function splitTopLevel(text, separator) { + const parts = []; + let depth = 0; + let start = 0; + for (let index = 0; index < text.length; index++) { + const character = text[index]; + if (character === '(') { + depth++; + } else if (character === ')') { + depth--; + } else if (character === separator && depth === 0) { + parts.push(text.slice(start, index).trim()); + start = index + 1; + } + } + parts.push(text.slice(start).trim()); + return parts; +} + +function selectScheme(value, scheme) { + const marker = 'light-dark('; + let result = ''; + let index = 0; + for (;;) { + const start = value.indexOf(marker, index); + if (start === -1) { + return result + value.slice(index); + } + const argumentsStart = start + marker.length; + const end = findClosingParenthesis(value, argumentsStart); + const choices = splitTopLevel(value.slice(argumentsStart, end), ','); + if (choices.length !== 2) { + throw new Error(`light-dark() needs two values: ${value}`); + } + result += value.slice(index, start) + selectScheme(choices[scheme === 'dark' ? 1 : 0], scheme); + index = end + 1; + } +} + +function sameDeclarations(left, right) { + return left.size === right.size && [...left].every(([name, value]) => right.get(name) === value); +} + +const mediaDarkSelector = '@media (prefers-color-scheme: dark)'; +const knownSelectors = new Set([':root', '[data-theme="light"]', '[data-theme="dark"]', mediaDarkSelector]); + +/** Read one adaptive sheet as resolved light and dark declarations. */ +function readAdaptiveSheet(filePath) { + const blocks = new Map(); + for (const { selector, body } of parseRules(stripComments(readFileSync(filePath, 'utf8')))) { + if (!knownSelectors.has(selector) || blocks.has(selector)) { + throw new Error(`Unexpected CSS rule "${selector}" in ${filePath}.`); + } + blocks.set(selector, body); + } + if (!blocks.has(':root')) { + throw new Error(`Missing :root rule in ${filePath}.`); + } + + const root = parseDeclarations(blocks.get(':root')); + const overrides = { + light: parseDeclarations(blocks.get('[data-theme="light"]') ?? ''), + dark: parseDeclarations(blocks.get('[data-theme="dark"]') ?? ''), + }; + if (blocks.has(mediaDarkSelector)) { + const media = parseRules(blocks.get(mediaDarkSelector)); + if (media.length !== 1 || media[0].selector !== ':root' || !sameDeclarations(parseDeclarations(media[0].body), overrides.dark)) { + throw new Error(`The prefers-color-scheme dark rule in ${filePath} must equal its [data-theme="dark"] rule.`); + } + } + + const sheet = {}; + for (const scheme of schemes) { + const declarations = new Map(); + for (const [name, value] of new Map([...root, ...overrides[scheme]])) { + declarations.set(name, selectScheme(value, scheme)); + } + sheet[scheme] = declarations; + } + return sheet; +} + +// Value conversion. + +const hexColorPattern = /^#(?:[0-9a-f]{6}|[0-9a-f]{8})$/; + +function parseHexColor(value, source) { + if (!hexColorPattern.test(value)) { + throw new Error(`${source} must be a lowercase #rrggbb or #rrggbbaa color; found "${value}".`); + } + return value; +} + +function normalizeHex(value) { + const lower = String(value).toLowerCase(); + return lower.length === 9 && lower.endsWith('ff') ? lower.slice(0, 7) : lower; +} + +function parseNumber(text, source) { + const value = Number(text); + if (text.trim() === '' || !Number.isFinite(value)) { + throw new Error(`${source} has a non-numeric value "${text}".`); + } + return value; +} + +function parseUnit(value, unit, source) { + if (!value.endsWith(unit)) { + throw new Error(`${source} must use ${unit}; found "${value}".`); + } + return parseNumber(value.slice(0, -unit.length), source); +} + +function parsePixels(value, source) { + return value.endsWith('rem') ? parseUnit(value, 'rem', source) * 16 : parseUnit(value, 'px', source); +} + +function parseFunction(value, name, source) { + const prefix = `${name}(`; + if (!value.startsWith(prefix) || !value.endsWith(')')) { + throw new Error(`${source} must be ${name}(); found "${value}".`); + } + return splitTopLevel(value.slice(prefix.length, -1), ','); +} + +function parseShadowColor(value, declarations, source) { + const prefix = 'oklch(from var('; + if (!value.startsWith(prefix)) { + return parseHexColor(value, source); + } + if (!value.endsWith(')')) { + throw new Error(`${source} has an unsupported shadow color "${value}".`); + } + const inner = value.slice(prefix.length, -1); + const close = inner.indexOf(')'); + const channels = inner.slice(close + 1).trim(); + const channelPrefix = 'l c h / '; + if (close === -1 || !channels.startsWith(channelPrefix) || !channels.endsWith('%')) { + throw new Error(`${source} may only change the alpha of a relative shadow color; found "${value}".`); + } + const baseName = inner.slice(0, close); + const base = normalizeHex(parseHexColor(declarations.get(baseName) ?? '', `${source} base ${baseName}`)); + if (base.length !== 7) { + throw new Error(`${source} base ${baseName} must be opaque.`); + } + const alpha = Math.round((parseNumber(channels.slice(channelPrefix.length, -1), source) * 255) / 100); + return `${base}${alpha.toString(16).padStart(2, '0')}`; +} + +function parseShadow(value, declarations, source) { + return splitTopLevel(value, ',').map((layer) => { + const lengths = []; + let index = 0; + while (lengths.length < 3) { + const end = layer.indexOf(' ', index); + if (end === -1) { + throw new Error(`${source} shadow layers need x, y, blur, and color; found "${layer}".`); + } + lengths.push(parsePixels(layer.slice(index, end), source)); + index = end + 1; + } + const [x, y, blur] = lengths; + return { x, y, blur, color: parseShadowColor(layer.slice(index).trim(), declarations, source) }; + }); +} + +function readFontWeights() { + const prefix = 'export const '; + const weights = new Map(); + for (const line of readFileSync(globalTokensPath, 'utf8').split('\n')) { + if (line.startsWith(`${prefix}fontWeight`)) { + const [name, value] = line.slice(prefix.length).split(' = '); + weights.set(name, value.trim().slice(1, -2)); + } + } + return weights; +} + +const nativeFontWeights = readFontWeights(); +const fontWeightRoles = [ + ['Semibold', 600, 'fontWeightSemibold'], + ['Regular', 420, 'fontWeightRegular'], + ['Medium', 550, 'fontWeightMedium'], + ['Bold', 625, 'fontWeightBold'], +]; +const fontFamilies = new Map([ + ['sans-serif', ['fontFamilyBase', 'The x3 sans-serif stack uses the native platform base family.']], + ['serif', ['fontFamilyBase', 'The x3 serif stack has no portable native serif family, so it uses the platform base family.']], + ['monospace', ['fontFamilyMonospace', 'The x3 monospace stack uses the native platform monospace family.']], +]); + +/** + * Convert one non-color source value. Returns the native value, an optional + * representation for values emitted as identifiers, and the ledger adaptation. + */ +function convertValue(group, token, value, context) { + const source = `${group}.${token}`; + switch (group) { + case 'shadow': + return { + value: parseShadow(value, context.declarations, source), + adaptation: 'Relative oklch alpha resolves to #rrggbbaa; every layer is preserved.', + }; + case 'fontWeight': { + const role = fontWeightRoles.find(([suffix]) => token.endsWith(suffix)); + if (!role) { + throw new Error(`${source} has no native font weight role.`); + } + const [roleName, sourceWeight, identifier] = role; + if (parseNumber(value, source) !== sourceWeight) { + throw new Error(`${source} changed from ${sourceWeight} to ${value}; review its native weight role.`); + } + return { + value: expression(identifier), + representation: `${identifier} ('${nativeFontWeights.get(identifier)}')`, + adaptation: `The x3 variable weight ${value} uses the native static ${roleName.toLowerCase()} weight.`, + }; + } + case 'fontFamily': { + const families = splitTopLevel(value, ','); + const family = fontFamilies.get(families[families.length - 1]); + if (!family) { + throw new Error(`${source} has an unsupported generic family in "${value}".`); + } + return { value: expression(family[0]), representation: family[0], adaptation: family[1] }; + } + case 'fontSize': + return { + value: parsePixels(value, source), + adaptation: value.endsWith('rem') ? '1rem is 16 density-independent pixels.' : 'CSS px are density-independent pixels.', + }; + case 'lineHeight': { + const [percentage, step] = parseFunction(value, 'round', source); + const fontSize = context.fontSize(token); + const stepSize = parsePixels(step, source); + return { + value: Math.round((fontSize * parseUnit(percentage, '%', source)) / (100 * stepSize)) * stepSize, + adaptation: `Resolved against fontSize.${token} (${fontSize}).`, + }; + } + case 'borderRadius': + case 'spacing': + case 'strokeWidth': + return { value: parsePixels(value, source), adaptation: 'CSS px are density-independent pixels.' }; + case 'motion': + if (token.startsWith('duration')) { + return { + value: value.endsWith('ms') ? parseUnit(value, 'ms', source) : parseUnit(value, 's', source) * 1000, + adaptation: 'Durations are milliseconds.', + }; + } + return { + value: parseFunction(value, 'cubic-bezier', source).map((part) => parseNumber(part, source)), + adaptation: 'cubic-bezier() becomes [x1, y1, x2, y2].', + }; + default: + throw new Error(`No conversion is defined for ${source}.`); + } +} + +// Resolution. + +function sameValue(left, right) { + return JSON.stringify(left) === JSON.stringify(right); +} + +function schemeEntry(light, dark) { + return sameValue(light, dark) ? light : [light, dark]; +} + +function readSource(sheet, scheme, name, source) { + const value = sheet[scheme].get(name); + if (value === undefined) { + throw new Error(`${source} reads ${name}, which the ${scheme} source does not declare.`); + } + return value; +} + +function deriveState(rest, token, state, scheme, tone) { + const result = getInteractionColor(rest, scheme, state, { + colorTone: tone, + direction: getInteractionDirection(token), + compositing: getInteractionCompositing(token), + }); + return result.status === 'derived' ? result.value : rest; +} + +function getGeneric(mappingEntries, tokenPath) { + const source = mappingEntries.get(tokenPath)?.genericSource; + if (source === undefined) { + throw new Error(`${tokenPath} has no generic source in ${mappingPath}.`); + } + return source; +} + +function resolveColor(token, context) { + const { fallback, ledger, mappingEntries, semantic, tone } = context; + const tokenPath = `color.${token}.rest`; + const record = ledger.entry(tokenPath); + const source = getGeneric(mappingEntries, tokenPath); + const rest = {}; + for (const scheme of schemes) { + rest[scheme] = normalizeHex(parseHexColor(readSource(semantic, scheme, source, tokenPath), tokenPath)); + } + record.source = source; + record[tone.name] = { light: rest.light, dark: rest.dark }; + const restEntry = schemeEntry(rest.light, rest.dark); + + if (!isInteractiveColorToken(token)) { + for (const state of interactionStates) { + const statePath = `color.${token}.${state}`; + if (mappingEntries.has(statePath)) { + throw new Error(`${statePath} is mapped, but ${token} is not interactive.`); + } + Object.assign(ledger.entry(statePath), { state: 'rest', reason: 'non-interactive' }); + } + return restEntry; + } + + const type = getInteractionDirection(token); + record.type = type; + const description = { rest: restEntry }; + for (const state of interactionStates) { + const statePath = `color.${token}.${state}`; + const stateSource = getGeneric(mappingEntries, statePath); + const values = {}; + let explicit = false; + for (const scheme of schemes) { + values[scheme] = normalizeHex(parseHexColor(readSource(fallback, scheme, stateSource, statePath), statePath)); + if (normalizeHex(deriveState(rest[scheme], token, state, scheme, tone.name)) !== values[scheme]) { + explicit = true; + } + } + const stateRecord = ledger.entry(statePath); + stateRecord.source = stateSource; + stateRecord[tone.name] = { light: values.light, dark: values.dark, state: explicit ? 'explicit' : 'computed' }; + if (explicit) { + description[state] = schemeEntry(values.light, values.dark); + } + } + if (type !== 'standard') { + description.type = type; + } + return Object.keys(description).length === 1 ? restEntry : description; +} + +function resolveTone(tone, inputs, mappingEntries, ledger) { + const semantic = readAdaptiveSheet(path.join(packageRoot, inputs.pin.get(tone.semantic).snapshotPath)); + const fallback = readAdaptiveSheet(path.join(packageRoot, inputs.pin.get(tone.fallback).snapshotPath)); + const tokens = { color: {} }; + const fontSize = (scheme) => (token) => { + const tokenPath = `fontSize.${token}`; + return convertValue('fontSize', token, readSource(semantic, scheme, getGeneric(mappingEntries, tokenPath), tokenPath)).value; + }; + + for (const tokenPath of inputs.supportedTypePaths) { + const [group, token, state] = tokenPath.split('.'); + if (group === 'color') { + if (state === 'rest') { + tokens.color[token] = resolveColor(token, { fallback, ledger, mappingEntries, semantic, tone }); + } + continue; + } + + const source = getGeneric(mappingEntries, tokenPath); + const sourceValues = {}; + const converted = {}; + for (const scheme of schemes) { + sourceValues[scheme] = readSource(semantic, scheme, source, tokenPath); + converted[scheme] = convertValue(group, token, sourceValues[scheme], { declarations: semantic[scheme], fontSize: fontSize(scheme) }); + } + if (group !== 'shadow' && !sameValue(converted.light.value, converted.dark.value)) { + throw new Error(`${tokenPath} varies by scheme; only colors and shadows may.`); + } + const value = schemeEntry(converted.light.value, converted.dark.value); + const record = ledger.entry(tokenPath); + record.source = source; + record[tone.name] = { light: sourceValues.light, dark: sourceValues.dark, native: converted.light.representation ?? value }; + record.adaptation = converted.light.adaptation; + (tokens[group] ??= {})[token] = value; + } + + for (const tokenPath of inputs.unsupportedTypePaths) { + const source = getGeneric(mappingEntries, tokenPath); + const record = ledger.entry(tokenPath); + Object.assign(record, { + source, + status: 'unsupported', + reason: 'The source is em-relative; React Native letterSpacing takes absolute points, so UnsupportedFlexTokens excludes it.', + }); + record[tone.name] = { light: readSource(semantic, 'light', source, tokenPath), dark: readSource(semantic, 'dark', source, tokenPath) }; + } + + return tokens; +} + +// Emission. + +function collectIdentifiers(value, identifiers) { + if (value instanceof CodeExpression) { + identifiers.add(value.code); + } else if (typeof value === 'object' && value !== null) { + for (const item of Object.values(value)) { + collectIdentifiers(item, identifiers); + } + } +} + +function formatImport(names, from) { + const single = `import { ${names.join(', ')} } from '${from}';`; + return single.length <= printWidth ? [single] : ['import {', ...names.map((name) => ` ${name},`), `} from '${from}';`]; +} + +function nameValue(value) { + if (typeof value === 'object' && value !== null && 'blur' in value) { + return 'shadowLayer'; + } + return undefined; +} + +/** + * Emit the tone defaults through a value pool, which shares the entries the tones hold in common through ancestor + * objects and hoists repeated values into constants, keeping the minified module small. + */ +function emitDefaults(pin, files, toneTokens) { + const identifiers = new Set(); + collectIdentifiers( + toneTokens.map(({ tokens }) => tokens), + identifiers, + ); + const file = new GeneratedFile(outputPaths.defaults); + file.header = makeComment( + [ + `Generated by ${generatorPath}. Do not edit; run \`yarn gen:flex-defaults\`.`, + `Source: ${pin.repository}@${pin.commit}`, + ...tones.map((tone) => ` ${tone.name}: ${files[tone.name].join(', ')}`), + `Generic sources: ${mappingPath}`, + `Coverage: ${path.relative(packageRoot, outputPaths.ledger).replaceAll('\\', '/')}`, + ], + 'line', + ); + const pool = new ValuePool({ name: nameValue }).reserve('CompleteFlexTokenInput'); + for (const { tone, tokens } of toneTokens) { + pool.declare(tone.exportName, tokens, { + type: 'CompleteFlexTokenInput', + comment: `The x3 ${tone.name}-tone defaults. Omitted interaction states are computed from rest.`, + }); + } + const imports = [ + ...formatImport([...identifiers].sort(), '../../tokens/global.generated'), + "import type { CompleteFlexTokenInput } from '../tokens.types';", + ]; + file.add(`\n${imports.join('\n')}\n\n`, pool); + return file.render(); +} + +function createLedger(supportedTypePaths, unsupportedTypePaths) { + const entries = new Map(); + for (const tokenPath of [...supportedTypePaths, ...unsupportedTypePaths]) { + entries.set(tokenPath, { path: tokenPath }); + } + return { + entries, + entry(tokenPath) { + const entry = entries.get(tokenPath); + if (!entry) { + throw new Error(`${tokenPath} is not a declared Flex destination.`); + } + return entry; + }, + }; +} + +const ledgerKeys = ['path', 'source', 'status', 'type', 'state', 'reason', 'adaptation', ...tones.map((tone) => tone.name)]; + +function emitLedger(pin, files, ledger) { + const header = { + generator: generatorPath, + source: { repository: pin.repository, commit: pin.commit, files }, + mapping: mappingPath, + notes: [ + 'Each tone records the light and dark source values after resolving light-dark() and [data-theme] overrides.', + 'computed: the runtime interaction policy reproduces the source state from rest, so the default omits it. explicit: the default authors the source state.', + 'Computed states equal rest in high contrast; explicit states apply in every contrast.', + 'The x3 semantic sources define no native high-contrast or elevated values; those appearances reuse the light or dark defaults.', + 'native: the emitted value; adaptation: how the source value converts to it.', + 'Theme shadows project to legacy { ambient, key } pairs from the first and last layers; that projection is lossy.', + ], + }; + const headerText = JSON.stringify(header, null, 2); + const destinations = [...ledger.entries.values()].map((entry) => { + const unknown = Object.keys(entry).filter((key) => !ledgerKeys.includes(key)); + if (unknown.length > 0) { + throw new Error(`Unordered ledger fields: ${unknown.join(', ')}.`); + } + const ordered = Object.fromEntries(ledgerKeys.filter((key) => Object.hasOwn(entry, key)).map((key) => [key, entry[key]])); + return ` ${JSON.stringify(ordered)}`; + }); + return `${headerText.slice(0, -2)},\n "destinations": [\n${destinations.join(',\n')}\n ]\n}\n`; +} + +function generate() { + const inputs = loadMappingInputs(); + const pin = JSON.parse(readFileSync(pinPath, 'utf8')); + inputs.pin = new Map(pin.files.map((file) => [file.id, file])); + const { mappingEntries, violations } = createMappingProjections(inputs.mapping, inputs.supportedTypePaths); + if (violations.length > 0) { + throw new Error(`${mappingPath} is invalid; run yarn check:mappings.`); + } + + const ledger = createLedger(inputs.supportedTypePaths, inputs.unsupportedTypePaths); + const files = {}; + const toneTokens = tones.map((tone) => { + files[tone.name] = [tone.semantic, tone.fallback].map((id) => inputs.pin.get(id).upstreamPath); + return { tone, tokens: resolveTone(tone, inputs, mappingEntries, ledger) }; + }); + + return new Map([ + [outputPaths.defaults, emitDefaults(pin, files, toneTokens)], + [outputPaths.ledger, emitLedger(pin, files, ledger)], + ]); +} + +const check = process.argv.includes('--check'); +const stale = []; +for (const [filePath, contents] of generate()) { + if (existsSync(filePath) && readFileSync(filePath, 'utf8') === contents) { + continue; + } + stale.push(path.relative(packageRoot, filePath).replaceAll('\\', '/')); + if (!check) { + writeFileSync(filePath, contents); + } +} + +if (check && stale.length > 0) { + console.error(`Stale generated Flex defaults: ${stale.join(', ')}. Run yarn gen:flex-defaults.`); + process.exitCode = 1; +} else if (!check) { + console.log(stale.length > 0 ? `Updated ${stale.join(', ')}.` : 'Generated Flex defaults are current.'); +} diff --git a/packages/agentic/design/scripts/fluent-tokens.cts b/packages/agentic/design/scripts/fluent-tokens.cts new file mode 100644 index 00000000000..418e03b8830 --- /dev/null +++ b/packages/agentic/design/scripts/fluent-tokens.cts @@ -0,0 +1,439 @@ +import type { ValuePath } from '@fluentui-react-native/scripts'; +import type { AliasColorTokens } from '../src/fluent/types/Color.types'; +import type { Variants, VariantValue } from '../src/fluent/types/Typography.types'; +const { GeneratedFile, ValuePool, expression, makeComment } = require('@fluentui-react-native/scripts'); +const path = require('node:path'); +const { mapPipelineToShadow } = require('../src/deprecated/mapPipelineToShadow.ts'); + +type Appearance = 'light' | 'dark' | 'lightElevated' | 'darkElevated' | 'hcLight' | 'hcDark'; +type ColorKey = keyof AliasColorTokens; +type PipelineTokens = Record<string, Record<string, string | number>>; + +type PlatformData = { + /** Token package directory for each appearance the platform supplies. Light supplies the font aliases. */ + paths: Partial<Record<Appearance, string>> & { light: string; dark: string }; + /** Pipeline mapper module in src/deprecated for the platform. */ + mapper: string; + filename: string; + /** Native name for a pipeline `PlatformColor(Name)` system color. Defaults to the Win32 name. */ + platformColorName?: (name: string) => string; +}; + +const appearances: Appearance[] = ['light', 'dark', 'lightElevated', 'darkElevated', 'hcLight', 'hcDark']; + +/** The color scheme of each appearance, which selects the base aliases and portable defaults beneath it. */ +const appearanceSchemes: Record<Appearance, 'light' | 'dark'> = { + light: 'light', + dark: 'dark', + lightElevated: 'light', + darkElevated: 'dark', + hcLight: 'light', + hcDark: 'dark', +}; + +/** + * Appearances to use, in order, when a platform has no token data for an appearance. A single high-contrast set + * serves both color schemes; without one, high contrast uses the standard set for its scheme. + */ +const appearanceFallbacks: Record<Exclude<Appearance, 'light' | 'dark'>, Appearance[]> = { + lightElevated: ['light'], + darkElevated: ['dark'], + hcLight: ['hcDark', 'light'], + hcDark: ['hcLight', 'dark'], +}; + +const platformPaths: Record<string, PlatformData> = { + win32: { + paths: { + light: '@fluentui-react-native/design-tokens-win32/colorful/', + dark: '@fluentui-react-native/design-tokens-win32/black/', + // Office Dark Gray serves as the elevated dark set, and the one high-contrast set of system colors as dark. + darkElevated: '@fluentui-react-native/design-tokens-win32/darkgray/', + hcDark: '@fluentui-react-native/design-tokens-win32/hc/', + }, + mapper: 'mapPipelineToTheme.ts', + filename: 'fluentTokens.generated.ts', + }, + macos: { + paths: { + light: '@fluentui-react-native/design-tokens-macos/light/', + dark: '@fluentui-react-native/design-tokens-macos/dark/', + hcLight: '@fluentui-react-native/design-tokens-macos/hclight/', + hcDark: '@fluentui-react-native/design-tokens-macos/hcdark/', + }, + mapper: 'mapPipelineToTheme.ts', + filename: 'fluentTokens.generated.macos.ts', + }, + windows: { + paths: { + light: '@fluentui-react-native/design-tokens-windows/light/', + dark: '@fluentui-react-native/design-tokens-windows/dark/', + // Windows has no high-contrast set, so it uses the Win32 system colors as Windows brushes, as the legacy tokens do. + hcDark: '@fluentui-react-native/design-tokens-win32/hc/', + }, + platformColorName: (name) => `SystemColor${name}Color`, + mapper: 'mapPipelineToTheme.ts', + filename: 'fluentTokens.generated.windows.ts', + }, + android: { + paths: { + light: '@fluentui-react-native/design-tokens-android/light/', + dark: '@fluentui-react-native/design-tokens-android/dark/', + }, + mapper: 'mapPipelineToTheme.android.ts', + filename: 'fluentTokens.generated.android.ts', + }, + ios: { + paths: { + light: '@fluentui-react-native/design-tokens-ios/light/', + dark: '@fluentui-react-native/design-tokens-ios/dark/', + hcLight: '@fluentui-react-native/design-tokens-ios/hclight/', + hcDark: '@fluentui-react-native/design-tokens-ios/hcdark/', + darkElevated: '@fluentui-react-native/design-tokens-ios/elevateddark/', + }, + mapper: 'mapPipelineToTheme.ios.ts', + filename: 'fluentTokens.generated.ios.ts', + }, +}; + +const colorEquivalents: Partial<Record<ColorKey, ColorKey[]>> = { + neutralForeground4: ['neutralForeground3'], + neutralForegroundDisabled: ['neutralForegroundDisabled1'], + neutralForegroundDisabled1: ['neutralForegroundDisabled'], + neutralForegroundDisabled2: ['neutralForegroundDisabled1'], + neutralForegroundOnBrand: ['neutralForegroundOnColor'], + neutralForegroundOnColor: ['neutralForegroundOnBrand'], + neutralForegroundInverted: ['neutralForegroundOnColor'], + neutralForegroundInvertedLink: ['neutralForegroundInverted'], + brandForegroundLink: ['brandForeground1'], + compoundBrandForeground1: ['brandForeground1'], + brandForeground2: ['brandForeground1'], + brandForegroundTint: ['brandForeground2'], + brandForeground1Disabled: ['brandForegroundDisabled1', 'neutralForegroundDisabled'], + brandForegroundDisabled1: ['brandForeground1Disabled', 'neutralForegroundDisabled1'], + brandForegroundDisabled2: ['brandForegroundDisabled1'], + neutralBackgroundCanvas: ['neutralBackground1'], + neutralBackgroundLightStaticDisabled: ['neutralBackgroundDisabled'], + brandBackground2: ['brandBackground'], + brandBackground3: ['brandBackground2'], + brandBackgroundTint: ['brandBackground2'], + brandBackgroundInverted: ['neutralBackgroundInverted'], + brandBackgroundInvertedDisabled: ['neutralBackgroundDisabled'], + brandBackgroundDisabled: ['neutralBackgroundDisabled'], + compoundBrandBackground1: ['brandBackground'], + brandBackgroundStatic: ['brandBackground'], + neutralStroke3: ['neutralStroke2'], + neutralStrokeFocus1: ['strokeFocus1'], + neutralStrokeFocus2: ['strokeFocus2'], + strokeFocus1: ['neutralStrokeFocus1'], + strokeFocus2: ['neutralStrokeFocus2'], + brandStroke2: ['brandStrokeTint', 'brandStroke1'], + brandStrokeTint: ['brandStroke2'], + compoundBrandStroke1: ['brandStroke1'], + dangerStroke1: ['dangerBorder1', 'dangerForeground1'], + successStroke1: ['successBorder1', 'successForeground1'], + warningStroke1: ['warningBorder1', 'warningForeground1'], + severeStroke1: ['severeBorder1', 'severeForeground1'], + dangerBorder1: ['dangerStroke1'], + successBorder1: ['successStroke1'], + warningBorder1: ['warningStroke1'], + severeBorder1: ['severeStroke1'], + presenceAway: ['warningForeground1'], + presenceDnd: ['dangerForeground1'], + presenceAvailable: ['successForeground1'], + presenceOof: ['outofofficeForeground1'], + redBackground1: ['dangerBackground1'], + redBackground2: ['dangerBackground2'], + redBackground3: ['dangerBackground3'], + redForeground1: ['dangerForeground1'], + redForeground2: ['dangerForeground2'], + redForeground3: ['dangerForeground3'], + redBorderActive: ['dangerBorderActive'], + redBorder1: ['dangerBorder1'], + redBorder2: ['dangerBorder2'], +}; + +function colorCandidates(key: ColorKey): ColorKey[] { + if (colorEquivalents[key]) { + return colorEquivalents[key]; + } + const state = /(?:Brand)?(?:Hover|Pressed|Selected|Disabled)$/.exec(key); + if (!state) { + return []; + } + const rest = key.slice(0, state.index) as ColorKey; + return [...(colorEquivalents[rest] ?? []).map((candidate) => (candidate + state[0]) as ColorKey), rest]; +} + +function definedEntries<T>(values: Record<string, T | undefined>): Record<string, T> { + return Object.fromEntries(Object.entries(values).filter((entry): entry is [string, T] => entry[1] !== undefined)); +} + +function mapColors(tokens: PipelineTokens, mapper: string, keys?: Set<ColorKey>): Record<string, string> { + const { mapPipelineToTheme } = require(`../src/deprecated/${mapper}`); + const colors = definedEntries<string>(mapPipelineToTheme(tokens)); + // Keep native states that a legacy mapper omits, but do not add keys outside the alias contract. + if (keys) { + for (const [token, states] of Object.entries(tokens)) { + if (!('rest' in states)) { + continue; + } + const name = token === 'brandBackground1' ? 'brandBackground' : token; + for (const [state, value] of Object.entries(states)) { + const key = ( + state === 'rest' + ? name + : name === 'transparentStroke' && state === 'hover' + ? 'transparentStrokeInteractive' + : name + state[0].toUpperCase() + state.slice(1) + ) as ColorKey; + if (keys.has(key) && colors[key] === undefined) { + colors[key] = value as string; + } + } + } + } + return colors; +} + +function completeColors(native: Record<string, string>, fallback: Record<string, string>, keys: Set<ColorKey>) { + function fromNative(key: ColorKey, visiting = new Set<ColorKey>()): string | undefined { + if (native[key] !== undefined) { + return native[key]; + } + if (visiting.has(key)) { + return undefined; + } + visiting.add(key); + for (const candidate of colorCandidates(key)) { + const value = fromNative(candidate, visiting); + if (value !== undefined) { + return value; + } + } + return undefined; + } + return Object.fromEntries( + [...keys].map((key) => { + const value = fromNative(key) ?? fallback[key]; + if (value === undefined) { + throw new Error(`Missing Fluent color token: ${key}`); + } + return [key, value]; + }), + ); +} + +// Desktop pipelines without font aliases use their own global ramp, not another platform's font family. +const fontRamp: Record<string, [number, string]> = { + caption1: [100, 'regular'], + caption1Strong: [100, 'semibold'], + caption2: [100, 'regular'], + body1: [200, 'regular'], + body1Strong: [200, 'semibold'], + body2: [300, 'regular'], + body2Strong: [300, 'semibold'], + subtitle1: [500, 'regular'], + subtitle1Strong: [500, 'semibold'], + subtitle2: [400, 'regular'], + subtitle2Strong: [400, 'semibold'], + title1: [700, 'regular'], + title1Strong: [700, 'semibold'], + title2: [600, 'regular'], + title3: [500, 'regular'], + largeTitle: [900, 'regular'], + display: [900, 'semibold'], +}; +const fontEquivalents: Record<string, string> = { + caption1Strong: 'caption1', + caption2: 'caption1', + subtitle1: 'title2', + subtitle1Strong: 'title2', + subtitle2: 'title3', + subtitle2Strong: 'title3', + title1Strong: 'title1', + title2: 'subtitle1', + title3: 'subtitle2', +}; +const legacyFontAliases: Record<string, string> = { + captionStandard: 'caption1', + secondaryStandard: 'body1', + secondarySemibold: 'body1Strong', + bodyStandard: 'body2', + bodySemibold: 'body2Strong', + subheaderStandard: 'subtitle2', + subheaderSemibold: 'subtitle2Strong', + headerStandard: 'subtitle1', + headerSemibold: 'subtitle1Strong', + heroStandard: 'title1', + heroSemibold: 'title1Strong', + heroLargeStandard: 'largeTitle', + heroLargeSemibold: 'display', +}; + +function mapFonts(platformData: PlatformData): Record<string, VariantValue> { + const { mapFontPipelineToTheme } = require(`../src/deprecated/${platformData.mapper}`); + const { font } = require(`${platformData.paths.light}tokens-global.json`); + const defaults = Object.fromEntries( + Object.entries(fontRamp).map(([name, [size, weight]]) => [ + name, + { fontFamily: font.family.base ?? font.family.default, fontSize: font[`size${size}`], fontWeight: font.weight[weight] }, + ]), + ); + const tokens = { ...defaults, ...require(`${platformData.paths.light}tokens-aliases.json`) }; + const native: Partial<Variants> = mapFontPipelineToTheme(tokens); + const variants = { ...native } as Record<string, VariantValue>; + for (const key of Object.keys(fontRamp)) { + if (!variants[key]) { + const equivalent = native[fontEquivalents[key] as keyof Variants]; + const token = tokens[key]; + variants[key] = equivalent + ? { ...equivalent, ...(key.endsWith('Strong') ? { weight: font.weight.semibold } : {}) } + : { face: 'primary', size: token.fontSize, weight: token.fontWeight }; + } + } + for (const [key, alias] of Object.entries(legacyFontAliases)) { + variants[key] = variants[alias]; + } + return variants; +} + +/** The appearance whose token data supplies an appearance: its own, or the first fallback the platform supplies. */ +function sourceAppearance(platformData: PlatformData, appearance: Appearance): Appearance { + const candidates = appearance === 'light' || appearance === 'dark' ? [appearance] : [appearance, ...appearanceFallbacks[appearance]]; + const source = candidates.find((candidate) => platformData.paths[candidate]); + if (!source) { + throw new Error(`No token data for the ${appearance} appearance`); + } + return source; +} + +function sourcePath(platformData: PlatformData, appearance: Appearance): string { + return platformData.paths[sourceAppearance(platformData, appearance)] as string; +} + +function appearanceScheme(platformData: PlatformData, appearance: Appearance): 'light' | 'dark' { + return appearanceSchemes[sourceAppearance(platformData, appearance)]; +} + +function readAliases(platformData: PlatformData, appearance: Appearance): PipelineTokens { + const scheme = appearanceScheme(platformData, appearance); + const base: PipelineTokens = require(`${platformData.paths[scheme]}tokens-aliases.json`); + const tokens: PipelineTokens = require(`${sourcePath(platformData, appearance)}tokens-aliases.json`); + return Object.fromEntries( + [...new Set([...Object.keys(base), ...Object.keys(tokens)])].map((key) => [key, { ...base[key], ...tokens[key] }]), + ); +} + +const platformColorPattern = /^PlatformColor\(([A-Za-z][A-Za-z0-9]*)\)$/; + +/** + * Replace the pipeline's `PlatformColor(Name)` strings with PlatformColor calls of the platform's system color names, as + * processAliasTokens does at runtime. + */ +function toCodeValues(value: unknown, platformColors: Set<string>, colorName: (name: string) => string): unknown { + if (typeof value === 'string') { + const match = platformColorPattern.exec(value); + if (!match) { + if (value.includes('PlatformColor')) { + throw new Error(`Unsupported platform color value: ${value}`); + } + return value; + } + const name = colorName(match[1]); + platformColors.add(name); + return expression(`PlatformColor('${name}')`, { pure: true, name: `platformColor${match[1]}` }); + } + if (Array.isArray(value)) { + return value.map((item) => toCodeValues(item, platformColors, colorName)); + } + if (value && typeof value === 'object') { + return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, toCodeValues(item, platformColors, colorName)])); + } + return value; +} + +function nameValue(value: unknown, valuePath: ValuePath): string | undefined { + if (value && typeof value === 'object' && 'blur' in value) { + return 'shadowLayer'; + } + return typeof value === 'string' && valuePath[valuePath.length - 1] === 'weight' ? `fontWeight${value}` : undefined; +} + +function generatePlatformFluentTokens( + platformData: PlatformData, + colorKeys: Set<ColorKey>, + fallbackColors: Record<'light' | 'dark', Record<string, string>>, +) { + const target = path.join(__dirname, '../src/fluent/defaults', platformData.filename); + const generatedFile = new GeneratedFile(target); + generatedFile.header = makeComment([ + 'WARNING: This file is auto-generated by scripts/fluent-tokens.cts. Do not edit it manually.', + 'Complete Fluent tokens: native values, same-platform equivalents, then same-scheme portable defaults.', + 'An appearance without token data inherits elevated from standard, and high contrast from the other', + 'high-contrast appearance, else from standard. Shared values are emitted once.', + ]); + const pool = new ValuePool({ name: nameValue }); + const typeImports = { + AliasColorTokens: '../types/Color.types', + BaseShadowAliasTokens: '../types/Shadow.types', + Variants: '../types/Typography.types', + }; + pool.reserve(...Object.keys(typeImports)); + + // Appearances with token data come first, so each inherited appearance is emitted as an alias of its source. + const ordered = [ + ...appearances.filter((appearance) => platformData.paths[appearance]), + ...appearances.filter((appearance) => !platformData.paths[appearance]), + ]; + const platformColors = new Set<string>(); + for (const appearance of ordered) { + pool.declare(`${appearance}Shadows`, mapPipelineToShadow(require(`${sourcePath(platformData, appearance)}tokens-shadow.json`)), { + type: 'BaseShadowAliasTokens', + }); + } + for (const appearance of ordered) { + const native = mapColors(readAliases(platformData, appearance), platformData.mapper, colorKeys); + const scheme = appearanceScheme(platformData, appearance); + const colors = completeColors(native, fallbackColors[scheme], colorKeys); + pool.declare(`${appearance}AliasColors`, toCodeValues(colors, platformColors, platformData.platformColorName ?? ((name) => name)), { + type: 'Required<AliasColorTokens>', + }); + } + pool.declare('fontAliasTokens', mapFonts(platformData), { + type: 'Required<Variants>', + comment: 'Font aliases from the light appearance, completed with native equivalents and the platform global ramp.', + }); + + const imports = Object.entries(typeImports).map(([name, from]) => `import type { ${name} } from '${from}';\n`); + if (platformColors.size > 0) { + imports.unshift("import { PlatformColor } from 'react-native';\n\n"); + } + generatedFile.add(...imports, '\n', pool); + generatedFile.commit(); +} + +function codegenFluentTokens() { + const colorKeys = new Set<ColorKey>(Object.keys(colorEquivalents) as ColorKey[]); + for (const platform of Object.values(platformPaths)) { + for (const key of Object.keys(mapColors(readAliases(platform, 'light'), platform.mapper))) { + colorKeys.add(key as ColorKey); + } + } + const fallbackColors = Object.fromEntries( + (['light', 'dark'] as const).map((appearance) => { + const colors = Object.assign( + {}, + ...['android', 'ios', 'win32'].map((platform) => + mapColors(readAliases(platformPaths[platform], appearance), platformPaths[platform].mapper, colorKeys), + ), + ); + return [appearance, completeColors(colors, {}, colorKeys)]; + }), + ) as Record<'light' | 'dark', Record<string, string>>; + for (const platform of Object.values(platformPaths)) { + generatePlatformFluentTokens(platform, colorKeys, fallbackColors); + } +} + +module.exports = { codegenFluentTokens }; diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/interaction-fallback-dark.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/interaction-fallback-dark.css new file mode 100644 index 00000000000..f4d6af7fdcd --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/interaction-fallback-dark.css @@ -0,0 +1,130 @@ +/* Fluent Design — Interaction Fallback (Dark Theme) — precomputed hex and shadows for non-OKLCH environments + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +[data-theme="dark"] { + --gnrc-color-surface-neutral-farther-hover: #2f2f2f; + --gnrc-color-surface-neutral-farther-pressed: #454545; + --gnrc-color-surface-neutral-far-hover: #323232; + --gnrc-color-surface-neutral-far-pressed: #464646; + --gnrc-color-surface-neutral-near-hover: #2d2d2d; + --gnrc-color-surface-neutral-near-pressed: #434343; + --gnrc-color-surface-neutral-nearer-hover: #3a3a3a; + --gnrc-color-surface-neutral-nearer-pressed: #4b4b4b; + --gnrc-color-surface-neutral-translucent-hover: #47474788; + --gnrc-color-surface-neutral-translucent-pressed: #5353538f; + --gnrc-color-background-neutral-heavy-hover: #f5f5f5; + --gnrc-color-background-neutral-heavy-pressed: #ebebeb; + --gnrc-color-background-neutral-loud-hover: #898989; + --gnrc-color-background-neutral-loud-pressed: #808080; + --gnrc-color-background-neutral-soft-hover: #ffffff27; + --gnrc-color-background-neutral-soft-pressed: #ffffff2e; + --gnrc-color-background-neutral-subtle-hover: #ffffff1c; + --gnrc-color-background-neutral-subtle-pressed: #ffffff23; + --gnrc-color-background-neutral-transparent-hover: #ffffff08; + --gnrc-color-background-neutral-transparent-pressed: #ffffff0f; + --gnrc-color-background-neutral-translucent-hover: #56565688; + --gnrc-color-background-neutral-translucent-pressed: #6d6d6d8f; + --gnrc-color-background-brand-heavy-hover: #f5f5f5; + --gnrc-color-background-brand-heavy-pressed: #ebebeb; + --gnrc-color-background-brand-loud-hover: #898989; + --gnrc-color-background-brand-loud-pressed: #808080; + --gnrc-color-background-brand-soft-hover: #ffffff27; + --gnrc-color-background-brand-soft-pressed: #ffffff2e; + --gnrc-color-background-brand-subtle-hover: #ffffff1c; + --gnrc-color-background-brand-subtle-pressed: #ffffff23; + --gnrc-color-background-brand-transparent-hover: #ffffff08; + --gnrc-color-background-brand-transparent-pressed: #ffffff0f; + --gnrc-color-background-danger-loud-hover: #da5471; + --gnrc-color-background-danger-loud-pressed: #d04b69; + --gnrc-color-background-danger-soft-hover: #67353e; + --gnrc-color-background-danger-soft-pressed: #754149; + --gnrc-color-background-danger-subtle-hover: #503438; + --gnrc-color-background-danger-subtle-pressed: #614448; + --gnrc-color-background-warning-loud-hover: #da5d2e; + --gnrc-color-background-warning-loud-pressed: #d05422; + --gnrc-color-background-warning-soft-hover: #663828; + --gnrc-color-background-warning-soft-pressed: #744434; + --gnrc-color-background-warning-subtle-hover: #51352c; + --gnrc-color-background-warning-subtle-pressed: #62453b; + --gnrc-color-background-success-loud-hover: #00a369; + --gnrc-color-background-success-loud-pressed: #009a60; + --gnrc-color-background-success-soft-hover: #1c5238; + --gnrc-color-background-success-soft-pressed: #295f44; + --gnrc-color-background-success-subtle-hover: #294435; + --gnrc-color-background-success-subtle-pressed: #385445; + --gnrc-color-stroke-neutral-heavy-hover: #d4d4d4; + --gnrc-color-stroke-neutral-heavy-pressed: #cbcbcb; + --gnrc-color-stroke-neutral-loud-hover: #898989; + --gnrc-color-stroke-neutral-loud-pressed: #808080; + --gnrc-color-stroke-neutral-soft-hover: #ffffff69; + --gnrc-color-stroke-neutral-soft-pressed: #ffffff70; + --gnrc-color-stroke-neutral-subtle-hover: #ffffff50; + --gnrc-color-stroke-neutral-subtle-pressed: #ffffff57; + --gnrc-color-stroke-neutral-transparent-hover: #ffffff08; + --gnrc-color-stroke-neutral-transparent-pressed: #ffffff0f; + --gnrc-color-stroke-neutral-onloud-hover: #000000db; + --gnrc-color-stroke-neutral-onloud-pressed: #000000db; + --gnrc-color-stroke-brand-loud-hover: #898989; + --gnrc-color-stroke-brand-loud-pressed: #808080; + --gnrc-color-stroke-brand-soft-hover: #ffffff69; + --gnrc-color-stroke-brand-soft-pressed: #ffffff70; + --gnrc-color-stroke-brand-subtle-hover: #ffffff50; + --gnrc-color-stroke-brand-subtle-pressed: #ffffff57; + --gnrc-color-stroke-brand-onloud-hover: #131313; + --gnrc-color-stroke-brand-onloud-pressed: #050505; + --gnrc-color-stroke-danger-loud-hover: #da5471; + --gnrc-color-stroke-danger-loud-pressed: #d04b69; + --gnrc-color-stroke-danger-soft-hover: #dc4b6d; + --gnrc-color-stroke-danger-soft-pressed: #e65575; + --gnrc-color-stroke-danger-subtle-hover: #803242; + --gnrc-color-stroke-danger-subtle-pressed: #893a4a; + --gnrc-color-stroke-danger-onloud-hover: #131313; + --gnrc-color-stroke-danger-onloud-pressed: #050505; + --gnrc-color-stroke-warning-loud-hover: #da5d2e; + --gnrc-color-stroke-warning-loud-pressed: #d05422; + --gnrc-color-stroke-warning-soft-hover: #d8521a; + --gnrc-color-stroke-warning-soft-pressed: #e25c27; + --gnrc-color-stroke-warning-subtle-hover: #7f371b; + --gnrc-color-stroke-warning-subtle-pressed: #893f24; + --gnrc-color-stroke-warning-onloud-hover: #131313; + --gnrc-color-stroke-warning-onloud-pressed: #050505; + --gnrc-color-stroke-success-loud-hover: #00a369; + --gnrc-color-stroke-success-loud-pressed: #009a60; + --gnrc-color-stroke-success-soft-hover: #1a9765; + --gnrc-color-stroke-success-soft-pressed: #2aa16d; + --gnrc-color-stroke-success-subtle-hover: #125f3e; + --gnrc-color-stroke-success-subtle-pressed: #1e6746; + --gnrc-color-stroke-success-onloud-hover: #131313; + --gnrc-color-stroke-success-onloud-pressed: #050505; + --gnrc-color-foreground-neutral-primary-hover: #ffffffe6; + --gnrc-color-foreground-neutral-primary-pressed: #ffffffed; + --gnrc-color-foreground-neutral-secondary-hover: #ffffffa9; + --gnrc-color-foreground-neutral-secondary-pressed: #ffffffb0; + --gnrc-color-foreground-neutral-tertiary-hover: #ffffff88; + --gnrc-color-foreground-neutral-tertiary-pressed: #ffffff8f; + --gnrc-color-foreground-neutral-onloud-hover: #000000db; + --gnrc-color-foreground-neutral-onloud-pressed: #000000db; + --gnrc-color-foreground-brand-primary-hover: #e8e8e8; + --gnrc-color-foreground-brand-primary-pressed: #f2f2f2; + --gnrc-color-foreground-brand-onloud-hover: #000000db; + --gnrc-color-foreground-brand-onloud-pressed: #000000db; + --gnrc-color-foreground-danger-primary-hover: #ff97aa; + --gnrc-color-foreground-danger-primary-pressed: #ffa1b4; + --gnrc-color-foreground-danger-onloud-hover: #000000db; + --gnrc-color-foreground-danger-onloud-pressed: #000000db; + --gnrc-color-foreground-warning-primary-hover: #ff9f7a; + --gnrc-color-foreground-warning-primary-pressed: #ffa884; + --gnrc-color-foreground-warning-onloud-hover: #000000db; + --gnrc-color-foreground-warning-onloud-pressed: #000000db; + --gnrc-color-foreground-success-primary-hover: #67d8a0; + --gnrc-color-foreground-success-primary-pressed: #72e2aa; + --gnrc-color-foreground-success-onloud-hover: #000000db; + --gnrc-color-foreground-success-onloud-pressed: #000000db; + --gnrc-shadow-lowest: 0px 0px 2px #00000033, 0px 1px 2px #0000001a; + --gnrc-shadow-lower: 0px 0px 2px #00000033, 0px 2px 4px #00000029; + --gnrc-shadow-low: 0px 0px 2px #00000033, 0px 2px 4px #0000001f, 0px 4px 8px #00000029; + --gnrc-shadow-high: 0px 0px 2px #00000033, 0px 4px 8px #0000001f, 0px 8px 16px #0000001f; + --gnrc-shadow-higher: 0px 0px 2px #00000033, 0px 8px 16px #0000001f, 0px 16px 32px #0000001f; + --gnrc-shadow-highest: 0px 0px 2px #00000033, 0px 8px 16px #0000001f, 0px 32px 64px #0000001f; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/interaction-fallback-light.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/interaction-fallback-light.css new file mode 100644 index 00000000000..87f488d731b --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/interaction-fallback-light.css @@ -0,0 +1,130 @@ +/* Fluent Design — Interaction Fallback (Light Theme) — precomputed hex and shadows for non-OKLCH environments + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +:root, [data-theme="light"] { + --gnrc-color-surface-neutral-farther-hover: #e1e1e1; + --gnrc-color-surface-neutral-farther-pressed: #d7d7d7; + --gnrc-color-surface-neutral-far-hover: #e8e8e8; + --gnrc-color-surface-neutral-far-pressed: #dedede; + --gnrc-color-surface-neutral-near-hover: #f2f2f2; + --gnrc-color-surface-neutral-near-pressed: #e8e8e8; + --gnrc-color-surface-neutral-nearer-hover: #f5f5f5; + --gnrc-color-surface-neutral-nearer-pressed: #ebebeb; + --gnrc-color-surface-neutral-translucent-hover: #f5f5f58a; + --gnrc-color-surface-neutral-translucent-pressed: #ebebeb94; + --gnrc-color-background-neutral-heavy-hover: #363636; + --gnrc-color-background-neutral-heavy-pressed: #494949; + --gnrc-color-background-neutral-loud-hover: #787878; + --gnrc-color-background-neutral-loud-pressed: #818181; + --gnrc-color-background-neutral-soft-hover: #0000001e; + --gnrc-color-background-neutral-soft-pressed: #00000028; + --gnrc-color-background-neutral-subtle-hover: #00000017; + --gnrc-color-background-neutral-subtle-pressed: #00000021; + --gnrc-color-background-neutral-transparent-hover: #1313130a; + --gnrc-color-background-neutral-transparent-pressed: #05050514; + --gnrc-color-background-neutral-translucent-hover: #d8d8d88a; + --gnrc-color-background-neutral-translucent-pressed: #cacaca94; + --gnrc-color-background-brand-heavy-hover: #363636; + --gnrc-color-background-brand-heavy-pressed: #494949; + --gnrc-color-background-brand-loud-hover: #787878; + --gnrc-color-background-brand-loud-pressed: #818181; + --gnrc-color-background-brand-soft-hover: #0000001e; + --gnrc-color-background-brand-soft-pressed: #00000028; + --gnrc-color-background-brand-subtle-hover: #00000014; + --gnrc-color-background-brand-subtle-pressed: #0000001e; + --gnrc-color-background-brand-transparent-hover: #1313130a; + --gnrc-color-background-brand-transparent-pressed: #05050514; + --gnrc-color-background-danger-loud-hover: #cb395e; + --gnrc-color-background-danger-loud-pressed: #d54467; + --gnrc-color-background-danger-soft-hover: #f5d9dc; + --gnrc-color-background-danger-soft-pressed: #ebcfd2; + --gnrc-color-background-danger-subtle-hover: #f5e7e9; + --gnrc-color-background-danger-subtle-pressed: #ebdddf; + --gnrc-color-background-warning-loud-hover: #c54a14; + --gnrc-color-background-warning-loud-pressed: #d05321; + --gnrc-color-background-warning-soft-hover: #f5dbd2; + --gnrc-color-background-warning-soft-pressed: #ebd1c9; + --gnrc-color-background-warning-subtle-hover: #f5e8e4; + --gnrc-color-background-warning-subtle-pressed: #ebdeda; + --gnrc-color-background-success-loud-hover: #188d5d; + --gnrc-color-background-success-loud-pressed: #279666; + --gnrc-color-background-success-soft-hover: #bfeed3; + --gnrc-color-background-success-soft-pressed: #b6e4ca; + --gnrc-color-background-success-subtle-hover: #d9f2e4; + --gnrc-color-background-success-subtle-pressed: #cfe8da; + --gnrc-color-stroke-neutral-heavy-hover: #363636; + --gnrc-color-stroke-neutral-heavy-pressed: #494949; + --gnrc-color-stroke-neutral-loud-hover: #787878; + --gnrc-color-stroke-neutral-loud-pressed: #818181; + --gnrc-color-stroke-neutral-soft-hover: #02020277; + --gnrc-color-stroke-neutral-soft-pressed: #04040481; + --gnrc-color-stroke-neutral-subtle-hover: #0000002b; + --gnrc-color-stroke-neutral-subtle-pressed: #05050535; + --gnrc-color-stroke-neutral-transparent-hover: #1313130a; + --gnrc-color-stroke-neutral-transparent-pressed: #05050514; + --gnrc-color-stroke-neutral-onloud-hover: #ffffff; + --gnrc-color-stroke-neutral-onloud-pressed: #ffffff; + --gnrc-color-stroke-brand-loud-hover: #787878; + --gnrc-color-stroke-brand-loud-pressed: #818181; + --gnrc-color-stroke-brand-soft-hover: #02020277; + --gnrc-color-stroke-brand-soft-pressed: #04040481; + --gnrc-color-stroke-brand-subtle-hover: #0000002b; + --gnrc-color-stroke-brand-subtle-pressed: #05050535; + --gnrc-color-stroke-brand-onloud-hover: #ffffff; + --gnrc-color-stroke-brand-onloud-pressed: #ffffff; + --gnrc-color-stroke-danger-loud-hover: #cb395e; + --gnrc-color-stroke-danger-loud-pressed: #d54467; + --gnrc-color-stroke-danger-soft-hover: #da5471; + --gnrc-color-stroke-danger-soft-pressed: #d04b69; + --gnrc-color-stroke-danger-subtle-hover: #f5c6cc; + --gnrc-color-stroke-danger-subtle-pressed: #ebbdc3; + --gnrc-color-stroke-danger-onloud-hover: #ffffff; + --gnrc-color-stroke-danger-onloud-pressed: #ffffff; + --gnrc-color-stroke-warning-loud-hover: #d8521a; + --gnrc-color-stroke-warning-loud-pressed: #e25c27; + --gnrc-color-stroke-warning-soft-hover: #f28c68; + --gnrc-color-stroke-warning-soft-pressed: #e7825f; + --gnrc-color-stroke-warning-subtle-hover: #f5c9ba; + --gnrc-color-stroke-warning-subtle-pressed: #ebc0b1; + --gnrc-color-stroke-warning-onloud-hover: #ffffff; + --gnrc-color-stroke-warning-onloud-pressed: #ffffff; + --gnrc-color-stroke-success-loud-hover: #188d5d; + --gnrc-color-stroke-success-loud-pressed: #279666; + --gnrc-color-stroke-success-soft-hover: #52c48e; + --gnrc-color-stroke-success-soft-pressed: #47bb85; + --gnrc-color-stroke-success-subtle-hover: #a7e5c2; + --gnrc-color-stroke-success-subtle-pressed: #9edbb9; + --gnrc-color-stroke-success-onloud-hover: #ffffff; + --gnrc-color-stroke-success-onloud-pressed: #ffffff; + --gnrc-color-foreground-neutral-primary-hover: #000000e5; + --gnrc-color-foreground-neutral-primary-pressed: #000000ef; + --gnrc-color-foreground-neutral-secondary-hover: #000000ac; + --gnrc-color-foreground-neutral-secondary-pressed: #000000b6; + --gnrc-color-foreground-neutral-tertiary-hover: #0000009a; + --gnrc-color-foreground-neutral-tertiary-pressed: #000000a4; + --gnrc-color-foreground-neutral-onloud-hover: #ffffff; + --gnrc-color-foreground-neutral-onloud-pressed: #ffffff; + --gnrc-color-foreground-brand-primary-hover: #131313; + --gnrc-color-foreground-brand-primary-pressed: #050505; + --gnrc-color-foreground-brand-onloud-hover: #ffffff; + --gnrc-color-foreground-brand-onloud-pressed: #ffffff; + --gnrc-color-foreground-danger-primary-hover: #9c133f; + --gnrc-color-foreground-danger-primary-pressed: #910037; + --gnrc-color-foreground-danger-onloud-hover: #ffffff; + --gnrc-color-foreground-danger-onloud-pressed: #ffffff; + --gnrc-color-foreground-warning-primary-hover: #9f2f00; + --gnrc-color-foreground-warning-primary-pressed: #952500; + --gnrc-color-foreground-warning-onloud-hover: #ffffff; + --gnrc-color-foreground-warning-onloud-pressed: #ffffff; + --gnrc-color-foreground-success-primary-hover: #006740; + --gnrc-color-foreground-success-primary-pressed: #005f38; + --gnrc-color-foreground-success-onloud-hover: #ffffff; + --gnrc-color-foreground-success-onloud-pressed: #ffffff; + --gnrc-shadow-lowest: 0px 0px 2px #0000001a, 0px 1px 2px #0000000d; + --gnrc-shadow-lower: 0px 0px 2px #0000001a, 0px 2px 4px #00000014; + --gnrc-shadow-low: 0px 0px 2px #0000001a, 0px 2px 4px #00000008, 0px 4px 8px #00000014; + --gnrc-shadow-high: 0px 0px 2px #0000001a, 0px 4px 8px #00000008, 0px 8px 16px #0000000f; + --gnrc-shadow-higher: 0px 0px 2px #0000001a, 0px 8px 16px #00000008, 0px 16px 32px #0000000f; + --gnrc-shadow-highest: 0px 0px 2px #0000001a, 0px 8px 16px #00000008, 0px 32px 64px #0000000f; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/mappings.json b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/mappings.json index 4b917a8c93a..33c7a100a20 100644 --- a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/mappings.json +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/mappings.json @@ -549,6 +549,7 @@ "prmt-duration-200": "200ms", "prmt-duration-300": "300ms", "prmt-duration-500": "500ms", + "prmt-duration-1000": "1000ms", "prmt-easing-immediate": "cubic-bezier(0, 0, 0, 1)", "prmt-easing-standard": "cubic-bezier(0.33, 0, 0, 1)", "prmt-easing-emphasized": "cubic-bezier(0.6, 0, 0.75, 0.4)", @@ -581,6 +582,7 @@ "prmt-breakpoint-1440": "1440px", "prmt-breakpoint-1920": "1920px", "prmt-font-family-segoe-sans": "'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif", + "prmt-font-family-segoe-serif": "'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif", "prmt-font-family-georgia-pro": "'Georgia Pro', Georgia, 'Times New Roman', serif", "prmt-font-family-consolas": "'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace", "prmt-font-size-10": "0.625rem", @@ -1494,7 +1496,7 @@ }, { "name": "--gnrc-font-family-content-editorial", - "primitive": "prmt-font-family-georgia-pro" + "primitive": "prmt-font-family-segoe-serif" }, { "name": "--gnrc-font-family-content-code", @@ -1989,6 +1991,10 @@ "name": "--gnrc-motion-duration-base-500", "primitive": "prmt-duration-500" }, + { + "name": "--gnrc-motion-duration-base-1000", + "primitive": "prmt-duration-1000" + }, { "name": "--gnrc-motion-easing-functional-enter", "primitive": "prmt-easing-immediate" diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic-dark.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic-dark.css new file mode 100644 index 00000000000..d9ae7355fc3 --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic-dark.css @@ -0,0 +1,283 @@ +/* Fluent Design — Semantic Tokens (Dark Theme) + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +[data-theme="dark"] { + --gnrc-color-fixed-white: #ffffff; + --gnrc-color-fixed-black: #000000; + --gnrc-color-expression-accent-heavy: #ffffff; + --gnrc-color-expression-accent-loud: #929292; + --gnrc-color-expression-accent-soft: #ffffff1f; + --gnrc-color-expression-accent-subtle: #ffffff14; + --gnrc-color-expression-achromatic-heavy: #ffffff; + --gnrc-color-expression-achromatic-subtle: #000000; + --gnrc-color-expression-gray-heavy: #f5f5f5; + --gnrc-color-expression-gray-loud: #dedede; + --gnrc-color-expression-gray-soft: #929292; + --gnrc-color-expression-gray-subtle: #484848; + --gnrc-color-expression-navy-heavy: #f0f5ff; + --gnrc-color-expression-navy-loud: #cedeff; + --gnrc-color-expression-navy-soft: #5c8df8; + --gnrc-color-expression-navy-subtle: #294482; + --gnrc-color-expression-blue-heavy: #eef6ff; + --gnrc-color-expression-blue-loud: #c6e1ff; + --gnrc-color-expression-blue-soft: #2f95f4; + --gnrc-color-expression-blue-subtle: #0b497f; + --gnrc-color-expression-green-heavy: #e7fce9; + --gnrc-color-expression-green-loud: #baedc1; + --gnrc-color-expression-green-soft: #32ad52; + --gnrc-color-expression-green-subtle: #0c5722; + --gnrc-color-expression-lime-heavy: #e6ffcf; + --gnrc-color-expression-lime-loud: #cbff93; + --gnrc-color-expression-lime-soft: #6da603; + --gnrc-color-expression-lime-subtle: #345200; + --gnrc-color-expression-yellow-heavy: #fff7c4; + --gnrc-color-expression-yellow-loud: #ffed85; + --gnrc-color-expression-yellow-soft: #fbdf06; + --gnrc-color-expression-yellow-subtle: #524800; + --gnrc-color-expression-pumpkin-heavy: #fef2ee; + --gnrc-color-expression-pumpkin-loud: #ffd3c2; + --gnrc-color-expression-pumpkin-soft: #fb966e; + --gnrc-color-expression-pumpkin-subtle: #762f0e; + --gnrc-color-expression-red-heavy: #fff2f0; + --gnrc-color-expression-red-loud: #ffd2cd; + --gnrc-color-expression-red-soft: #e7615b; + --gnrc-color-expression-red-subtle: #772b28; + --gnrc-color-expression-pink-heavy: #fff1f7; + --gnrc-color-expression-pink-loud: #ffcee6; + --gnrc-color-expression-pink-soft: #d961a6; + --gnrc-color-expression-pink-subtle: #6f2b53; + --gnrc-color-expression-purple-heavy: #f7f3ff; + --gnrc-color-expression-purple-loud: #e4d6ff; + --gnrc-color-expression-purple-soft: #a575e8; + --gnrc-color-expression-purple-subtle: #523778; + --gnrc-color-overlay-neutral-translucent: #00000099; + --gnrc-color-surface-neutral-farther: #1b1b1b; + --gnrc-color-surface-neutral-far: #1f1f1f; + --gnrc-color-surface-neutral-near: #181818; + --gnrc-color-surface-neutral-nearer: #292929; + --gnrc-color-surface-neutral-translucent: #3c3c3c80; + --gnrc-material-background-thick: #262626ea; + --gnrc-material-background-regular: #2f2f2fd1; + --gnrc-material-background-thin: #3434348b; + --gnrc-color-background-neutral-heavy: #ffffff; + --gnrc-color-background-neutral-loud: #929292; + --gnrc-color-background-neutral-soft: #ffffff1f; + --gnrc-color-background-neutral-subtle: #ffffff14; + --gnrc-color-background-neutral-transparent: #ffffff00; + --gnrc-color-background-neutral-translucent: #3c3c3c80; + --gnrc-color-background-neutral-disabled: #ffffff07; + --gnrc-color-background-neutral-heavy-disabled: #ffffff20; + --gnrc-color-background-neutral-subtle-disabled: #ffffff07; + --gnrc-color-background-brand-heavy: #ffffff; + --gnrc-color-background-brand-loud: #929292; + --gnrc-color-background-brand-soft: #ffffff1f; + --gnrc-color-background-brand-subtle: #ffffff14; + --gnrc-color-background-brand-transparent: #ffffff00; + --gnrc-color-background-danger-loud: #e55e7a; + --gnrc-color-background-danger-soft: #5a2932; + --gnrc-color-background-danger-subtle: #402529; + --gnrc-color-background-warning-loud: #e56738; + --gnrc-color-background-warning-soft: #592c1c; + --gnrc-color-background-warning-subtle: #40261d; + --gnrc-color-background-success-loud: #05ad72; + --gnrc-color-background-success-soft: #0c462d; + --gnrc-color-background-success-subtle: #193426; + --gnrc-color-stroke-neutral-heavy: #dedede; + --gnrc-color-stroke-neutral-loud: #929292; + --gnrc-color-stroke-neutral-soft: #ffffff61; + --gnrc-color-stroke-neutral-subtle: #ffffff48; + --gnrc-color-stroke-neutral-transparent: #ffffff00; + --gnrc-color-stroke-neutral-onloud: #000000db; + --gnrc-color-stroke-neutral-disabled: #ffffff24; + --gnrc-color-stroke-brand-loud: #929292; + --gnrc-color-stroke-brand-soft: #ffffff61; + --gnrc-color-stroke-brand-subtle: #ffffff48; + --gnrc-color-stroke-brand-onloud: #242424; + --gnrc-color-stroke-danger-loud: #e55e7a; + --gnrc-color-stroke-danger-soft: #d14164; + --gnrc-color-stroke-danger-subtle: #76293a; + --gnrc-color-stroke-danger-onloud: #242424; + --gnrc-color-stroke-warning-loud: #e56738; + --gnrc-color-stroke-warning-soft: #cd4808; + --gnrc-color-stroke-warning-subtle: #762e12; + --gnrc-color-stroke-warning-onloud: #242424; + --gnrc-color-stroke-success-loud: #05ad72; + --gnrc-color-stroke-success-soft: #008e5c; + --gnrc-color-stroke-success-subtle: #025636; + --gnrc-color-stroke-success-onloud: #242424; + --gnrc-color-stroke-focus-inner: #000000; + --gnrc-color-stroke-focus-outer: #ffffff; + --gnrc-color-foreground-neutral-primary: #ffffffde; + --gnrc-color-foreground-neutral-secondary: #ffffffa1; + --gnrc-color-foreground-neutral-tertiary: #ffffff80; + --gnrc-color-foreground-neutral-onloud: #000000db; + --gnrc-color-foreground-neutral-disabled: #ffffff61; + --gnrc-color-foreground-brand-primary: #dedede; + --gnrc-color-foreground-brand-onloud: #000000db; + --gnrc-color-foreground-danger-primary: #fd8ea1; + --gnrc-color-foreground-danger-onloud: #000000db; + --gnrc-color-foreground-warning-primary: #fc9571; + --gnrc-color-foreground-warning-onloud: #000000db; + --gnrc-color-foreground-success-primary: #5dce97; + --gnrc-color-foreground-success-onloud: #000000db; + --gnrc-color-shadow: #000000; + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-font-weight-functional-regular: 420; + --gnrc-font-weight-functional-medium: 550; + --gnrc-font-weight-functional-semibold: 600; + --gnrc-font-weight-functional-bold: 625; + --gnrc-font-weight-content-regular: 420; + --gnrc-font-weight-content-medium: 550; + --gnrc-font-weight-content-semibold: 600; + --gnrc-font-weight-content-bold: 625; + --gnrc-font-weight-content-editorial-regular: 420; + --gnrc-font-weight-content-editorial-medium: 550; + --gnrc-font-weight-content-editorial-semibold: 600; + --gnrc-font-weight-content-editorial-bold: 625; + --gnrc-font-family-functional: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content-editorial: 'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif; + --gnrc-font-family-content-code: 'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace; + --gnrc-letter-spacing-functional-display: -0.0075em; + --gnrc-letter-spacing-functional-pagetitle: -0.0075em; + --gnrc-letter-spacing-functional-title-large: -0.0015em; + --gnrc-letter-spacing-functional-title-medium: -0.0015em; + --gnrc-letter-spacing-functional-title-small: -0.0015em; + --gnrc-letter-spacing-functional-subtitle: -0.0015em; + --gnrc-letter-spacing-functional-body-large: 0em; + --gnrc-letter-spacing-functional-body-medium: 0em; + --gnrc-letter-spacing-functional-body-small: 0em; + --gnrc-letter-spacing-functional-caption: 0em; + --gnrc-letter-spacing-content-statement: -0.0075em; + --gnrc-letter-spacing-content-expressive-large: -0.0075em; + --gnrc-letter-spacing-content-expressive-medium: -0.0015em; + --gnrc-letter-spacing-content-expressive-small: -0.0015em; + --gnrc-letter-spacing-content-h1: -0.0015em; + --gnrc-letter-spacing-content-h2: -0.0015em; + --gnrc-letter-spacing-content-h3: -0.0015em; + --gnrc-letter-spacing-content-h4: -0.0015em; + --gnrc-letter-spacing-content-h5: -0.0015em; + --gnrc-letter-spacing-content-subheadline: 0em; + --gnrc-letter-spacing-content-paragraph-large: 0em; + --gnrc-letter-spacing-content-paragraph-medium: 0em; + --gnrc-letter-spacing-content-paragraph-small: 0em; + --gnrc-letter-spacing-content-subtext: 0em; + --gnrc-letter-spacing-content-table: 0em; + --gnrc-letter-spacing-content-code: 0em; + --gnrc-font-size-functional-display: 4.25rem; + --gnrc-font-size-functional-pagetitle: 2.5rem; + --gnrc-font-size-functional-title-large: 2rem; + --gnrc-font-size-functional-title-medium: 1.75rem; + --gnrc-font-size-functional-title-small: 1.5rem; + --gnrc-font-size-functional-subtitle: 1.25rem; + --gnrc-font-size-functional-body-large: 1rem; + --gnrc-font-size-functional-body-medium: 0.875rem; + --gnrc-font-size-functional-body-small: 0.75rem; + --gnrc-font-size-functional-caption: 0.625rem; + --gnrc-font-size-content-statement: 3.5rem; + --gnrc-font-size-content-expressive-large: 3rem; + --gnrc-font-size-content-expressive-medium: 2.25rem; + --gnrc-font-size-content-expressive-small: 1.75rem; + --gnrc-font-size-content-h1: 2.25rem; + --gnrc-font-size-content-h2: 2rem; + --gnrc-font-size-content-h3: 1.75rem; + --gnrc-font-size-content-h4: 1.5rem; + --gnrc-font-size-content-h5: 1.25rem; + --gnrc-font-size-content-subheadline: 1rem; + --gnrc-font-size-content-paragraph-large: 1.25rem; + --gnrc-font-size-content-paragraph-medium: 1rem; + --gnrc-font-size-content-paragraph-small: 0.75rem; + --gnrc-font-size-content-subtext: 0.625rem; + --gnrc-font-size-content-table: 1rem; + --gnrc-font-size-content-code: 1rem; + --gnrc-line-height-functional-display: round(120%, 2px); + --gnrc-line-height-functional-pagetitle: round(120%, 2px); + --gnrc-line-height-functional-title-large: round(120%, 2px); + --gnrc-line-height-functional-title-medium: round(120%, 2px); + --gnrc-line-height-functional-title-small: round(120%, 2px); + --gnrc-line-height-functional-subtitle: round(140%, 2px); + --gnrc-line-height-functional-body-large: round(140%, 2px); + --gnrc-line-height-functional-body-medium: round(140%, 2px); + --gnrc-line-height-functional-body-small: round(140%, 2px); + --gnrc-line-height-functional-caption: round(140%, 2px); + --gnrc-line-height-content-statement: round(120%, 2px); + --gnrc-line-height-content-expressive-large: round(120%, 2px); + --gnrc-line-height-content-expressive-medium: round(120%, 2px); + --gnrc-line-height-content-expressive-small: round(120%, 2px); + --gnrc-line-height-content-h1: round(120%, 2px); + --gnrc-line-height-content-h2: round(120%, 2px); + --gnrc-line-height-content-h3: round(120%, 2px); + --gnrc-line-height-content-h4: round(120%, 2px); + --gnrc-line-height-content-h5: round(120%, 2px); + --gnrc-line-height-content-subheadline: round(140%, 2px); + --gnrc-line-height-content-paragraph-large: round(170%, 2px); + --gnrc-line-height-content-paragraph-medium: round(170%, 2px); + --gnrc-line-height-content-paragraph-small: round(170%, 2px); + --gnrc-line-height-content-subtext: round(140%, 2px); + --gnrc-line-height-content-table: round(140%, 2px); + --gnrc-line-height-content-code: round(140%, 2px); + --gnrc-border-radius-base-100: 4px; + --gnrc-border-radius-base-200: 8px; + --gnrc-border-radius-base-300: 12px; + --gnrc-border-radius-base-400: 16px; + --gnrc-border-radius-base-600: 24px; + --gnrc-border-radius-base-700: 28px; + --gnrc-border-radius-circular: 9999px; + --gnrc-spacing-component-base-50: 2px; + --gnrc-spacing-component-base-100: 4px; + --gnrc-spacing-component-base-150: 6px; + --gnrc-spacing-component-base-200: 8px; + --gnrc-spacing-component-base-250: 10px; + --gnrc-spacing-component-base-300: 12px; + --gnrc-spacing-component-base-400: 16px; + --gnrc-spacing-component-base-500: 20px; + --gnrc-spacing-component-base-600: 24px; + --gnrc-spacing-component-base-700: 28px; + --gnrc-spacing-component-base-800: 32px; + --gnrc-spacing-layout-base-100: 8px; + --gnrc-spacing-layout-base-200: 16px; + --gnrc-spacing-layout-base-300: 24px; + --gnrc-spacing-layout-base-400: 32px; + --gnrc-spacing-layout-base-450: 36px; + --gnrc-spacing-layout-base-500: 40px; + --gnrc-spacing-layout-base-600: 48px; + --gnrc-spacing-layout-base-700: 56px; + --gnrc-spacing-layout-base-800: 64px; + --gnrc-spacing-layout-base-1000: 80px; + --gnrc-spacing-layout-base-1200: 96px; + --gnrc-stroke-width-thin: 1px; + --gnrc-stroke-width-thick: 2px; + --gnrc-stroke-width-thicker: 3px; + --gnrc-stroke-width-thickest: 4px; + --gnrc-motion-duration-base-50: 50ms; + --gnrc-motion-duration-base-100: 100ms; + --gnrc-motion-duration-base-200: 200ms; + --gnrc-motion-duration-base-300: 300ms; + --gnrc-motion-duration-base-500: 500ms; + --gnrc-motion-duration-base-1000: 1000ms; + --gnrc-motion-easing-functional-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-functional-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-functional-transition: cubic-bezier(0.33, 0, 0, 1); + --gnrc-motion-easing-functional-linear: cubic-bezier(0, 0, 1, 1); + --gnrc-motion-easing-expressive-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-expressive-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-expressive-transition: cubic-bezier(0.33, 0, 0, 1); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: 0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.06; + --interaction-standard-hover: calc(l + 0.03 * clamp(1,(.5 - l)/.1,3)) c h / calc(alpha + 0.03); + --interaction-standard-pressed: calc(l + 0.06 * clamp(1,(.5 - l)/.1,3)) c h / calc(alpha + 0.06); + --interaction-inverse-hover: calc(l - 0.03 * clamp(1,(.5 - l)/.1,3)) c h / alpha; + --interaction-inverse-pressed: calc(l - 0.06 * clamp(1,(.5 - l)/.1,3)) c h / alpha; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic-light.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic-light.css new file mode 100644 index 00000000000..633b87a634b --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic-light.css @@ -0,0 +1,283 @@ +/* Fluent Design — Semantic Tokens (Light Theme) + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +:root, [data-theme="light"] { + --gnrc-color-fixed-white: #ffffff; + --gnrc-color-fixed-black: #000000; + --gnrc-color-expression-accent-heavy: #242424; + --gnrc-color-expression-accent-loud: #6f6f6f; + --gnrc-color-expression-accent-soft: #00000014; + --gnrc-color-expression-accent-subtle: #0000000d; + --gnrc-color-expression-achromatic-heavy: #000000; + --gnrc-color-expression-achromatic-subtle: #ffffff; + --gnrc-color-expression-gray-heavy: #484848; + --gnrc-color-expression-gray-loud: #929292; + --gnrc-color-expression-gray-soft: #dedede; + --gnrc-color-expression-gray-subtle: #f5f5f5; + --gnrc-color-expression-navy-heavy: #294482; + --gnrc-color-expression-navy-loud: #5c8df8; + --gnrc-color-expression-navy-soft: #cedeff; + --gnrc-color-expression-navy-subtle: #f0f5ff; + --gnrc-color-expression-blue-heavy: #0b497f; + --gnrc-color-expression-blue-loud: #2f95f4; + --gnrc-color-expression-blue-soft: #c6e1ff; + --gnrc-color-expression-blue-subtle: #eef6ff; + --gnrc-color-expression-green-heavy: #0c5722; + --gnrc-color-expression-green-loud: #32ad52; + --gnrc-color-expression-green-soft: #baedc1; + --gnrc-color-expression-green-subtle: #e7fce9; + --gnrc-color-expression-lime-heavy: #345200; + --gnrc-color-expression-lime-loud: #6da603; + --gnrc-color-expression-lime-soft: #cbff93; + --gnrc-color-expression-lime-subtle: #e6ffcf; + --gnrc-color-expression-yellow-heavy: #524800; + --gnrc-color-expression-yellow-loud: #fbdf06; + --gnrc-color-expression-yellow-soft: #ffed85; + --gnrc-color-expression-yellow-subtle: #fff7c4; + --gnrc-color-expression-pumpkin-heavy: #762f0e; + --gnrc-color-expression-pumpkin-loud: #fb966e; + --gnrc-color-expression-pumpkin-soft: #ffd3c2; + --gnrc-color-expression-pumpkin-subtle: #fef2ee; + --gnrc-color-expression-red-heavy: #772b28; + --gnrc-color-expression-red-loud: #e7615b; + --gnrc-color-expression-red-soft: #ffd2cd; + --gnrc-color-expression-red-subtle: #fff2f0; + --gnrc-color-expression-pink-heavy: #6f2b53; + --gnrc-color-expression-pink-loud: #d961a6; + --gnrc-color-expression-pink-soft: #ffcee6; + --gnrc-color-expression-pink-subtle: #fff1f7; + --gnrc-color-expression-purple-heavy: #523778; + --gnrc-color-expression-purple-loud: #a575e8; + --gnrc-color-expression-purple-soft: #e4d6ff; + --gnrc-color-expression-purple-subtle: #f7f3ff; + --gnrc-color-overlay-neutral-translucent: #00000026; + --gnrc-color-surface-neutral-farther: #ebebeb; + --gnrc-color-surface-neutral-far: #f2f2f2; + --gnrc-color-surface-neutral-near: #fcfcfc; + --gnrc-color-surface-neutral-nearer: #ffffff; + --gnrc-color-surface-neutral-translucent: #ffffff80; + --gnrc-material-background-thick: #fffffff1; + --gnrc-material-background-regular: #ffffffd7; + --gnrc-material-background-thin: #ffffff7e; + --gnrc-color-background-neutral-heavy: #242424; + --gnrc-color-background-neutral-loud: #6f6f6f; + --gnrc-color-background-neutral-soft: #00000014; + --gnrc-color-background-neutral-subtle: #0000000d; + --gnrc-color-background-neutral-transparent: #24242400; + --gnrc-color-background-neutral-translucent: #e9e9e980; + --gnrc-color-background-neutral-disabled: #00000008; + --gnrc-color-background-neutral-heavy-disabled: #0000001a; + --gnrc-color-background-neutral-subtle-disabled: #00000008; + --gnrc-color-background-brand-heavy: #242424; + --gnrc-color-background-brand-loud: #6f6f6f; + --gnrc-color-background-brand-soft: #00000014; + --gnrc-color-background-brand-subtle: #0000000a; + --gnrc-color-background-brand-transparent: #24242400; + --gnrc-color-background-danger-loud: #c02e56; + --gnrc-color-background-danger-soft: #ffe3e6; + --gnrc-color-background-danger-subtle: #fff1f3; + --gnrc-color-background-warning-loud: #bb4001; + --gnrc-color-background-warning-soft: #ffe5dc; + --gnrc-color-background-warning-subtle: #fff2ee; + --gnrc-color-background-success-loud: #008455; + --gnrc-color-background-success-soft: #c9f8dd; + --gnrc-color-background-success-subtle: #e3fcee; + --gnrc-color-stroke-neutral-heavy: #242424; + --gnrc-color-stroke-neutral-loud: #6f6f6f; + --gnrc-color-stroke-neutral-soft: #0000006d; + --gnrc-color-stroke-neutral-subtle: #00000021; + --gnrc-color-stroke-neutral-transparent: #24242400; + --gnrc-color-stroke-neutral-onloud: #ffffffff; + --gnrc-color-stroke-neutral-disabled: #00000014; + --gnrc-color-stroke-brand-loud: #6f6f6f; + --gnrc-color-stroke-brand-soft: #0000006d; + --gnrc-color-stroke-brand-subtle: #00000021; + --gnrc-color-stroke-brand-onloud: #ffffff; + --gnrc-color-stroke-danger-loud: #c02e56; + --gnrc-color-stroke-danger-soft: #e55e7a; + --gnrc-color-stroke-danger-subtle: #ffd0d6; + --gnrc-color-stroke-danger-onloud: #ffffff; + --gnrc-color-stroke-warning-loud: #cd4808; + --gnrc-color-stroke-warning-soft: #fc9571; + --gnrc-color-stroke-warning-subtle: #ffd3c4; + --gnrc-color-stroke-warning-onloud: #ffffff; + --gnrc-color-stroke-success-loud: #008455; + --gnrc-color-stroke-success-soft: #5dce97; + --gnrc-color-stroke-success-subtle: #b1efcc; + --gnrc-color-stroke-success-onloud: #ffffff; + --gnrc-color-stroke-focus-inner: #ffffff; + --gnrc-color-stroke-focus-outer: #000000; + --gnrc-color-foreground-neutral-primary: #000000db; + --gnrc-color-foreground-neutral-secondary: #000000a2; + --gnrc-color-foreground-neutral-tertiary: #00000090; + --gnrc-color-foreground-neutral-onloud: #ffffffff; + --gnrc-color-foreground-neutral-disabled: #0000006d; + --gnrc-color-foreground-brand-primary: #242424; + --gnrc-color-foreground-brand-onloud: #ffffff; + --gnrc-color-foreground-danger-primary: #a62147; + --gnrc-color-foreground-danger-onloud: #ffffff; + --gnrc-color-foreground-warning-primary: #a93901; + --gnrc-color-foreground-warning-onloud: #ffffff; + --gnrc-color-foreground-success-primary: #017048; + --gnrc-color-foreground-success-onloud: #ffffff; + --gnrc-color-shadow: #000000; + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 5%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-font-weight-functional-regular: 420; + --gnrc-font-weight-functional-medium: 550; + --gnrc-font-weight-functional-semibold: 600; + --gnrc-font-weight-functional-bold: 625; + --gnrc-font-weight-content-regular: 420; + --gnrc-font-weight-content-medium: 550; + --gnrc-font-weight-content-semibold: 600; + --gnrc-font-weight-content-bold: 625; + --gnrc-font-weight-content-editorial-regular: 420; + --gnrc-font-weight-content-editorial-medium: 550; + --gnrc-font-weight-content-editorial-semibold: 600; + --gnrc-font-weight-content-editorial-bold: 625; + --gnrc-font-family-functional: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content-editorial: 'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif; + --gnrc-font-family-content-code: 'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace; + --gnrc-letter-spacing-functional-display: -0.0075em; + --gnrc-letter-spacing-functional-pagetitle: -0.0075em; + --gnrc-letter-spacing-functional-title-large: -0.0015em; + --gnrc-letter-spacing-functional-title-medium: -0.0015em; + --gnrc-letter-spacing-functional-title-small: -0.0015em; + --gnrc-letter-spacing-functional-subtitle: -0.0015em; + --gnrc-letter-spacing-functional-body-large: 0em; + --gnrc-letter-spacing-functional-body-medium: 0em; + --gnrc-letter-spacing-functional-body-small: 0em; + --gnrc-letter-spacing-functional-caption: 0em; + --gnrc-letter-spacing-content-statement: -0.0075em; + --gnrc-letter-spacing-content-expressive-large: -0.0075em; + --gnrc-letter-spacing-content-expressive-medium: -0.0015em; + --gnrc-letter-spacing-content-expressive-small: -0.0015em; + --gnrc-letter-spacing-content-h1: -0.0015em; + --gnrc-letter-spacing-content-h2: -0.0015em; + --gnrc-letter-spacing-content-h3: -0.0015em; + --gnrc-letter-spacing-content-h4: -0.0015em; + --gnrc-letter-spacing-content-h5: -0.0015em; + --gnrc-letter-spacing-content-subheadline: 0em; + --gnrc-letter-spacing-content-paragraph-large: 0em; + --gnrc-letter-spacing-content-paragraph-medium: 0em; + --gnrc-letter-spacing-content-paragraph-small: 0em; + --gnrc-letter-spacing-content-subtext: 0em; + --gnrc-letter-spacing-content-table: 0em; + --gnrc-letter-spacing-content-code: 0em; + --gnrc-font-size-functional-display: 4.25rem; + --gnrc-font-size-functional-pagetitle: 2.5rem; + --gnrc-font-size-functional-title-large: 2rem; + --gnrc-font-size-functional-title-medium: 1.75rem; + --gnrc-font-size-functional-title-small: 1.5rem; + --gnrc-font-size-functional-subtitle: 1.25rem; + --gnrc-font-size-functional-body-large: 1rem; + --gnrc-font-size-functional-body-medium: 0.875rem; + --gnrc-font-size-functional-body-small: 0.75rem; + --gnrc-font-size-functional-caption: 0.625rem; + --gnrc-font-size-content-statement: 3.5rem; + --gnrc-font-size-content-expressive-large: 3rem; + --gnrc-font-size-content-expressive-medium: 2.25rem; + --gnrc-font-size-content-expressive-small: 1.75rem; + --gnrc-font-size-content-h1: 2.25rem; + --gnrc-font-size-content-h2: 2rem; + --gnrc-font-size-content-h3: 1.75rem; + --gnrc-font-size-content-h4: 1.5rem; + --gnrc-font-size-content-h5: 1.25rem; + --gnrc-font-size-content-subheadline: 1rem; + --gnrc-font-size-content-paragraph-large: 1.25rem; + --gnrc-font-size-content-paragraph-medium: 1rem; + --gnrc-font-size-content-paragraph-small: 0.75rem; + --gnrc-font-size-content-subtext: 0.625rem; + --gnrc-font-size-content-table: 1rem; + --gnrc-font-size-content-code: 1rem; + --gnrc-line-height-functional-display: round(120%, 2px); + --gnrc-line-height-functional-pagetitle: round(120%, 2px); + --gnrc-line-height-functional-title-large: round(120%, 2px); + --gnrc-line-height-functional-title-medium: round(120%, 2px); + --gnrc-line-height-functional-title-small: round(120%, 2px); + --gnrc-line-height-functional-subtitle: round(140%, 2px); + --gnrc-line-height-functional-body-large: round(140%, 2px); + --gnrc-line-height-functional-body-medium: round(140%, 2px); + --gnrc-line-height-functional-body-small: round(140%, 2px); + --gnrc-line-height-functional-caption: round(140%, 2px); + --gnrc-line-height-content-statement: round(120%, 2px); + --gnrc-line-height-content-expressive-large: round(120%, 2px); + --gnrc-line-height-content-expressive-medium: round(120%, 2px); + --gnrc-line-height-content-expressive-small: round(120%, 2px); + --gnrc-line-height-content-h1: round(120%, 2px); + --gnrc-line-height-content-h2: round(120%, 2px); + --gnrc-line-height-content-h3: round(120%, 2px); + --gnrc-line-height-content-h4: round(120%, 2px); + --gnrc-line-height-content-h5: round(120%, 2px); + --gnrc-line-height-content-subheadline: round(140%, 2px); + --gnrc-line-height-content-paragraph-large: round(170%, 2px); + --gnrc-line-height-content-paragraph-medium: round(170%, 2px); + --gnrc-line-height-content-paragraph-small: round(170%, 2px); + --gnrc-line-height-content-subtext: round(140%, 2px); + --gnrc-line-height-content-table: round(140%, 2px); + --gnrc-line-height-content-code: round(140%, 2px); + --gnrc-border-radius-base-100: 4px; + --gnrc-border-radius-base-200: 8px; + --gnrc-border-radius-base-300: 12px; + --gnrc-border-radius-base-400: 16px; + --gnrc-border-radius-base-600: 24px; + --gnrc-border-radius-base-700: 28px; + --gnrc-border-radius-circular: 9999px; + --gnrc-spacing-component-base-50: 2px; + --gnrc-spacing-component-base-100: 4px; + --gnrc-spacing-component-base-150: 6px; + --gnrc-spacing-component-base-200: 8px; + --gnrc-spacing-component-base-250: 10px; + --gnrc-spacing-component-base-300: 12px; + --gnrc-spacing-component-base-400: 16px; + --gnrc-spacing-component-base-500: 20px; + --gnrc-spacing-component-base-600: 24px; + --gnrc-spacing-component-base-700: 28px; + --gnrc-spacing-component-base-800: 32px; + --gnrc-spacing-layout-base-100: 8px; + --gnrc-spacing-layout-base-200: 16px; + --gnrc-spacing-layout-base-300: 24px; + --gnrc-spacing-layout-base-400: 32px; + --gnrc-spacing-layout-base-450: 36px; + --gnrc-spacing-layout-base-500: 40px; + --gnrc-spacing-layout-base-600: 48px; + --gnrc-spacing-layout-base-700: 56px; + --gnrc-spacing-layout-base-800: 64px; + --gnrc-spacing-layout-base-1000: 80px; + --gnrc-spacing-layout-base-1200: 96px; + --gnrc-stroke-width-thin: 1px; + --gnrc-stroke-width-thick: 2px; + --gnrc-stroke-width-thicker: 3px; + --gnrc-stroke-width-thickest: 4px; + --gnrc-motion-duration-base-50: 50ms; + --gnrc-motion-duration-base-100: 100ms; + --gnrc-motion-duration-base-200: 200ms; + --gnrc-motion-duration-base-300: 300ms; + --gnrc-motion-duration-base-500: 500ms; + --gnrc-motion-duration-base-1000: 1000ms; + --gnrc-motion-easing-functional-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-functional-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-functional-transition: cubic-bezier(0.33, 0, 0, 1); + --gnrc-motion-easing-functional-linear: cubic-bezier(0, 0, 1, 1); + --gnrc-motion-easing-expressive-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-expressive-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-expressive-transition: cubic-bezier(0.33, 0, 0, 1); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: -0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: -0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.04; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.08; + --interaction-standard-hover: calc(l - 0.03 * clamp(1,(.5 - l)/.1,3)) c h / calc(alpha + 0.04); + --interaction-standard-pressed: calc(l - 0.06 * clamp(1,(.5 - l)/.1,3)) c h / calc(alpha + 0.08); + --interaction-inverse-hover: calc(l + 0.03 * clamp(1,(.5 - l)/.1,3)) c h / alpha; + --interaction-inverse-pressed: calc(l + 0.06 * clamp(1,(.5 - l)/.1,3)) c h / alpha; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic.css index 6dac670ac83..4c9f3e0a70b 100644 --- a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic.css +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/semantic.css @@ -143,7 +143,7 @@ --gnrc-font-weight-content-editorial-bold: 625; --gnrc-font-family-functional: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; --gnrc-font-family-content: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; - --gnrc-font-family-content-editorial: 'Georgia Pro', Georgia, 'Times New Roman', serif; + --gnrc-font-family-content-editorial: 'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif; --gnrc-font-family-content-code: 'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace; --gnrc-letter-spacing-functional-display: -0.0075em; --gnrc-letter-spacing-functional-pagetitle: -0.0075em; @@ -261,6 +261,7 @@ --gnrc-motion-duration-base-200: 200ms; --gnrc-motion-duration-base-300: 300ms; --gnrc-motion-duration-base-500: 500ms; + --gnrc-motion-duration-base-1000: 1000ms; --gnrc-motion-easing-functional-enter: cubic-bezier(0, 0, 0, 1); --gnrc-motion-easing-functional-exit: cubic-bezier(0.6, 0, 0.75, 0.4); --gnrc-motion-easing-functional-transition: cubic-bezier(0.33, 0, 0, 1); diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/tokens.json b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/tokens.json new file mode 100644 index 00000000000..49bec466b83 --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/tokens.json @@ -0,0 +1,2320 @@ +{ + "generics": [ + { + "name": "--gnrc-color-fixed-white", + "light": "#ffffff", + "dark": "#ffffff" + }, + { + "name": "--gnrc-color-fixed-black", + "light": "#000000", + "dark": "#000000" + }, + { + "name": "--gnrc-color-expression-accent-heavy", + "light": "#242424", + "dark": "#ffffff" + }, + { + "name": "--gnrc-color-expression-accent-loud", + "light": "#6f6f6f", + "dark": "#929292" + }, + { + "name": "--gnrc-color-expression-accent-soft", + "light": "#00000014", + "dark": "#ffffff1f" + }, + { + "name": "--gnrc-color-expression-accent-subtle", + "light": "#0000000d", + "dark": "#ffffff14" + }, + { + "name": "--gnrc-color-expression-achromatic-heavy", + "light": "#000000", + "dark": "#ffffff" + }, + { + "name": "--gnrc-color-expression-achromatic-subtle", + "light": "#ffffff", + "dark": "#000000" + }, + { + "name": "--gnrc-color-expression-gray-heavy", + "light": "#484848", + "dark": "#f5f5f5" + }, + { + "name": "--gnrc-color-expression-gray-loud", + "light": "#929292", + "dark": "#dedede" + }, + { + "name": "--gnrc-color-expression-gray-soft", + "light": "#dedede", + "dark": "#929292" + }, + { + "name": "--gnrc-color-expression-gray-subtle", + "light": "#f5f5f5", + "dark": "#484848" + }, + { + "name": "--gnrc-color-expression-navy-heavy", + "light": "#294482", + "dark": "#f0f5ff" + }, + { + "name": "--gnrc-color-expression-navy-loud", + "light": "#5c8df8", + "dark": "#cedeff" + }, + { + "name": "--gnrc-color-expression-navy-soft", + "light": "#cedeff", + "dark": "#5c8df8" + }, + { + "name": "--gnrc-color-expression-navy-subtle", + "light": "#f0f5ff", + "dark": "#294482" + }, + { + "name": "--gnrc-color-expression-blue-heavy", + "light": "#0b497f", + "dark": "#eef6ff" + }, + { + "name": "--gnrc-color-expression-blue-loud", + "light": "#2f95f4", + "dark": "#c6e1ff" + }, + { + "name": "--gnrc-color-expression-blue-soft", + "light": "#c6e1ff", + "dark": "#2f95f4" + }, + { + "name": "--gnrc-color-expression-blue-subtle", + "light": "#eef6ff", + "dark": "#0b497f" + }, + { + "name": "--gnrc-color-expression-green-heavy", + "light": "#0c5722", + "dark": "#e7fce9" + }, + { + "name": "--gnrc-color-expression-green-loud", + "light": "#32ad52", + "dark": "#baedc1" + }, + { + "name": "--gnrc-color-expression-green-soft", + "light": "#baedc1", + "dark": "#32ad52" + }, + { + "name": "--gnrc-color-expression-green-subtle", + "light": "#e7fce9", + "dark": "#0c5722" + }, + { + "name": "--gnrc-color-expression-lime-heavy", + "light": "#345200", + "dark": "#e6ffcf" + }, + { + "name": "--gnrc-color-expression-lime-loud", + "light": "#6da603", + "dark": "#cbff93" + }, + { + "name": "--gnrc-color-expression-lime-soft", + "light": "#cbff93", + "dark": "#6da603" + }, + { + "name": "--gnrc-color-expression-lime-subtle", + "light": "#e6ffcf", + "dark": "#345200" + }, + { + "name": "--gnrc-color-expression-yellow-heavy", + "light": "#524800", + "dark": "#fff7c4" + }, + { + "name": "--gnrc-color-expression-yellow-loud", + "light": "#fbdf06", + "dark": "#ffed85" + }, + { + "name": "--gnrc-color-expression-yellow-soft", + "light": "#ffed85", + "dark": "#fbdf06" + }, + { + "name": "--gnrc-color-expression-yellow-subtle", + "light": "#fff7c4", + "dark": "#524800" + }, + { + "name": "--gnrc-color-expression-pumpkin-heavy", + "light": "#762f0e", + "dark": "#fef2ee" + }, + { + "name": "--gnrc-color-expression-pumpkin-loud", + "light": "#fb966e", + "dark": "#ffd3c2" + }, + { + "name": "--gnrc-color-expression-pumpkin-soft", + "light": "#ffd3c2", + "dark": "#fb966e" + }, + { + "name": "--gnrc-color-expression-pumpkin-subtle", + "light": "#fef2ee", + "dark": "#762f0e" + }, + { + "name": "--gnrc-color-expression-red-heavy", + "light": "#772b28", + "dark": "#fff2f0" + }, + { + "name": "--gnrc-color-expression-red-loud", + "light": "#e7615b", + "dark": "#ffd2cd" + }, + { + "name": "--gnrc-color-expression-red-soft", + "light": "#ffd2cd", + "dark": "#e7615b" + }, + { + "name": "--gnrc-color-expression-red-subtle", + "light": "#fff2f0", + "dark": "#772b28" + }, + { + "name": "--gnrc-color-expression-pink-heavy", + "light": "#6f2b53", + "dark": "#fff1f7" + }, + { + "name": "--gnrc-color-expression-pink-loud", + "light": "#d961a6", + "dark": "#ffcee6" + }, + { + "name": "--gnrc-color-expression-pink-soft", + "light": "#ffcee6", + "dark": "#d961a6" + }, + { + "name": "--gnrc-color-expression-pink-subtle", + "light": "#fff1f7", + "dark": "#6f2b53" + }, + { + "name": "--gnrc-color-expression-purple-heavy", + "light": "#523778", + "dark": "#f7f3ff" + }, + { + "name": "--gnrc-color-expression-purple-loud", + "light": "#a575e8", + "dark": "#e4d6ff" + }, + { + "name": "--gnrc-color-expression-purple-soft", + "light": "#e4d6ff", + "dark": "#a575e8" + }, + { + "name": "--gnrc-color-expression-purple-subtle", + "light": "#f7f3ff", + "dark": "#523778" + }, + { + "name": "--gnrc-color-overlay-neutral-translucent", + "light": "#00000026", + "dark": "#00000099" + }, + { + "name": "--gnrc-color-surface-neutral-farther", + "light": "#ebebeb", + "dark": "#1b1b1b" + }, + { + "name": "--gnrc-color-surface-neutral-far", + "light": "#f2f2f2", + "dark": "#1f1f1f" + }, + { + "name": "--gnrc-color-surface-neutral-near", + "light": "#fcfcfc", + "dark": "#181818" + }, + { + "name": "--gnrc-color-surface-neutral-nearer", + "light": "#ffffff", + "dark": "#292929" + }, + { + "name": "--gnrc-color-surface-neutral-translucent", + "light": "#ffffff80", + "dark": "#3c3c3c80" + }, + { + "name": "--gnrc-material-background-thick", + "light": "#fffffff1", + "dark": "#262626ea" + }, + { + "name": "--gnrc-material-background-regular", + "light": "#ffffffd7", + "dark": "#2f2f2fd1" + }, + { + "name": "--gnrc-material-background-thin", + "light": "#ffffff7e", + "dark": "#3434348b" + }, + { + "name": "--gnrc-color-background-neutral-heavy", + "light": "#242424", + "dark": "#ffffff" + }, + { + "name": "--gnrc-color-background-neutral-loud", + "light": "#6f6f6f", + "dark": "#929292" + }, + { + "name": "--gnrc-color-background-neutral-soft", + "light": "#00000014", + "dark": "#ffffff1f" + }, + { + "name": "--gnrc-color-background-neutral-subtle", + "light": "#0000000d", + "dark": "#ffffff14" + }, + { + "name": "--gnrc-color-background-neutral-transparent", + "light": "#24242400", + "dark": "#ffffff00" + }, + { + "name": "--gnrc-color-background-neutral-translucent", + "light": "#e9e9e980", + "dark": "#3c3c3c80" + }, + { + "name": "--gnrc-color-background-neutral-disabled", + "light": "#00000008", + "dark": "#ffffff07", + "deprecated": "Use --gnrc-color-background-neutral-subtle-disabled for subtle disabled fills, or --gnrc-color-background-neutral-heavy-disabled for high-emphasis disabled fills." + }, + { + "name": "--gnrc-color-background-neutral-heavy-disabled", + "light": "#0000001a", + "dark": "#ffffff20" + }, + { + "name": "--gnrc-color-background-neutral-subtle-disabled", + "light": "#00000008", + "dark": "#ffffff07" + }, + { + "name": "--gnrc-color-background-brand-heavy", + "light": "#242424", + "dark": "#ffffff" + }, + { + "name": "--gnrc-color-background-brand-loud", + "light": "#6f6f6f", + "dark": "#929292" + }, + { + "name": "--gnrc-color-background-brand-soft", + "light": "#00000014", + "dark": "#ffffff1f" + }, + { + "name": "--gnrc-color-background-brand-subtle", + "light": "#0000000a", + "dark": "#ffffff14" + }, + { + "name": "--gnrc-color-background-brand-transparent", + "light": "#24242400", + "dark": "#ffffff00" + }, + { + "name": "--gnrc-color-background-danger-loud", + "light": "#c02e56", + "dark": "#e55e7a" + }, + { + "name": "--gnrc-color-background-danger-soft", + "light": "#ffe3e6", + "dark": "#5a2932" + }, + { + "name": "--gnrc-color-background-danger-subtle", + "light": "#fff1f3", + "dark": "#402529" + }, + { + "name": "--gnrc-color-background-warning-loud", + "light": "#bb4001", + "dark": "#e56738" + }, + { + "name": "--gnrc-color-background-warning-soft", + "light": "#ffe5dc", + "dark": "#592c1c" + }, + { + "name": "--gnrc-color-background-warning-subtle", + "light": "#fff2ee", + "dark": "#40261d" + }, + { + "name": "--gnrc-color-background-success-loud", + "light": "#008455", + "dark": "#05ad72" + }, + { + "name": "--gnrc-color-background-success-soft", + "light": "#c9f8dd", + "dark": "#0c462d" + }, + { + "name": "--gnrc-color-background-success-subtle", + "light": "#e3fcee", + "dark": "#193426" + }, + { + "name": "--gnrc-color-stroke-neutral-heavy", + "light": "#242424", + "dark": "#dedede" + }, + { + "name": "--gnrc-color-stroke-neutral-loud", + "light": "#6f6f6f", + "dark": "#929292" + }, + { + "name": "--gnrc-color-stroke-neutral-soft", + "light": "#0000006d", + "dark": "#ffffff61" + }, + { + "name": "--gnrc-color-stroke-neutral-subtle", + "light": "#00000021", + "dark": "#ffffff48" + }, + { + "name": "--gnrc-color-stroke-neutral-transparent", + "light": "#24242400", + "dark": "#ffffff00" + }, + { + "name": "--gnrc-color-stroke-neutral-onloud", + "light": "#ffffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-stroke-neutral-disabled", + "light": "#00000014", + "dark": "#ffffff24" + }, + { + "name": "--gnrc-color-stroke-brand-loud", + "light": "#6f6f6f", + "dark": "#929292" + }, + { + "name": "--gnrc-color-stroke-brand-soft", + "light": "#0000006d", + "dark": "#ffffff61" + }, + { + "name": "--gnrc-color-stroke-brand-subtle", + "light": "#00000021", + "dark": "#ffffff48" + }, + { + "name": "--gnrc-color-stroke-brand-onloud", + "light": "#ffffff", + "dark": "#242424" + }, + { + "name": "--gnrc-color-stroke-danger-loud", + "light": "#c02e56", + "dark": "#e55e7a" + }, + { + "name": "--gnrc-color-stroke-danger-soft", + "light": "#e55e7a", + "dark": "#d14164" + }, + { + "name": "--gnrc-color-stroke-danger-subtle", + "light": "#ffd0d6", + "dark": "#76293a" + }, + { + "name": "--gnrc-color-stroke-danger-onloud", + "light": "#ffffff", + "dark": "#242424" + }, + { + "name": "--gnrc-color-stroke-warning-loud", + "light": "#cd4808", + "dark": "#e56738" + }, + { + "name": "--gnrc-color-stroke-warning-soft", + "light": "#fc9571", + "dark": "#cd4808" + }, + { + "name": "--gnrc-color-stroke-warning-subtle", + "light": "#ffd3c4", + "dark": "#762e12" + }, + { + "name": "--gnrc-color-stroke-warning-onloud", + "light": "#ffffff", + "dark": "#242424" + }, + { + "name": "--gnrc-color-stroke-success-loud", + "light": "#008455", + "dark": "#05ad72" + }, + { + "name": "--gnrc-color-stroke-success-soft", + "light": "#5dce97", + "dark": "#008e5c" + }, + { + "name": "--gnrc-color-stroke-success-subtle", + "light": "#b1efcc", + "dark": "#025636" + }, + { + "name": "--gnrc-color-stroke-success-onloud", + "light": "#ffffff", + "dark": "#242424" + }, + { + "name": "--gnrc-color-stroke-focus-inner", + "light": "#ffffff", + "dark": "#000000" + }, + { + "name": "--gnrc-color-stroke-focus-outer", + "light": "#000000", + "dark": "#ffffff" + }, + { + "name": "--gnrc-color-foreground-neutral-primary", + "light": "#000000db", + "dark": "#ffffffde" + }, + { + "name": "--gnrc-color-foreground-neutral-secondary", + "light": "#000000a2", + "dark": "#ffffffa1" + }, + { + "name": "--gnrc-color-foreground-neutral-tertiary", + "light": "#00000090", + "dark": "#ffffff80" + }, + { + "name": "--gnrc-color-foreground-neutral-onloud", + "light": "#ffffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-neutral-disabled", + "light": "#0000006d", + "dark": "#ffffff61" + }, + { + "name": "--gnrc-color-foreground-brand-primary", + "light": "#242424", + "dark": "#dedede" + }, + { + "name": "--gnrc-color-foreground-brand-onloud", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-danger-primary", + "light": "#a62147", + "dark": "#fd8ea1" + }, + { + "name": "--gnrc-color-foreground-danger-onloud", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-warning-primary", + "light": "#a93901", + "dark": "#fc9571" + }, + { + "name": "--gnrc-color-foreground-warning-onloud", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-success-primary", + "light": "#017048", + "dark": "#5dce97" + }, + { + "name": "--gnrc-color-foreground-success-onloud", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-shadow", + "light": "#000000", + "dark": "#000000" + }, + { + "name": "--gnrc-shadow-lowest", + "light": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 5%)", + "dark": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%)" + }, + { + "name": "--gnrc-shadow-lower", + "light": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 8%)", + "dark": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 16%)" + }, + { + "name": "--gnrc-shadow-low", + "light": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 8%)", + "dark": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 16%)" + }, + { + "name": "--gnrc-shadow-high", + "light": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 6%)", + "dark": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%)" + }, + { + "name": "--gnrc-shadow-higher", + "light": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 6%)", + "dark": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 12%)" + }, + { + "name": "--gnrc-shadow-highest", + "light": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 6%)", + "dark": "0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 12%)" + }, + { + "name": "--gnrc-font-weight-functional-regular", + "light": 420, + "dark": 420 + }, + { + "name": "--gnrc-font-weight-functional-medium", + "light": 550, + "dark": 550 + }, + { + "name": "--gnrc-font-weight-functional-semibold", + "light": 600, + "dark": 600 + }, + { + "name": "--gnrc-font-weight-functional-bold", + "light": 625, + "dark": 625 + }, + { + "name": "--gnrc-font-weight-content-regular", + "light": 420, + "dark": 420 + }, + { + "name": "--gnrc-font-weight-content-medium", + "light": 550, + "dark": 550 + }, + { + "name": "--gnrc-font-weight-content-semibold", + "light": 600, + "dark": 600 + }, + { + "name": "--gnrc-font-weight-content-bold", + "light": 625, + "dark": 625 + }, + { + "name": "--gnrc-font-weight-content-editorial-regular", + "light": 420, + "dark": 420 + }, + { + "name": "--gnrc-font-weight-content-editorial-medium", + "light": 550, + "dark": 550 + }, + { + "name": "--gnrc-font-weight-content-editorial-semibold", + "light": 600, + "dark": 600 + }, + { + "name": "--gnrc-font-weight-content-editorial-bold", + "light": 625, + "dark": 625 + }, + { + "name": "--gnrc-font-family-functional", + "light": "'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif", + "dark": "'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif" + }, + { + "name": "--gnrc-font-family-content", + "light": "'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif", + "dark": "'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif" + }, + { + "name": "--gnrc-font-family-content-editorial", + "light": "'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif", + "dark": "'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif" + }, + { + "name": "--gnrc-font-family-content-code", + "light": "'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace", + "dark": "'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace" + }, + { + "name": "--gnrc-letter-spacing-functional-display", + "light": "-0.75%", + "dark": "-0.75%" + }, + { + "name": "--gnrc-letter-spacing-functional-pagetitle", + "light": "-0.75%", + "dark": "-0.75%" + }, + { + "name": "--gnrc-letter-spacing-functional-title-large", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-functional-title-medium", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-functional-title-small", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-functional-subtitle", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-functional-body-large", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-functional-body-medium", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-functional-body-small", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-functional-caption", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-content-statement", + "light": "-0.75%", + "dark": "-0.75%" + }, + { + "name": "--gnrc-letter-spacing-content-expressive-large", + "light": "-0.75%", + "dark": "-0.75%" + }, + { + "name": "--gnrc-letter-spacing-content-expressive-medium", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-content-expressive-small", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-content-h1", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-content-h2", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-content-h3", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-content-h4", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-content-h5", + "light": "-0.15%", + "dark": "-0.15%" + }, + { + "name": "--gnrc-letter-spacing-content-subheadline", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-content-paragraph-large", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-content-paragraph-medium", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-content-paragraph-small", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-content-subtext", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-content-table", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-letter-spacing-content-code", + "light": "0%", + "dark": "0%" + }, + { + "name": "--gnrc-font-size-functional-display", + "light": "4.25rem", + "dark": "4.25rem" + }, + { + "name": "--gnrc-font-size-functional-pagetitle", + "light": "2.5rem", + "dark": "2.5rem" + }, + { + "name": "--gnrc-font-size-functional-title-large", + "light": "2rem", + "dark": "2rem" + }, + { + "name": "--gnrc-font-size-functional-title-medium", + "light": "1.75rem", + "dark": "1.75rem" + }, + { + "name": "--gnrc-font-size-functional-title-small", + "light": "1.5rem", + "dark": "1.5rem" + }, + { + "name": "--gnrc-font-size-functional-subtitle", + "light": "1.25rem", + "dark": "1.25rem" + }, + { + "name": "--gnrc-font-size-functional-body-large", + "light": "1rem", + "dark": "1rem" + }, + { + "name": "--gnrc-font-size-functional-body-medium", + "light": "0.875rem", + "dark": "0.875rem" + }, + { + "name": "--gnrc-font-size-functional-body-small", + "light": "0.75rem", + "dark": "0.75rem" + }, + { + "name": "--gnrc-font-size-functional-caption", + "light": "0.625rem", + "dark": "0.625rem" + }, + { + "name": "--gnrc-font-size-content-statement", + "light": "3.5rem", + "dark": "3.5rem" + }, + { + "name": "--gnrc-font-size-content-expressive-large", + "light": "3rem", + "dark": "3rem" + }, + { + "name": "--gnrc-font-size-content-expressive-medium", + "light": "2.25rem", + "dark": "2.25rem" + }, + { + "name": "--gnrc-font-size-content-expressive-small", + "light": "1.75rem", + "dark": "1.75rem" + }, + { + "name": "--gnrc-font-size-content-h1", + "light": "2.25rem", + "dark": "2.25rem" + }, + { + "name": "--gnrc-font-size-content-h2", + "light": "2rem", + "dark": "2rem" + }, + { + "name": "--gnrc-font-size-content-h3", + "light": "1.75rem", + "dark": "1.75rem" + }, + { + "name": "--gnrc-font-size-content-h4", + "light": "1.5rem", + "dark": "1.5rem" + }, + { + "name": "--gnrc-font-size-content-h5", + "light": "1.25rem", + "dark": "1.25rem" + }, + { + "name": "--gnrc-font-size-content-subheadline", + "light": "1rem", + "dark": "1rem" + }, + { + "name": "--gnrc-font-size-content-paragraph-large", + "light": "1.25rem", + "dark": "1.25rem" + }, + { + "name": "--gnrc-font-size-content-paragraph-medium", + "light": "1rem", + "dark": "1rem" + }, + { + "name": "--gnrc-font-size-content-paragraph-small", + "light": "0.75rem", + "dark": "0.75rem" + }, + { + "name": "--gnrc-font-size-content-subtext", + "light": "0.625rem", + "dark": "0.625rem" + }, + { + "name": "--gnrc-font-size-content-table", + "light": "1rem", + "dark": "1rem" + }, + { + "name": "--gnrc-font-size-content-code", + "light": "1rem", + "dark": "1rem" + }, + { + "name": "--gnrc-line-height-functional-display", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-functional-pagetitle", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-functional-title-large", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-functional-title-medium", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-functional-title-small", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-functional-subtitle", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-functional-body-large", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-functional-body-medium", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-functional-body-small", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-functional-caption", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-content-statement", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-expressive-large", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-expressive-medium", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-expressive-small", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-h1", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-h2", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-h3", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-h4", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-h5", + "light": "120%", + "dark": "120%" + }, + { + "name": "--gnrc-line-height-content-subheadline", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-content-paragraph-large", + "light": "170%", + "dark": "170%" + }, + { + "name": "--gnrc-line-height-content-paragraph-medium", + "light": "170%", + "dark": "170%" + }, + { + "name": "--gnrc-line-height-content-paragraph-small", + "light": "170%", + "dark": "170%" + }, + { + "name": "--gnrc-line-height-content-subtext", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-content-table", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-line-height-content-code", + "light": "140%", + "dark": "140%" + }, + { + "name": "--gnrc-border-radius-base-100", + "light": "4px", + "dark": "4px" + }, + { + "name": "--gnrc-border-radius-base-200", + "light": "8px", + "dark": "8px" + }, + { + "name": "--gnrc-border-radius-base-300", + "light": "12px", + "dark": "12px" + }, + { + "name": "--gnrc-border-radius-base-400", + "light": "16px", + "dark": "16px" + }, + { + "name": "--gnrc-border-radius-base-600", + "light": "24px", + "dark": "24px" + }, + { + "name": "--gnrc-border-radius-base-700", + "light": "28px", + "dark": "28px" + }, + { + "name": "--gnrc-border-radius-circular", + "light": "9999px", + "dark": "9999px" + }, + { + "name": "--gnrc-spacing-component-base-50", + "light": "2px", + "dark": "2px" + }, + { + "name": "--gnrc-spacing-component-base-100", + "light": "4px", + "dark": "4px" + }, + { + "name": "--gnrc-spacing-component-base-150", + "light": "6px", + "dark": "6px" + }, + { + "name": "--gnrc-spacing-component-base-200", + "light": "8px", + "dark": "8px" + }, + { + "name": "--gnrc-spacing-component-base-250", + "light": "10px", + "dark": "10px" + }, + { + "name": "--gnrc-spacing-component-base-300", + "light": "12px", + "dark": "12px" + }, + { + "name": "--gnrc-spacing-component-base-400", + "light": "16px", + "dark": "16px" + }, + { + "name": "--gnrc-spacing-component-base-500", + "light": "20px", + "dark": "20px" + }, + { + "name": "--gnrc-spacing-component-base-600", + "light": "24px", + "dark": "24px" + }, + { + "name": "--gnrc-spacing-component-base-700", + "light": "28px", + "dark": "28px" + }, + { + "name": "--gnrc-spacing-component-base-800", + "light": "32px", + "dark": "32px" + }, + { + "name": "--gnrc-spacing-layout-base-100", + "light": "8px", + "dark": "8px" + }, + { + "name": "--gnrc-spacing-layout-base-200", + "light": "16px", + "dark": "16px" + }, + { + "name": "--gnrc-spacing-layout-base-300", + "light": "24px", + "dark": "24px" + }, + { + "name": "--gnrc-spacing-layout-base-400", + "light": "32px", + "dark": "32px" + }, + { + "name": "--gnrc-spacing-layout-base-450", + "light": "36px", + "dark": "36px" + }, + { + "name": "--gnrc-spacing-layout-base-500", + "light": "40px", + "dark": "40px" + }, + { + "name": "--gnrc-spacing-layout-base-600", + "light": "48px", + "dark": "48px" + }, + { + "name": "--gnrc-spacing-layout-base-700", + "light": "56px", + "dark": "56px" + }, + { + "name": "--gnrc-spacing-layout-base-800", + "light": "64px", + "dark": "64px" + }, + { + "name": "--gnrc-spacing-layout-base-1000", + "light": "80px", + "dark": "80px" + }, + { + "name": "--gnrc-spacing-layout-base-1200", + "light": "96px", + "dark": "96px" + }, + { + "name": "--gnrc-stroke-width-thin", + "light": "1px", + "dark": "1px" + }, + { + "name": "--gnrc-stroke-width-thick", + "light": "2px", + "dark": "2px" + }, + { + "name": "--gnrc-stroke-width-thicker", + "light": "3px", + "dark": "3px" + }, + { + "name": "--gnrc-stroke-width-thickest", + "light": "4px", + "dark": "4px" + }, + { + "name": "--gnrc-motion-duration-base-50", + "light": "50ms", + "dark": "50ms" + }, + { + "name": "--gnrc-motion-duration-base-100", + "light": "100ms", + "dark": "100ms" + }, + { + "name": "--gnrc-motion-duration-base-200", + "light": "200ms", + "dark": "200ms" + }, + { + "name": "--gnrc-motion-duration-base-300", + "light": "300ms", + "dark": "300ms" + }, + { + "name": "--gnrc-motion-duration-base-500", + "light": "500ms", + "dark": "500ms" + }, + { + "name": "--gnrc-motion-duration-base-1000", + "light": "1000ms", + "dark": "1000ms" + }, + { + "name": "--gnrc-motion-easing-functional-enter", + "light": "cubic-bezier(0, 0, 0, 1)", + "dark": "cubic-bezier(0, 0, 0, 1)" + }, + { + "name": "--gnrc-motion-easing-functional-exit", + "light": "cubic-bezier(0.6, 0, 0.75, 0.4)", + "dark": "cubic-bezier(0.6, 0, 0.75, 0.4)" + }, + { + "name": "--gnrc-motion-easing-functional-transition", + "light": "cubic-bezier(0.33, 0, 0, 1)", + "dark": "cubic-bezier(0.33, 0, 0, 1)" + }, + { + "name": "--gnrc-motion-easing-functional-linear", + "light": "cubic-bezier(0, 0, 1, 1)", + "dark": "cubic-bezier(0, 0, 1, 1)" + }, + { + "name": "--gnrc-motion-easing-expressive-enter", + "light": "cubic-bezier(0, 0, 0, 1)", + "dark": "cubic-bezier(0, 0, 0, 1)" + }, + { + "name": "--gnrc-motion-easing-expressive-exit", + "light": "cubic-bezier(0.6, 0, 0.75, 0.4)", + "dark": "cubic-bezier(0.6, 0, 0.75, 0.4)" + }, + { + "name": "--gnrc-motion-easing-expressive-transition", + "light": "cubic-bezier(0.33, 0, 0, 1)", + "dark": "cubic-bezier(0.33, 0, 0, 1)" + } + ], + "interaction": [ + { + "name": "--gnrc-color-surface-neutral-farther-hover", + "light": "#e1e1e1", + "dark": "#2f2f2f" + }, + { + "name": "--gnrc-color-surface-neutral-farther-pressed", + "light": "#d7d7d7", + "dark": "#454545" + }, + { + "name": "--gnrc-color-surface-neutral-far-hover", + "light": "#e8e8e8", + "dark": "#323232" + }, + { + "name": "--gnrc-color-surface-neutral-far-pressed", + "light": "#dedede", + "dark": "#464646" + }, + { + "name": "--gnrc-color-surface-neutral-near-hover", + "light": "#f2f2f2", + "dark": "#2d2d2d" + }, + { + "name": "--gnrc-color-surface-neutral-near-pressed", + "light": "#e8e8e8", + "dark": "#434343" + }, + { + "name": "--gnrc-color-surface-neutral-nearer-hover", + "light": "#f5f5f5", + "dark": "#3a3a3a" + }, + { + "name": "--gnrc-color-surface-neutral-nearer-pressed", + "light": "#ebebeb", + "dark": "#4b4b4b" + }, + { + "name": "--gnrc-color-surface-neutral-translucent-hover", + "light": "#f5f5f58a", + "dark": "#47474788" + }, + { + "name": "--gnrc-color-surface-neutral-translucent-pressed", + "light": "#ebebeb94", + "dark": "#5353538f" + }, + { + "name": "--gnrc-color-background-neutral-heavy-hover", + "light": "#363636", + "dark": "#f5f5f5" + }, + { + "name": "--gnrc-color-background-neutral-heavy-pressed", + "light": "#494949", + "dark": "#ebebeb" + }, + { + "name": "--gnrc-color-background-neutral-loud-hover", + "light": "#787878", + "dark": "#898989" + }, + { + "name": "--gnrc-color-background-neutral-loud-pressed", + "light": "#818181", + "dark": "#808080" + }, + { + "name": "--gnrc-color-background-neutral-soft-hover", + "light": "#0000001e", + "dark": "#ffffff27" + }, + { + "name": "--gnrc-color-background-neutral-soft-pressed", + "light": "#00000028", + "dark": "#ffffff2e" + }, + { + "name": "--gnrc-color-background-neutral-subtle-hover", + "light": "#00000017", + "dark": "#ffffff1c" + }, + { + "name": "--gnrc-color-background-neutral-subtle-pressed", + "light": "#00000021", + "dark": "#ffffff23" + }, + { + "name": "--gnrc-color-background-neutral-transparent-hover", + "light": "#1313130a", + "dark": "#ffffff08" + }, + { + "name": "--gnrc-color-background-neutral-transparent-pressed", + "light": "#05050514", + "dark": "#ffffff0f" + }, + { + "name": "--gnrc-color-background-neutral-translucent-hover", + "light": "#d8d8d88a", + "dark": "#56565688" + }, + { + "name": "--gnrc-color-background-neutral-translucent-pressed", + "light": "#cacaca94", + "dark": "#6d6d6d8f" + }, + { + "name": "--gnrc-color-background-brand-heavy-hover", + "light": "#363636", + "dark": "#f5f5f5" + }, + { + "name": "--gnrc-color-background-brand-heavy-pressed", + "light": "#494949", + "dark": "#ebebeb" + }, + { + "name": "--gnrc-color-background-brand-loud-hover", + "light": "#787878", + "dark": "#898989" + }, + { + "name": "--gnrc-color-background-brand-loud-pressed", + "light": "#818181", + "dark": "#808080" + }, + { + "name": "--gnrc-color-background-brand-soft-hover", + "light": "#0000001e", + "dark": "#ffffff27" + }, + { + "name": "--gnrc-color-background-brand-soft-pressed", + "light": "#00000028", + "dark": "#ffffff2e" + }, + { + "name": "--gnrc-color-background-brand-subtle-hover", + "light": "#00000014", + "dark": "#ffffff1c" + }, + { + "name": "--gnrc-color-background-brand-subtle-pressed", + "light": "#0000001e", + "dark": "#ffffff23" + }, + { + "name": "--gnrc-color-background-brand-transparent-hover", + "light": "#1313130a", + "dark": "#ffffff08" + }, + { + "name": "--gnrc-color-background-brand-transparent-pressed", + "light": "#05050514", + "dark": "#ffffff0f" + }, + { + "name": "--gnrc-color-background-danger-loud-hover", + "light": "#cb395e", + "dark": "#da5471" + }, + { + "name": "--gnrc-color-background-danger-loud-pressed", + "light": "#d54467", + "dark": "#d04b69" + }, + { + "name": "--gnrc-color-background-danger-soft-hover", + "light": "#f5d9dc", + "dark": "#67353e" + }, + { + "name": "--gnrc-color-background-danger-soft-pressed", + "light": "#ebcfd2", + "dark": "#754149" + }, + { + "name": "--gnrc-color-background-danger-subtle-hover", + "light": "#f5e7e9", + "dark": "#503438" + }, + { + "name": "--gnrc-color-background-danger-subtle-pressed", + "light": "#ebdddf", + "dark": "#614448" + }, + { + "name": "--gnrc-color-background-warning-loud-hover", + "light": "#c54a14", + "dark": "#da5d2e" + }, + { + "name": "--gnrc-color-background-warning-loud-pressed", + "light": "#d05321", + "dark": "#d05422" + }, + { + "name": "--gnrc-color-background-warning-soft-hover", + "light": "#f5dbd2", + "dark": "#663828" + }, + { + "name": "--gnrc-color-background-warning-soft-pressed", + "light": "#ebd1c9", + "dark": "#744434" + }, + { + "name": "--gnrc-color-background-warning-subtle-hover", + "light": "#f5e8e4", + "dark": "#51352c" + }, + { + "name": "--gnrc-color-background-warning-subtle-pressed", + "light": "#ebdeda", + "dark": "#62453b" + }, + { + "name": "--gnrc-color-background-success-loud-hover", + "light": "#188d5d", + "dark": "#00a369" + }, + { + "name": "--gnrc-color-background-success-loud-pressed", + "light": "#279666", + "dark": "#009a60" + }, + { + "name": "--gnrc-color-background-success-soft-hover", + "light": "#bfeed3", + "dark": "#1c5238" + }, + { + "name": "--gnrc-color-background-success-soft-pressed", + "light": "#b6e4ca", + "dark": "#295f44" + }, + { + "name": "--gnrc-color-background-success-subtle-hover", + "light": "#d9f2e4", + "dark": "#294435" + }, + { + "name": "--gnrc-color-background-success-subtle-pressed", + "light": "#cfe8da", + "dark": "#385445" + }, + { + "name": "--gnrc-color-stroke-neutral-heavy-hover", + "light": "#363636", + "dark": "#d4d4d4" + }, + { + "name": "--gnrc-color-stroke-neutral-heavy-pressed", + "light": "#494949", + "dark": "#cbcbcb" + }, + { + "name": "--gnrc-color-stroke-neutral-loud-hover", + "light": "#787878", + "dark": "#898989" + }, + { + "name": "--gnrc-color-stroke-neutral-loud-pressed", + "light": "#818181", + "dark": "#808080" + }, + { + "name": "--gnrc-color-stroke-neutral-soft-hover", + "light": "#02020277", + "dark": "#ffffff69" + }, + { + "name": "--gnrc-color-stroke-neutral-soft-pressed", + "light": "#04040481", + "dark": "#ffffff70" + }, + { + "name": "--gnrc-color-stroke-neutral-subtle-hover", + "light": "#0000002b", + "dark": "#ffffff50" + }, + { + "name": "--gnrc-color-stroke-neutral-subtle-pressed", + "light": "#05050535", + "dark": "#ffffff57" + }, + { + "name": "--gnrc-color-stroke-neutral-transparent-hover", + "light": "#1313130a", + "dark": "#ffffff08" + }, + { + "name": "--gnrc-color-stroke-neutral-transparent-pressed", + "light": "#05050514", + "dark": "#ffffff0f" + }, + { + "name": "--gnrc-color-stroke-neutral-onloud-hover", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-stroke-neutral-onloud-pressed", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-stroke-brand-loud-hover", + "light": "#787878", + "dark": "#898989" + }, + { + "name": "--gnrc-color-stroke-brand-loud-pressed", + "light": "#818181", + "dark": "#808080" + }, + { + "name": "--gnrc-color-stroke-brand-soft-hover", + "light": "#02020277", + "dark": "#ffffff69" + }, + { + "name": "--gnrc-color-stroke-brand-soft-pressed", + "light": "#04040481", + "dark": "#ffffff70" + }, + { + "name": "--gnrc-color-stroke-brand-subtle-hover", + "light": "#0000002b", + "dark": "#ffffff50" + }, + { + "name": "--gnrc-color-stroke-brand-subtle-pressed", + "light": "#05050535", + "dark": "#ffffff57" + }, + { + "name": "--gnrc-color-stroke-brand-onloud-hover", + "light": "#ffffff", + "dark": "#131313" + }, + { + "name": "--gnrc-color-stroke-brand-onloud-pressed", + "light": "#ffffff", + "dark": "#050505" + }, + { + "name": "--gnrc-color-stroke-danger-loud-hover", + "light": "#cb395e", + "dark": "#da5471" + }, + { + "name": "--gnrc-color-stroke-danger-loud-pressed", + "light": "#d54467", + "dark": "#d04b69" + }, + { + "name": "--gnrc-color-stroke-danger-soft-hover", + "light": "#da5471", + "dark": "#dc4b6d" + }, + { + "name": "--gnrc-color-stroke-danger-soft-pressed", + "light": "#d04b69", + "dark": "#e65575" + }, + { + "name": "--gnrc-color-stroke-danger-subtle-hover", + "light": "#f5c6cc", + "dark": "#803242" + }, + { + "name": "--gnrc-color-stroke-danger-subtle-pressed", + "light": "#ebbdc3", + "dark": "#893a4a" + }, + { + "name": "--gnrc-color-stroke-danger-onloud-hover", + "light": "#ffffff", + "dark": "#131313" + }, + { + "name": "--gnrc-color-stroke-danger-onloud-pressed", + "light": "#ffffff", + "dark": "#050505" + }, + { + "name": "--gnrc-color-stroke-warning-loud-hover", + "light": "#d8521a", + "dark": "#da5d2e" + }, + { + "name": "--gnrc-color-stroke-warning-loud-pressed", + "light": "#e25c27", + "dark": "#d05422" + }, + { + "name": "--gnrc-color-stroke-warning-soft-hover", + "light": "#f28c68", + "dark": "#d8521a" + }, + { + "name": "--gnrc-color-stroke-warning-soft-pressed", + "light": "#e7825f", + "dark": "#e25c27" + }, + { + "name": "--gnrc-color-stroke-warning-subtle-hover", + "light": "#f5c9ba", + "dark": "#7f371b" + }, + { + "name": "--gnrc-color-stroke-warning-subtle-pressed", + "light": "#ebc0b1", + "dark": "#893f24" + }, + { + "name": "--gnrc-color-stroke-warning-onloud-hover", + "light": "#ffffff", + "dark": "#131313" + }, + { + "name": "--gnrc-color-stroke-warning-onloud-pressed", + "light": "#ffffff", + "dark": "#050505" + }, + { + "name": "--gnrc-color-stroke-success-loud-hover", + "light": "#188d5d", + "dark": "#00a369" + }, + { + "name": "--gnrc-color-stroke-success-loud-pressed", + "light": "#279666", + "dark": "#009a60" + }, + { + "name": "--gnrc-color-stroke-success-soft-hover", + "light": "#52c48e", + "dark": "#1a9765" + }, + { + "name": "--gnrc-color-stroke-success-soft-pressed", + "light": "#47bb85", + "dark": "#2aa16d" + }, + { + "name": "--gnrc-color-stroke-success-subtle-hover", + "light": "#a7e5c2", + "dark": "#125f3e" + }, + { + "name": "--gnrc-color-stroke-success-subtle-pressed", + "light": "#9edbb9", + "dark": "#1e6746" + }, + { + "name": "--gnrc-color-stroke-success-onloud-hover", + "light": "#ffffff", + "dark": "#131313" + }, + { + "name": "--gnrc-color-stroke-success-onloud-pressed", + "light": "#ffffff", + "dark": "#050505" + }, + { + "name": "--gnrc-color-foreground-neutral-primary-hover", + "light": "#000000e5", + "dark": "#ffffffe6" + }, + { + "name": "--gnrc-color-foreground-neutral-primary-pressed", + "light": "#000000ef", + "dark": "#ffffffed" + }, + { + "name": "--gnrc-color-foreground-neutral-secondary-hover", + "light": "#000000ac", + "dark": "#ffffffa9" + }, + { + "name": "--gnrc-color-foreground-neutral-secondary-pressed", + "light": "#000000b6", + "dark": "#ffffffb0" + }, + { + "name": "--gnrc-color-foreground-neutral-tertiary-hover", + "light": "#0000009a", + "dark": "#ffffff88" + }, + { + "name": "--gnrc-color-foreground-neutral-tertiary-pressed", + "light": "#000000a4", + "dark": "#ffffff8f" + }, + { + "name": "--gnrc-color-foreground-neutral-onloud-hover", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-neutral-onloud-pressed", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-brand-primary-hover", + "light": "#131313", + "dark": "#e8e8e8" + }, + { + "name": "--gnrc-color-foreground-brand-primary-pressed", + "light": "#050505", + "dark": "#f2f2f2" + }, + { + "name": "--gnrc-color-foreground-brand-onloud-hover", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-brand-onloud-pressed", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-danger-primary-hover", + "light": "#9c133f", + "dark": "#ff97aa" + }, + { + "name": "--gnrc-color-foreground-danger-primary-pressed", + "light": "#910037", + "dark": "#ffa1b4" + }, + { + "name": "--gnrc-color-foreground-danger-onloud-hover", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-danger-onloud-pressed", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-warning-primary-hover", + "light": "#9f2f00", + "dark": "#ff9f7a" + }, + { + "name": "--gnrc-color-foreground-warning-primary-pressed", + "light": "#952500", + "dark": "#ffa884" + }, + { + "name": "--gnrc-color-foreground-warning-onloud-hover", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-warning-onloud-pressed", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-success-primary-hover", + "light": "#006740", + "dark": "#67d8a0" + }, + { + "name": "--gnrc-color-foreground-success-primary-pressed", + "light": "#005f38", + "dark": "#72e2aa" + }, + { + "name": "--gnrc-color-foreground-success-onloud-hover", + "light": "#ffffff", + "dark": "#000000db" + }, + { + "name": "--gnrc-color-foreground-success-onloud-pressed", + "light": "#ffffff", + "dark": "#000000db" + } + ], + "textstyle": [ + { + "name": "textstyle-functional-display", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-medium", + "font_size": "--gnrc-font-size-functional-display", + "line_height": "--gnrc-line-height-functional-display", + "letter_spacing": "--gnrc-letter-spacing-functional-display", + "optical_size": 36 + }, + { + "name": "textstyle-functional-pagetitle", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-medium", + "font_size": "--gnrc-font-size-functional-pagetitle", + "line_height": "--gnrc-line-height-functional-pagetitle", + "letter_spacing": "--gnrc-letter-spacing-functional-pagetitle", + "optical_size": 36 + }, + { + "name": "textstyle-functional-title-large", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-semibold", + "font_size": "--gnrc-font-size-functional-title-large", + "line_height": "--gnrc-line-height-functional-title-large", + "letter_spacing": "--gnrc-letter-spacing-functional-title-large", + "optical_size": 36 + }, + { + "name": "textstyle-functional-title-medium", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-semibold", + "font_size": "--gnrc-font-size-functional-title-medium", + "line_height": "--gnrc-line-height-functional-title-medium", + "letter_spacing": "--gnrc-letter-spacing-functional-title-medium", + "optical_size": 36 + }, + { + "name": "textstyle-functional-title-small", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-semibold", + "font_size": "--gnrc-font-size-functional-title-small", + "line_height": "--gnrc-line-height-functional-title-small", + "letter_spacing": "--gnrc-letter-spacing-functional-title-small", + "optical_size": 36 + }, + { + "name": "textstyle-functional-subtitle", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-semibold", + "font_size": "--gnrc-font-size-functional-subtitle", + "line_height": "--gnrc-line-height-functional-subtitle", + "letter_spacing": "--gnrc-letter-spacing-functional-subtitle", + "optical_size": 36 + }, + { + "name": "textstyle-functional-body-large", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-regular", + "font_size": "--gnrc-font-size-functional-body-large", + "line_height": "--gnrc-line-height-functional-body-large", + "letter_spacing": "--gnrc-letter-spacing-functional-body-large", + "optical_size": 8 + }, + { + "name": "textstyle-functional-body-large-strong", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-bold", + "font_size": "--gnrc-font-size-functional-body-large", + "line_height": "--gnrc-line-height-functional-body-large", + "letter_spacing": "--gnrc-letter-spacing-functional-body-large", + "optical_size": 8 + }, + { + "name": "textstyle-functional-body-medium", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-regular", + "font_size": "--gnrc-font-size-functional-body-medium", + "line_height": "--gnrc-line-height-functional-body-medium", + "letter_spacing": "--gnrc-letter-spacing-functional-body-medium", + "optical_size": 8 + }, + { + "name": "textstyle-functional-body-medium-strong", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-bold", + "font_size": "--gnrc-font-size-functional-body-medium", + "line_height": "--gnrc-line-height-functional-body-medium", + "letter_spacing": "--gnrc-letter-spacing-functional-body-medium", + "optical_size": 8 + }, + { + "name": "textstyle-functional-body-small", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-regular", + "font_size": "--gnrc-font-size-functional-body-small", + "line_height": "--gnrc-line-height-functional-body-small", + "letter_spacing": "--gnrc-letter-spacing-functional-body-small", + "optical_size": 8 + }, + { + "name": "textstyle-functional-body-small-strong", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-bold", + "font_size": "--gnrc-font-size-functional-body-small", + "line_height": "--gnrc-line-height-functional-body-small", + "letter_spacing": "--gnrc-letter-spacing-functional-body-small", + "optical_size": 8 + }, + { + "name": "textstyle-functional-caption", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-regular", + "font_size": "--gnrc-font-size-functional-caption", + "line_height": "--gnrc-line-height-functional-caption", + "letter_spacing": "--gnrc-letter-spacing-functional-caption", + "optical_size": 8 + }, + { + "name": "textstyle-functional-caption-strong", + "font_family": "--gnrc-font-family-functional", + "font_weight": "--gnrc-font-weight-functional-bold", + "font_size": "--gnrc-font-size-functional-caption", + "line_height": "--gnrc-line-height-functional-caption", + "letter_spacing": "--gnrc-letter-spacing-functional-caption", + "optical_size": 8 + }, + { + "name": "textstyle-content-statement", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-statement", + "line_height": "--gnrc-line-height-content-statement", + "letter_spacing": "--gnrc-letter-spacing-content-statement", + "optical_size": 36 + }, + { + "name": "textstyle-content-expressive-large", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-expressive-large", + "line_height": "--gnrc-line-height-content-expressive-large", + "letter_spacing": "--gnrc-letter-spacing-content-expressive-large", + "optical_size": 36 + }, + { + "name": "textstyle-content-expressive-medium", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-expressive-medium", + "line_height": "--gnrc-line-height-content-expressive-medium", + "letter_spacing": "--gnrc-letter-spacing-content-expressive-medium", + "optical_size": 36 + }, + { + "name": "textstyle-content-expressive-small", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-expressive-small", + "line_height": "--gnrc-line-height-content-expressive-small", + "letter_spacing": "--gnrc-letter-spacing-content-expressive-small", + "optical_size": 36 + }, + { + "name": "textstyle-content-h1", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-medium", + "font_size": "--gnrc-font-size-content-h1", + "line_height": "--gnrc-line-height-content-h1", + "letter_spacing": "--gnrc-letter-spacing-content-h1", + "optical_size": 36 + }, + { + "name": "textstyle-content-h2", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-medium", + "font_size": "--gnrc-font-size-content-h2", + "line_height": "--gnrc-line-height-content-h2", + "letter_spacing": "--gnrc-letter-spacing-content-h2", + "optical_size": 36 + }, + { + "name": "textstyle-content-h3", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-medium", + "font_size": "--gnrc-font-size-content-h3", + "line_height": "--gnrc-line-height-content-h3", + "letter_spacing": "--gnrc-letter-spacing-content-h3", + "optical_size": 36 + }, + { + "name": "textstyle-content-h4", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-medium", + "font_size": "--gnrc-font-size-content-h4", + "line_height": "--gnrc-line-height-content-h4", + "letter_spacing": "--gnrc-letter-spacing-content-h4", + "optical_size": 36 + }, + { + "name": "textstyle-content-h5", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-medium", + "font_size": "--gnrc-font-size-content-h5", + "line_height": "--gnrc-line-height-content-h5", + "letter_spacing": "--gnrc-letter-spacing-content-h5", + "optical_size": 36 + }, + { + "name": "textstyle-content-subheadline", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-subheadline", + "line_height": "--gnrc-line-height-content-subheadline", + "letter_spacing": "--gnrc-letter-spacing-content-subheadline", + "optical_size": 36 + }, + { + "name": "textstyle-content-paragraph-large", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-paragraph-large", + "line_height": "--gnrc-line-height-content-paragraph-large", + "letter_spacing": "--gnrc-letter-spacing-content-paragraph-large", + "optical_size": 8 + }, + { + "name": "textstyle-content-paragraph-large-strong", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-bold", + "font_size": "--gnrc-font-size-content-paragraph-large", + "line_height": "--gnrc-line-height-content-paragraph-large", + "letter_spacing": "--gnrc-letter-spacing-content-paragraph-large", + "optical_size": 8 + }, + { + "name": "textstyle-content-paragraph-medium", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-paragraph-medium", + "line_height": "--gnrc-line-height-content-paragraph-medium", + "letter_spacing": "--gnrc-letter-spacing-content-paragraph-medium", + "optical_size": 8 + }, + { + "name": "textstyle-content-paragraph-medium-strong", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-bold", + "font_size": "--gnrc-font-size-content-paragraph-medium", + "line_height": "--gnrc-line-height-content-paragraph-medium", + "letter_spacing": "--gnrc-letter-spacing-content-paragraph-medium", + "optical_size": 8 + }, + { + "name": "textstyle-content-paragraph-small", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-paragraph-small", + "line_height": "--gnrc-line-height-content-paragraph-small", + "letter_spacing": "--gnrc-letter-spacing-content-paragraph-small", + "optical_size": 8 + }, + { + "name": "textstyle-content-paragraph-small-strong", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-bold", + "font_size": "--gnrc-font-size-content-paragraph-small", + "line_height": "--gnrc-line-height-content-paragraph-small", + "letter_spacing": "--gnrc-letter-spacing-content-paragraph-small", + "optical_size": 8 + }, + { + "name": "textstyle-content-subtext", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-subtext", + "line_height": "--gnrc-line-height-content-subtext", + "letter_spacing": "--gnrc-letter-spacing-content-subtext", + "optical_size": 8 + }, + { + "name": "textstyle-content-table", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-table", + "line_height": "--gnrc-line-height-content-table", + "letter_spacing": "--gnrc-letter-spacing-content-table", + "optical_size": 8 + }, + { + "name": "textstyle-content-table-strong", + "font_family": "--gnrc-font-family-content", + "font_weight": "--gnrc-font-weight-content-bold", + "font_size": "--gnrc-font-size-content-table", + "line_height": "--gnrc-line-height-content-table", + "letter_spacing": "--gnrc-letter-spacing-content-table", + "optical_size": 8 + }, + { + "name": "textstyle-content-code", + "font_family": "--gnrc-font-family-content-code", + "font_weight": "--gnrc-font-weight-content-regular", + "font_size": "--gnrc-font-size-content-code", + "line_height": "--gnrc-line-height-content-code", + "letter_spacing": "--gnrc-letter-spacing-content-code", + "optical_size": 8 + }, + { + "name": "textstyle-content-editorial-statement", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-regular", + "font_size": "--gnrc-font-size-content-statement", + "line_height": "--gnrc-line-height-content-statement", + "letter_spacing": "--gnrc-letter-spacing-content-statement", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-expressive-large", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-regular", + "font_size": "--gnrc-font-size-content-expressive-large", + "line_height": "--gnrc-line-height-content-expressive-large", + "letter_spacing": "--gnrc-letter-spacing-content-expressive-large", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-expressive-medium", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-regular", + "font_size": "--gnrc-font-size-content-expressive-medium", + "line_height": "--gnrc-line-height-content-expressive-medium", + "letter_spacing": "--gnrc-letter-spacing-content-expressive-medium", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-expressive-small", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-regular", + "font_size": "--gnrc-font-size-content-expressive-small", + "line_height": "--gnrc-line-height-content-expressive-small", + "letter_spacing": "--gnrc-letter-spacing-content-expressive-small", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-h1", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-medium", + "font_size": "--gnrc-font-size-content-h1", + "line_height": "--gnrc-line-height-content-h1", + "letter_spacing": "--gnrc-letter-spacing-content-h1", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-h2", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-medium", + "font_size": "--gnrc-font-size-content-h2", + "line_height": "--gnrc-line-height-content-h2", + "letter_spacing": "--gnrc-letter-spacing-content-h2", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-h3", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-medium", + "font_size": "--gnrc-font-size-content-h3", + "line_height": "--gnrc-line-height-content-h3", + "letter_spacing": "--gnrc-letter-spacing-content-h3", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-h4", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-medium", + "font_size": "--gnrc-font-size-content-h4", + "line_height": "--gnrc-line-height-content-h4", + "letter_spacing": "--gnrc-letter-spacing-content-h4", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-h5", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-medium", + "font_size": "--gnrc-font-size-content-h5", + "line_height": "--gnrc-line-height-content-h5", + "letter_spacing": "--gnrc-letter-spacing-content-h5", + "optical_size": 36 + }, + { + "name": "textstyle-content-editorial-subheadline", + "font_family": "--gnrc-font-family-content-editorial", + "font_weight": "--gnrc-font-weight-content-editorial-regular", + "font_size": "--gnrc-font-size-content-subheadline", + "line_height": "--gnrc-line-height-content-subheadline", + "letter_spacing": "--gnrc-letter-spacing-content-subheadline", + "optical_size": 36 + } + ] +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-dark.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-dark.css new file mode 100644 index 00000000000..6d51a1eb182 --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-dark.css @@ -0,0 +1,130 @@ +/* Fluent Design — Warm Interaction Fallback (Dark Theme) — precomputed hex and shadows for non-OKLCH environments + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +[data-theme="dark"] { + --gnrc-color-surface-neutral-farther-hover: #342d29; + --gnrc-color-surface-neutral-farther-pressed: #4b423d; + --gnrc-color-surface-neutral-far-hover: #38312b; + --gnrc-color-surface-neutral-far-pressed: #4d453e; + --gnrc-color-surface-neutral-near-hover: #322b27; + --gnrc-color-surface-neutral-near-pressed: #4b413c; + --gnrc-color-surface-neutral-nearer-hover: #403832; + --gnrc-color-surface-neutral-nearer-pressed: #534941; + --gnrc-color-surface-neutral-translucent-hover: #02010188; + --gnrc-color-surface-neutral-translucent-pressed: #0e0b0c8f; + --gnrc-color-background-neutral-heavy-hover: #f6f5f3; + --gnrc-color-background-neutral-heavy-pressed: #edebe7; + --gnrc-color-background-neutral-loud-hover: #f3dfd29a; + --gnrc-color-background-neutral-loud-pressed: #e6d0c09a; + --gnrc-color-background-neutral-soft-hover: #fde1c548; + --gnrc-color-background-neutral-soft-pressed: #ffdec44f; + --gnrc-color-background-neutral-subtle-hover: #ffe8e81c; + --gnrc-color-background-neutral-subtle-pressed: #ffdfdf23; + --gnrc-color-background-neutral-transparent-hover: #fbfaf808; + --gnrc-color-background-neutral-transparent-pressed: #fefcf80f; + --gnrc-color-background-neutral-translucent-hover: #52524e88; + --gnrc-color-background-neutral-translucent-pressed: #67665e8f; + --gnrc-color-background-brand-heavy-hover: #f6f5f3; + --gnrc-color-background-brand-heavy-pressed: #edebe7; + --gnrc-color-background-brand-loud-hover: #f3dfd29a; + --gnrc-color-background-brand-loud-pressed: #e6d0c09a; + --gnrc-color-background-brand-soft-hover: #fde1c548; + --gnrc-color-background-brand-soft-pressed: #ffdec44f; + --gnrc-color-background-brand-subtle-hover: #ffe8e81c; + --gnrc-color-background-brand-subtle-pressed: #ffdfdf23; + --gnrc-color-background-brand-transparent-hover: #fbfaf808; + --gnrc-color-background-brand-transparent-pressed: #fefcf80f; + --gnrc-color-background-danger-loud-hover: #dd5170; + --gnrc-color-background-danger-loud-pressed: #d54467; + --gnrc-color-background-danger-soft-hover: #68343d; + --gnrc-color-background-danger-soft-pressed: #773f49; + --gnrc-color-background-danger-subtle-hover: #523338; + --gnrc-color-background-danger-subtle-pressed: #644247; + --gnrc-color-background-warning-loud-hover: #dd5b28; + --gnrc-color-background-warning-loud-pressed: #d54f13; + --gnrc-color-background-warning-soft-hover: #673726; + --gnrc-color-background-warning-soft-pressed: #764331; + --gnrc-color-background-warning-subtle-hover: #52352b; + --gnrc-color-background-warning-subtle-pressed: #644439; + --gnrc-color-background-success-loud-hover: #00a468; + --gnrc-color-background-success-loud-pressed: #009c5e; + --gnrc-color-background-success-soft-hover: #185338; + --gnrc-color-background-success-soft-pressed: #246043; + --gnrc-color-background-success-subtle-hover: #274435; + --gnrc-color-background-success-subtle-pressed: #355544; + --gnrc-color-stroke-neutral-heavy-hover: #dbd2cb; + --gnrc-color-stroke-neutral-heavy-pressed: #d3c8c0; + --gnrc-color-stroke-neutral-loud-hover: #92877e; + --gnrc-color-stroke-neutral-loud-pressed: #8b7d74; + --gnrc-color-stroke-neutral-soft-hover: #ffe6cf64; + --gnrc-color-stroke-neutral-soft-pressed: #ffe8d06b; + --gnrc-color-stroke-neutral-subtle-hover: #fde1c548; + --gnrc-color-stroke-neutral-subtle-pressed: #ffdec44f; + --gnrc-color-stroke-neutral-transparent-hover: #fbfaf808; + --gnrc-color-stroke-neutral-transparent-pressed: #fefcf80f; + --gnrc-color-stroke-neutral-onloud-hover: #000000e1; + --gnrc-color-stroke-neutral-onloud-pressed: #000000e1; + --gnrc-color-stroke-brand-loud-hover: #92877e; + --gnrc-color-stroke-brand-loud-pressed: #8b7d74; + --gnrc-color-stroke-brand-soft-hover: #ffe6cf64; + --gnrc-color-stroke-brand-soft-pressed: #ffe8d06b; + --gnrc-color-stroke-brand-subtle-hover: #fde1c548; + --gnrc-color-stroke-brand-subtle-pressed: #ffdec44f; + --gnrc-color-stroke-brand-onloud-hover: #000000e1; + --gnrc-color-stroke-brand-onloud-pressed: #000000e1; + --gnrc-color-stroke-danger-loud-hover: #dd5170; + --gnrc-color-stroke-danger-loud-pressed: #d54467; + --gnrc-color-stroke-danger-soft-hover: #de486c; + --gnrc-color-stroke-danger-soft-pressed: #eb4f74; + --gnrc-color-stroke-danger-subtle-hover: #813041; + --gnrc-color-stroke-danger-subtle-pressed: #8c3749; + --gnrc-color-stroke-danger-onloud-hover: #141312; + --gnrc-color-stroke-danger-onloud-pressed: #060504; + --gnrc-color-stroke-warning-loud-hover: #dd5b28; + --gnrc-color-stroke-warning-loud-pressed: #d54f13; + --gnrc-color-stroke-warning-soft-hover: #da4f11; + --gnrc-color-stroke-warning-soft-pressed: #e75618; + --gnrc-color-stroke-warning-subtle-hover: #813518; + --gnrc-color-stroke-warning-subtle-pressed: #8c3c1e; + --gnrc-color-stroke-warning-onloud-hover: #141312; + --gnrc-color-stroke-warning-onloud-pressed: #060504; + --gnrc-color-stroke-success-loud-hover: #00a468; + --gnrc-color-stroke-success-loud-pressed: #009c5e; + --gnrc-color-stroke-success-soft-hover: #089863; + --gnrc-color-stroke-success-soft-pressed: #11a26b; + --gnrc-color-stroke-success-subtle-hover: #0a5f3d; + --gnrc-color-stroke-success-subtle-pressed: #136844; + --gnrc-color-stroke-success-onloud-hover: #141312; + --gnrc-color-stroke-success-onloud-pressed: #060504; + --gnrc-color-foreground-neutral-primary-hover: #fff8f2eb; + --gnrc-color-foreground-neutral-primary-pressed: #fffaf2f2; + --gnrc-color-foreground-neutral-secondary-hover: #fff7ebbd; + --gnrc-color-foreground-neutral-secondary-pressed: #fff9ecc4; + --gnrc-color-foreground-neutral-tertiary-hover: #fff6eaa2; + --gnrc-color-foreground-neutral-tertiary-pressed: #fff8eaa9; + --gnrc-color-foreground-neutral-onloud-hover: #010000e1; + --gnrc-color-foreground-neutral-onloud-pressed: #000000e1; + --gnrc-color-foreground-brand-primary-hover: #fff8f2eb; + --gnrc-color-foreground-brand-primary-pressed: #fffaf2f2; + --gnrc-color-foreground-brand-onloud-hover: #010000e1; + --gnrc-color-foreground-brand-onloud-pressed: #000000e1; + --gnrc-color-foreground-danger-primary-hover: #ff96aa; + --gnrc-color-foreground-danger-primary-pressed: #ff9db2; + --gnrc-color-foreground-danger-onloud-hover: #000000db; + --gnrc-color-foreground-danger-onloud-pressed: #000000db; + --gnrc-color-foreground-warning-primary-hover: #ff9d77; + --gnrc-color-foreground-warning-primary-pressed: #ffa57d; + --gnrc-color-foreground-warning-onloud-hover: #000000db; + --gnrc-color-foreground-warning-onloud-pressed: #000000db; + --gnrc-color-foreground-success-primary-hover: #62d99f; + --gnrc-color-foreground-success-primary-pressed: #67e4a7; + --gnrc-color-foreground-success-onloud-hover: #000000db; + --gnrc-color-foreground-success-onloud-pressed: #000000db; + --gnrc-shadow-lowest: 0px 0px 2px #00000033, 0px 1px 2px #0000001a; + --gnrc-shadow-lower: 0px 0px 2px #00000033, 0px 2px 4px #00000029; + --gnrc-shadow-low: 0px 0px 2px #00000033, 0px 2px 4px #0000001f, 0px 4px 8px #00000029; + --gnrc-shadow-high: 0px 0px 2px #00000033, 0px 4px 8px #0000001f, 0px 8px 16px #0000001f; + --gnrc-shadow-higher: 0px 0px 2px #00000033, 0px 8px 16px #0000001f, 0px 16px 32px #0000001f; + --gnrc-shadow-highest: 0px 0px 2px #00000033, 0px 8px 16px #0000001f, 0px 32px 64px #0000001f; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-light.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-light.css new file mode 100644 index 00000000000..ffb1ef7e3ed --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-light.css @@ -0,0 +1,130 @@ +/* Fluent Design — Warm Interaction Fallback (Light Theme) — precomputed hex and shadows for non-OKLCH environments + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +:root, [data-theme="light"] { + --gnrc-color-surface-neutral-farther-hover: #e8e0d9; + --gnrc-color-surface-neutral-farther-pressed: #dfd6ce; + --gnrc-color-surface-neutral-far-hover: #f2eae4; + --gnrc-color-surface-neutral-far-pressed: #e9dfd9; + --gnrc-color-surface-neutral-near-hover: #ede7e0; + --gnrc-color-surface-neutral-near-pressed: #e5ddd4; + --gnrc-color-surface-neutral-nearer-hover: #f6f5f3; + --gnrc-color-surface-neutral-nearer-pressed: #edebe7; + --gnrc-color-surface-neutral-translucent-hover: #f7f6f48a; + --gnrc-color-surface-neutral-translucent-pressed: #f0eeea94; + --gnrc-color-background-neutral-heavy-hover: #3b352e; + --gnrc-color-background-neutral-heavy-pressed: #50473f; + --gnrc-color-background-neutral-loud-hover: #2e1a0a9a; + --gnrc-color-background-neutral-loud-pressed: #3f28169a; + --gnrc-color-background-neutral-soft-hover: #61330f32; + --gnrc-color-background-neutral-soft-pressed: #6a3b193c; + --gnrc-color-background-neutral-subtle-hover: #7f471c24; + --gnrc-color-background-neutral-subtle-pressed: #8b53272e; + --gnrc-color-background-neutral-transparent-hover: #231d170a; + --gnrc-color-background-neutral-transparent-pressed: #1e170f14; + --gnrc-color-background-neutral-translucent-hover: #dcdcd68a; + --gnrc-color-background-neutral-translucent-pressed: #d2cfc894; + --gnrc-color-background-brand-heavy-hover: #3b352e; + --gnrc-color-background-brand-heavy-pressed: #50473f; + --gnrc-color-background-brand-loud-hover: #2e1a0a9a; + --gnrc-color-background-brand-loud-pressed: #3f28169a; + --gnrc-color-background-brand-soft-hover: #61330f32; + --gnrc-color-background-brand-soft-pressed: #6a3b193c; + --gnrc-color-background-brand-subtle-hover: #7f471c24; + --gnrc-color-background-brand-subtle-pressed: #8b53272e; + --gnrc-color-background-brand-transparent-hover: #231d170a; + --gnrc-color-background-brand-transparent-pressed: #1e170f14; + --gnrc-color-background-danger-loud-hover: #cd355e; + --gnrc-color-background-danger-loud-pressed: #da3c65; + --gnrc-color-background-danger-soft-hover: #f7d8dc; + --gnrc-color-background-danger-soft-pressed: #efced1; + --gnrc-color-background-danger-subtle-hover: #f7e6e9; + --gnrc-color-background-danger-subtle-pressed: #efdcde; + --gnrc-color-background-warning-loud-hover: #c84709; + --gnrc-color-background-warning-loud-pressed: #d54e11; + --gnrc-color-background-warning-soft-hover: #f7dbd1; + --gnrc-color-background-warning-soft-pressed: #eed0c6; + --gnrc-color-background-warning-subtle-hover: #f7e7e3; + --gnrc-color-background-warning-subtle-pressed: #efddd7; + --gnrc-color-background-success-loud-hover: #088e5c; + --gnrc-color-background-success-loud-pressed: #119864; + --gnrc-color-background-success-soft-hover: #bdefd3; + --gnrc-color-background-success-soft-pressed: #b2e5c8; + --gnrc-color-background-success-subtle-hover: #d7f3e3; + --gnrc-color-background-success-subtle-pressed: #cce9d9; + --gnrc-color-stroke-neutral-heavy-hover: #3b352e; + --gnrc-color-stroke-neutral-heavy-pressed: #50473f; + --gnrc-color-stroke-neutral-loud-hover: #81756c; + --gnrc-color-stroke-neutral-loud-pressed: #8c7e73; + --gnrc-color-stroke-neutral-soft-hover: #2a120280; + --gnrc-color-stroke-neutral-soft-pressed: #2e16048a; + --gnrc-color-stroke-neutral-subtle-hover: #61330f32; + --gnrc-color-stroke-neutral-subtle-pressed: #6a3b193c; + --gnrc-color-stroke-neutral-transparent-hover: #231d170a; + --gnrc-color-stroke-neutral-transparent-pressed: #1e170f14; + --gnrc-color-stroke-neutral-onloud-hover: #fffffd; + --gnrc-color-stroke-neutral-onloud-pressed: #fffffb; + --gnrc-color-stroke-brand-loud-hover: #81756c; + --gnrc-color-stroke-brand-loud-pressed: #8c7e73; + --gnrc-color-stroke-brand-soft-hover: #2a120280; + --gnrc-color-stroke-brand-soft-pressed: #2e16048a; + --gnrc-color-stroke-brand-subtle-hover: #61330f32; + --gnrc-color-stroke-brand-subtle-pressed: #6a3b193c; + --gnrc-color-stroke-brand-onloud-hover: #fffffd; + --gnrc-color-stroke-brand-onloud-pressed: #fffffb; + --gnrc-color-stroke-danger-loud-hover: #cd355e; + --gnrc-color-stroke-danger-loud-pressed: #da3c65; + --gnrc-color-stroke-danger-soft-hover: #dd5170; + --gnrc-color-stroke-danger-soft-pressed: #d54467; + --gnrc-color-stroke-danger-subtle-hover: #f7c5cc; + --gnrc-color-stroke-danger-subtle-pressed: #eebbc2; + --gnrc-color-stroke-danger-onloud-hover: #fffffd; + --gnrc-color-stroke-danger-onloud-pressed: #fffffb; + --gnrc-color-stroke-warning-loud-hover: #da4f11; + --gnrc-color-stroke-warning-loud-pressed: #e75618; + --gnrc-color-stroke-warning-soft-hover: #f48a65; + --gnrc-color-stroke-warning-soft-pressed: #ec7f58; + --gnrc-color-stroke-warning-subtle-hover: #f7c9b9; + --gnrc-color-stroke-warning-subtle-pressed: #eebeae; + --gnrc-color-stroke-warning-onloud-hover: #fffffd; + --gnrc-color-stroke-warning-onloud-pressed: #fffffb; + --gnrc-color-stroke-success-loud-hover: #088e5c; + --gnrc-color-stroke-success-loud-pressed: #119864; + --gnrc-color-stroke-success-soft-hover: #4cc58d; + --gnrc-color-stroke-success-soft-pressed: #39bc82; + --gnrc-color-stroke-success-subtle-hover: #a5e6c2; + --gnrc-color-stroke-success-subtle-pressed: #9adcb7; + --gnrc-color-stroke-success-onloud-hover: #fffffd; + --gnrc-color-stroke-success-onloud-pressed: #fffffb; + --gnrc-color-foreground-neutral-primary-hover: #060300eb; + --gnrc-color-foreground-neutral-primary-pressed: #040100f5; + --gnrc-color-foreground-neutral-secondary-hover: #0a0100b5; + --gnrc-color-foreground-neutral-secondary-pressed: #060000bf; + --gnrc-color-foreground-neutral-tertiary-hover: #0c0100a4; + --gnrc-color-foreground-neutral-tertiary-pressed: #080000ae; + --gnrc-color-foreground-neutral-onloud-hover: #fffffd; + --gnrc-color-foreground-neutral-onloud-pressed: #fffffb; + --gnrc-color-foreground-brand-primary-hover: #060300eb; + --gnrc-color-foreground-brand-primary-pressed: #040100f5; + --gnrc-color-foreground-brand-onloud-hover: #fffffd; + --gnrc-color-foreground-brand-onloud-pressed: #fffffb; + --gnrc-color-foreground-danger-primary-hover: #9e0b3e; + --gnrc-color-foreground-danger-primary-pressed: #950035; + --gnrc-color-foreground-danger-onloud-hover: #fffffd; + --gnrc-color-foreground-danger-onloud-pressed: #fffffb; + --gnrc-color-foreground-warning-primary-hover: #a12c00; + --gnrc-color-foreground-warning-primary-pressed: #991c00; + --gnrc-color-foreground-warning-onloud-hover: #fffffd; + --gnrc-color-foreground-warning-onloud-pressed: #fffffb; + --gnrc-color-foreground-success-primary-hover: #00683f; + --gnrc-color-foreground-success-primary-pressed: #006036; + --gnrc-color-foreground-success-onloud-hover: #fffffd; + --gnrc-color-foreground-success-onloud-pressed: #fffffb; + --gnrc-shadow-lowest: 0px 0px 2px #0000001a, 0px 1px 2px #0000000d; + --gnrc-shadow-lower: 0px 0px 2px #0000001a, 0px 2px 4px #00000014; + --gnrc-shadow-low: 0px 0px 2px #0000001a, 0px 2px 4px #00000008, 0px 4px 8px #00000014; + --gnrc-shadow-high: 0px 0px 2px #0000001a, 0px 4px 8px #00000008, 0px 8px 16px #0000000f; + --gnrc-shadow-higher: 0px 0px 2px #0000001a, 0px 8px 16px #00000008, 0px 16px 32px #0000000f; + --gnrc-shadow-highest: 0px 0px 2px #0000001a, 0px 8px 16px #00000008, 0px 32px 64px #0000000f; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback.css new file mode 100644 index 00000000000..6dbe4a963fd --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback.css @@ -0,0 +1,130 @@ +/* Fluent Design — Warm Interaction Fallback (Light-Dark Adaptive) — precomputed hex and shadows for non-OKLCH environments + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +:root { + --gnrc-color-surface-neutral-farther-hover: light-dark(#e8e0d9, #342d29); + --gnrc-color-surface-neutral-farther-pressed: light-dark(#dfd6ce, #4b423d); + --gnrc-color-surface-neutral-far-hover: light-dark(#f2eae4, #38312b); + --gnrc-color-surface-neutral-far-pressed: light-dark(#e9dfd9, #4d453e); + --gnrc-color-surface-neutral-near-hover: light-dark(#ede7e0, #322b27); + --gnrc-color-surface-neutral-near-pressed: light-dark(#e5ddd4, #4b413c); + --gnrc-color-surface-neutral-nearer-hover: light-dark(#f6f5f3, #403832); + --gnrc-color-surface-neutral-nearer-pressed: light-dark(#edebe7, #534941); + --gnrc-color-surface-neutral-translucent-hover: light-dark(#f7f6f48a, #02010188); + --gnrc-color-surface-neutral-translucent-pressed: light-dark(#f0eeea94, #0e0b0c8f); + --gnrc-color-background-neutral-heavy-hover: light-dark(#3b352e, #f6f5f3); + --gnrc-color-background-neutral-heavy-pressed: light-dark(#50473f, #edebe7); + --gnrc-color-background-neutral-loud-hover: light-dark(#2e1a0a9a, #f3dfd29a); + --gnrc-color-background-neutral-loud-pressed: light-dark(#3f28169a, #e6d0c09a); + --gnrc-color-background-neutral-soft-hover: light-dark(#61330f32, #fde1c548); + --gnrc-color-background-neutral-soft-pressed: light-dark(#6a3b193c, #ffdec44f); + --gnrc-color-background-neutral-subtle-hover: light-dark(#7f471c24, #ffe8e81c); + --gnrc-color-background-neutral-subtle-pressed: light-dark(#8b53272e, #ffdfdf23); + --gnrc-color-background-neutral-transparent-hover: light-dark(#231d170a, #fbfaf808); + --gnrc-color-background-neutral-transparent-pressed: light-dark(#1e170f14, #fefcf80f); + --gnrc-color-background-neutral-translucent-hover: light-dark(#dcdcd68a, #52524e88); + --gnrc-color-background-neutral-translucent-pressed: light-dark(#d2cfc894, #67665e8f); + --gnrc-color-background-brand-heavy-hover: light-dark(#3b352e, #f6f5f3); + --gnrc-color-background-brand-heavy-pressed: light-dark(#50473f, #edebe7); + --gnrc-color-background-brand-loud-hover: light-dark(#2e1a0a9a, #f3dfd29a); + --gnrc-color-background-brand-loud-pressed: light-dark(#3f28169a, #e6d0c09a); + --gnrc-color-background-brand-soft-hover: light-dark(#61330f32, #fde1c548); + --gnrc-color-background-brand-soft-pressed: light-dark(#6a3b193c, #ffdec44f); + --gnrc-color-background-brand-subtle-hover: light-dark(#7f471c24, #ffe8e81c); + --gnrc-color-background-brand-subtle-pressed: light-dark(#8b53272e, #ffdfdf23); + --gnrc-color-background-brand-transparent-hover: light-dark(#231d170a, #fbfaf808); + --gnrc-color-background-brand-transparent-pressed: light-dark(#1e170f14, #fefcf80f); + --gnrc-color-background-danger-loud-hover: light-dark(#cd355e, #dd5170); + --gnrc-color-background-danger-loud-pressed: light-dark(#da3c65, #d54467); + --gnrc-color-background-danger-soft-hover: light-dark(#f7d8dc, #68343d); + --gnrc-color-background-danger-soft-pressed: light-dark(#efced1, #773f49); + --gnrc-color-background-danger-subtle-hover: light-dark(#f7e6e9, #523338); + --gnrc-color-background-danger-subtle-pressed: light-dark(#efdcde, #644247); + --gnrc-color-background-warning-loud-hover: light-dark(#c84709, #dd5b28); + --gnrc-color-background-warning-loud-pressed: light-dark(#d54e11, #d54f13); + --gnrc-color-background-warning-soft-hover: light-dark(#f7dbd1, #673726); + --gnrc-color-background-warning-soft-pressed: light-dark(#eed0c6, #764331); + --gnrc-color-background-warning-subtle-hover: light-dark(#f7e7e3, #52352b); + --gnrc-color-background-warning-subtle-pressed: light-dark(#efddd7, #644439); + --gnrc-color-background-success-loud-hover: light-dark(#088e5c, #00a468); + --gnrc-color-background-success-loud-pressed: light-dark(#119864, #009c5e); + --gnrc-color-background-success-soft-hover: light-dark(#bdefd3, #185338); + --gnrc-color-background-success-soft-pressed: light-dark(#b2e5c8, #246043); + --gnrc-color-background-success-subtle-hover: light-dark(#d7f3e3, #274435); + --gnrc-color-background-success-subtle-pressed: light-dark(#cce9d9, #355544); + --gnrc-color-stroke-neutral-heavy-hover: light-dark(#3b352e, #dbd2cb); + --gnrc-color-stroke-neutral-heavy-pressed: light-dark(#50473f, #d3c8c0); + --gnrc-color-stroke-neutral-loud-hover: light-dark(#81756c, #92877e); + --gnrc-color-stroke-neutral-loud-pressed: light-dark(#8c7e73, #8b7d74); + --gnrc-color-stroke-neutral-soft-hover: light-dark(#2a120280, #ffe6cf64); + --gnrc-color-stroke-neutral-soft-pressed: light-dark(#2e16048a, #ffe8d06b); + --gnrc-color-stroke-neutral-subtle-hover: light-dark(#61330f32, #fde1c548); + --gnrc-color-stroke-neutral-subtle-pressed: light-dark(#6a3b193c, #ffdec44f); + --gnrc-color-stroke-neutral-transparent-hover: light-dark(#231d170a, #fbfaf808); + --gnrc-color-stroke-neutral-transparent-pressed: light-dark(#1e170f14, #fefcf80f); + --gnrc-color-stroke-neutral-onloud-hover: light-dark(#fffffd, #000000e1); + --gnrc-color-stroke-neutral-onloud-pressed: light-dark(#fffffb, #000000e1); + --gnrc-color-stroke-brand-loud-hover: light-dark(#81756c, #92877e); + --gnrc-color-stroke-brand-loud-pressed: light-dark(#8c7e73, #8b7d74); + --gnrc-color-stroke-brand-soft-hover: light-dark(#2a120280, #ffe6cf64); + --gnrc-color-stroke-brand-soft-pressed: light-dark(#2e16048a, #ffe8d06b); + --gnrc-color-stroke-brand-subtle-hover: light-dark(#61330f32, #fde1c548); + --gnrc-color-stroke-brand-subtle-pressed: light-dark(#6a3b193c, #ffdec44f); + --gnrc-color-stroke-brand-onloud-hover: light-dark(#fffffd, #000000e1); + --gnrc-color-stroke-brand-onloud-pressed: light-dark(#fffffb, #000000e1); + --gnrc-color-stroke-danger-loud-hover: light-dark(#cd355e, #dd5170); + --gnrc-color-stroke-danger-loud-pressed: light-dark(#da3c65, #d54467); + --gnrc-color-stroke-danger-soft-hover: light-dark(#dd5170, #de486c); + --gnrc-color-stroke-danger-soft-pressed: light-dark(#d54467, #eb4f74); + --gnrc-color-stroke-danger-subtle-hover: light-dark(#f7c5cc, #813041); + --gnrc-color-stroke-danger-subtle-pressed: light-dark(#eebbc2, #8c3749); + --gnrc-color-stroke-danger-onloud-hover: light-dark(#fffffd, #141312); + --gnrc-color-stroke-danger-onloud-pressed: light-dark(#fffffb, #060504); + --gnrc-color-stroke-warning-loud-hover: light-dark(#da4f11, #dd5b28); + --gnrc-color-stroke-warning-loud-pressed: light-dark(#e75618, #d54f13); + --gnrc-color-stroke-warning-soft-hover: light-dark(#f48a65, #da4f11); + --gnrc-color-stroke-warning-soft-pressed: light-dark(#ec7f58, #e75618); + --gnrc-color-stroke-warning-subtle-hover: light-dark(#f7c9b9, #813518); + --gnrc-color-stroke-warning-subtle-pressed: light-dark(#eebeae, #8c3c1e); + --gnrc-color-stroke-warning-onloud-hover: light-dark(#fffffd, #141312); + --gnrc-color-stroke-warning-onloud-pressed: light-dark(#fffffb, #060504); + --gnrc-color-stroke-success-loud-hover: light-dark(#088e5c, #00a468); + --gnrc-color-stroke-success-loud-pressed: light-dark(#119864, #009c5e); + --gnrc-color-stroke-success-soft-hover: light-dark(#4cc58d, #089863); + --gnrc-color-stroke-success-soft-pressed: light-dark(#39bc82, #11a26b); + --gnrc-color-stroke-success-subtle-hover: light-dark(#a5e6c2, #0a5f3d); + --gnrc-color-stroke-success-subtle-pressed: light-dark(#9adcb7, #136844); + --gnrc-color-stroke-success-onloud-hover: light-dark(#fffffd, #141312); + --gnrc-color-stroke-success-onloud-pressed: light-dark(#fffffb, #060504); + --gnrc-color-foreground-neutral-primary-hover: light-dark(#060300eb, #fff8f2eb); + --gnrc-color-foreground-neutral-primary-pressed: light-dark(#040100f5, #fffaf2f2); + --gnrc-color-foreground-neutral-secondary-hover: light-dark(#0a0100b5, #fff7ebbd); + --gnrc-color-foreground-neutral-secondary-pressed: light-dark(#060000bf, #fff9ecc4); + --gnrc-color-foreground-neutral-tertiary-hover: light-dark(#0c0100a4, #fff6eaa2); + --gnrc-color-foreground-neutral-tertiary-pressed: light-dark(#080000ae, #fff8eaa9); + --gnrc-color-foreground-neutral-onloud-hover: light-dark(#fffffd, #010000e1); + --gnrc-color-foreground-neutral-onloud-pressed: light-dark(#fffffb, #000000e1); + --gnrc-color-foreground-brand-primary-hover: light-dark(#060300eb, #fff8f2eb); + --gnrc-color-foreground-brand-primary-pressed: light-dark(#040100f5, #fffaf2f2); + --gnrc-color-foreground-brand-onloud-hover: light-dark(#fffffd, #010000e1); + --gnrc-color-foreground-brand-onloud-pressed: light-dark(#fffffb, #000000e1); + --gnrc-color-foreground-danger-primary-hover: light-dark(#9e0b3e, #ff96aa); + --gnrc-color-foreground-danger-primary-pressed: light-dark(#950035, #ff9db2); + --gnrc-color-foreground-danger-onloud-hover: light-dark(#fffffd, #000000db); + --gnrc-color-foreground-danger-onloud-pressed: light-dark(#fffffb, #000000db); + --gnrc-color-foreground-warning-primary-hover: light-dark(#a12c00, #ff9d77); + --gnrc-color-foreground-warning-primary-pressed: light-dark(#991c00, #ffa57d); + --gnrc-color-foreground-warning-onloud-hover: light-dark(#fffffd, #000000db); + --gnrc-color-foreground-warning-onloud-pressed: light-dark(#fffffb, #000000db); + --gnrc-color-foreground-success-primary-hover: light-dark(#00683f, #62d99f); + --gnrc-color-foreground-success-primary-pressed: light-dark(#006036, #67e4a7); + --gnrc-color-foreground-success-onloud-hover: light-dark(#fffffd, #000000db); + --gnrc-color-foreground-success-onloud-pressed: light-dark(#fffffb, #000000db); + --gnrc-shadow-lowest: 0px 0px 2px light-dark(#0000001a, #00000033), 0px 1px 2px light-dark(#0000000d, #0000001a); + --gnrc-shadow-lower: 0px 0px 2px light-dark(#0000001a, #00000033), 0px 2px 4px light-dark(#00000014, #00000029); + --gnrc-shadow-low: 0px 0px 2px light-dark(#0000001a, #00000033), 0px 2px 4px light-dark(#00000008, #0000001f), 0px 4px 8px light-dark(#00000014, #00000029); + --gnrc-shadow-high: 0px 0px 2px light-dark(#0000001a, #00000033), 0px 4px 8px light-dark(#00000008, #0000001f), 0px 8px 16px light-dark(#0000000f, #0000001f); + --gnrc-shadow-higher: 0px 0px 2px light-dark(#0000001a, #00000033), 0px 8px 16px light-dark(#00000008, #0000001f), 0px 16px 32px light-dark(#0000000f, #0000001f); + --gnrc-shadow-highest: 0px 0px 2px light-dark(#0000001a, #00000033), 0px 8px 16px light-dark(#00000008, #0000001f), 0px 32px 64px light-dark(#0000000f, #0000001f); +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic-dark.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic-dark.css new file mode 100644 index 00000000000..cacec7d267f --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic-dark.css @@ -0,0 +1,283 @@ +/* Fluent Design — Warm Semantic Tokens (Dark Theme) + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +[data-theme="dark"] { + --gnrc-color-fixed-white: #ffffff; + --gnrc-color-fixed-black: #000000; + --gnrc-color-expression-accent-heavy: #ffffff; + --gnrc-color-expression-accent-loud: #ffeee39a; + --gnrc-color-expression-accent-soft: #ffe3cb40; + --gnrc-color-expression-accent-subtle: #fff4ef14; + --gnrc-color-expression-achromatic-heavy: #ffffff; + --gnrc-color-expression-achromatic-subtle: #000000; + --gnrc-color-expression-gray-heavy: #f5f5f5; + --gnrc-color-expression-gray-loud: #dedede; + --gnrc-color-expression-gray-soft: #929292; + --gnrc-color-expression-gray-subtle: #484848; + --gnrc-color-expression-navy-heavy: #f0f5ff; + --gnrc-color-expression-navy-loud: #cedeff; + --gnrc-color-expression-navy-soft: #5c8df8; + --gnrc-color-expression-navy-subtle: #294482; + --gnrc-color-expression-blue-heavy: #eef6ff; + --gnrc-color-expression-blue-loud: #c6e1ff; + --gnrc-color-expression-blue-soft: #2f95f4; + --gnrc-color-expression-blue-subtle: #0b497f; + --gnrc-color-expression-green-heavy: #e7fce9; + --gnrc-color-expression-green-loud: #baedc1; + --gnrc-color-expression-green-soft: #32ad52; + --gnrc-color-expression-green-subtle: #0c5722; + --gnrc-color-expression-lime-heavy: #e6ffcf; + --gnrc-color-expression-lime-loud: #cbff93; + --gnrc-color-expression-lime-soft: #6da603; + --gnrc-color-expression-lime-subtle: #345200; + --gnrc-color-expression-yellow-heavy: #fff7c4; + --gnrc-color-expression-yellow-loud: #ffed85; + --gnrc-color-expression-yellow-soft: #fbdf06; + --gnrc-color-expression-yellow-subtle: #524800; + --gnrc-color-expression-pumpkin-heavy: #fef2ee; + --gnrc-color-expression-pumpkin-loud: #ffd3c2; + --gnrc-color-expression-pumpkin-soft: #fb966e; + --gnrc-color-expression-pumpkin-subtle: #762f0e; + --gnrc-color-expression-red-heavy: #fff2f0; + --gnrc-color-expression-red-loud: #ffd2cd; + --gnrc-color-expression-red-soft: #e7615b; + --gnrc-color-expression-red-subtle: #772b28; + --gnrc-color-expression-pink-heavy: #fff1f7; + --gnrc-color-expression-pink-loud: #ffcee6; + --gnrc-color-expression-pink-soft: #d961a6; + --gnrc-color-expression-pink-subtle: #6f2b53; + --gnrc-color-expression-purple-heavy: #f7f3ff; + --gnrc-color-expression-purple-loud: #e4d6ff; + --gnrc-color-expression-purple-soft: #a575e8; + --gnrc-color-expression-purple-subtle: #523778; + --gnrc-color-overlay-neutral-translucent: #00000099; + --gnrc-color-surface-neutral-farther: #1e1916; + --gnrc-color-surface-neutral-far: #231e1a; + --gnrc-color-surface-neutral-near: #1c1714; + --gnrc-color-surface-neutral-nearer: #2e2823; + --gnrc-color-surface-neutral-translucent: #00000080; + --gnrc-material-background-thick: #262626ea; + --gnrc-material-background-regular: #2f2f2fd1; + --gnrc-material-background-thin: #3434348b; + --gnrc-color-background-neutral-heavy: #ffffff; + --gnrc-color-background-neutral-loud: #ffeee39a; + --gnrc-color-background-neutral-soft: #ffe3cb40; + --gnrc-color-background-neutral-subtle: #fff4ef14; + --gnrc-color-background-neutral-transparent: #ffffff00; + --gnrc-color-background-neutral-translucent: #3c3c3c80; + --gnrc-color-background-neutral-disabled: #ffffff07; + --gnrc-color-background-neutral-heavy-disabled: #ffffff20; + --gnrc-color-background-neutral-subtle-disabled: #ffffff1b; + --gnrc-color-background-brand-heavy: #ffffff; + --gnrc-color-background-brand-loud: #ffeee39a; + --gnrc-color-background-brand-soft: #ffe3cb40; + --gnrc-color-background-brand-subtle: #fff4ef14; + --gnrc-color-background-brand-transparent: #ffffff00; + --gnrc-color-background-danger-loud: #e55e7a; + --gnrc-color-background-danger-soft: #5a2932; + --gnrc-color-background-danger-subtle: #402529; + --gnrc-color-background-warning-loud: #e56738; + --gnrc-color-background-warning-soft: #592c1c; + --gnrc-color-background-warning-subtle: #40261d; + --gnrc-color-background-success-loud: #05ad72; + --gnrc-color-background-success-soft: #0c462d; + --gnrc-color-background-success-subtle: #193426; + --gnrc-color-stroke-neutral-heavy: #e3dcd7; + --gnrc-color-stroke-neutral-loud: #9a9089; + --gnrc-color-stroke-neutral-soft: #ffe6d35c; + --gnrc-color-stroke-neutral-subtle: #ffe3cb40; + --gnrc-color-stroke-neutral-transparent: #ffffff00; + --gnrc-color-stroke-neutral-onloud: #0b0600e1; + --gnrc-color-stroke-neutral-disabled: #ffffff24; + --gnrc-color-stroke-brand-loud: #9a9089; + --gnrc-color-stroke-brand-soft: #ffe6d35c; + --gnrc-color-stroke-brand-subtle: #ffe3cb40; + --gnrc-color-stroke-brand-onloud: #0b0600e1; + --gnrc-color-stroke-danger-loud: #e55e7a; + --gnrc-color-stroke-danger-soft: #d14164; + --gnrc-color-stroke-danger-subtle: #76293a; + --gnrc-color-stroke-danger-onloud: #242424; + --gnrc-color-stroke-warning-loud: #e56738; + --gnrc-color-stroke-warning-soft: #cd4808; + --gnrc-color-stroke-warning-subtle: #762e12; + --gnrc-color-stroke-warning-onloud: #242424; + --gnrc-color-stroke-success-loud: #05ad72; + --gnrc-color-stroke-success-soft: #008e5c; + --gnrc-color-stroke-success-subtle: #025636; + --gnrc-color-stroke-success-onloud: #242424; + --gnrc-color-stroke-focus-inner: #000000; + --gnrc-color-stroke-focus-outer: #ffffff; + --gnrc-color-foreground-neutral-primary: #fff7f2e3; + --gnrc-color-foreground-neutral-secondary: #fff2e8b5; + --gnrc-color-foreground-neutral-tertiary: #ffeee39a; + --gnrc-color-foreground-neutral-onloud: #0b0600e1; + --gnrc-color-foreground-neutral-disabled: #ffffff61; + --gnrc-color-foreground-brand-primary: #fff7f2e3; + --gnrc-color-foreground-brand-onloud: #0b0600e1; + --gnrc-color-foreground-danger-primary: #fd8ea1; + --gnrc-color-foreground-danger-onloud: #000000db; + --gnrc-color-foreground-warning-primary: #fc9571; + --gnrc-color-foreground-warning-onloud: #000000db; + --gnrc-color-foreground-success-primary: #5dce97; + --gnrc-color-foreground-success-onloud: #000000db; + --gnrc-color-shadow: #000000; + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-font-weight-functional-regular: 420; + --gnrc-font-weight-functional-medium: 550; + --gnrc-font-weight-functional-semibold: 600; + --gnrc-font-weight-functional-bold: 625; + --gnrc-font-weight-content-regular: 420; + --gnrc-font-weight-content-medium: 550; + --gnrc-font-weight-content-semibold: 600; + --gnrc-font-weight-content-bold: 625; + --gnrc-font-weight-content-editorial-regular: 420; + --gnrc-font-weight-content-editorial-medium: 550; + --gnrc-font-weight-content-editorial-semibold: 600; + --gnrc-font-weight-content-editorial-bold: 625; + --gnrc-font-family-functional: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content-editorial: 'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif; + --gnrc-font-family-content-code: 'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace; + --gnrc-letter-spacing-functional-display: -0.0075em; + --gnrc-letter-spacing-functional-pagetitle: -0.0075em; + --gnrc-letter-spacing-functional-title-large: -0.0015em; + --gnrc-letter-spacing-functional-title-medium: -0.0015em; + --gnrc-letter-spacing-functional-title-small: -0.0015em; + --gnrc-letter-spacing-functional-subtitle: -0.0015em; + --gnrc-letter-spacing-functional-body-large: 0em; + --gnrc-letter-spacing-functional-body-medium: 0em; + --gnrc-letter-spacing-functional-body-small: 0em; + --gnrc-letter-spacing-functional-caption: 0em; + --gnrc-letter-spacing-content-statement: -0.0075em; + --gnrc-letter-spacing-content-expressive-large: -0.0075em; + --gnrc-letter-spacing-content-expressive-medium: -0.0015em; + --gnrc-letter-spacing-content-expressive-small: -0.0015em; + --gnrc-letter-spacing-content-h1: -0.0015em; + --gnrc-letter-spacing-content-h2: -0.0015em; + --gnrc-letter-spacing-content-h3: -0.0015em; + --gnrc-letter-spacing-content-h4: -0.0015em; + --gnrc-letter-spacing-content-h5: -0.0015em; + --gnrc-letter-spacing-content-subheadline: 0em; + --gnrc-letter-spacing-content-paragraph-large: 0em; + --gnrc-letter-spacing-content-paragraph-medium: 0em; + --gnrc-letter-spacing-content-paragraph-small: 0em; + --gnrc-letter-spacing-content-subtext: 0em; + --gnrc-letter-spacing-content-table: 0em; + --gnrc-letter-spacing-content-code: 0em; + --gnrc-font-size-functional-display: 4.25rem; + --gnrc-font-size-functional-pagetitle: 2.5rem; + --gnrc-font-size-functional-title-large: 2rem; + --gnrc-font-size-functional-title-medium: 1.75rem; + --gnrc-font-size-functional-title-small: 1.5rem; + --gnrc-font-size-functional-subtitle: 1.25rem; + --gnrc-font-size-functional-body-large: 1rem; + --gnrc-font-size-functional-body-medium: 0.875rem; + --gnrc-font-size-functional-body-small: 0.75rem; + --gnrc-font-size-functional-caption: 0.625rem; + --gnrc-font-size-content-statement: 3.5rem; + --gnrc-font-size-content-expressive-large: 3rem; + --gnrc-font-size-content-expressive-medium: 2.25rem; + --gnrc-font-size-content-expressive-small: 1.75rem; + --gnrc-font-size-content-h1: 2.25rem; + --gnrc-font-size-content-h2: 2rem; + --gnrc-font-size-content-h3: 1.75rem; + --gnrc-font-size-content-h4: 1.5rem; + --gnrc-font-size-content-h5: 1.25rem; + --gnrc-font-size-content-subheadline: 1rem; + --gnrc-font-size-content-paragraph-large: 1.25rem; + --gnrc-font-size-content-paragraph-medium: 1rem; + --gnrc-font-size-content-paragraph-small: 0.75rem; + --gnrc-font-size-content-subtext: 0.625rem; + --gnrc-font-size-content-table: 1rem; + --gnrc-font-size-content-code: 1rem; + --gnrc-line-height-functional-display: round(120%, 2px); + --gnrc-line-height-functional-pagetitle: round(120%, 2px); + --gnrc-line-height-functional-title-large: round(120%, 2px); + --gnrc-line-height-functional-title-medium: round(120%, 2px); + --gnrc-line-height-functional-title-small: round(120%, 2px); + --gnrc-line-height-functional-subtitle: round(140%, 2px); + --gnrc-line-height-functional-body-large: round(140%, 2px); + --gnrc-line-height-functional-body-medium: round(140%, 2px); + --gnrc-line-height-functional-body-small: round(140%, 2px); + --gnrc-line-height-functional-caption: round(140%, 2px); + --gnrc-line-height-content-statement: round(120%, 2px); + --gnrc-line-height-content-expressive-large: round(120%, 2px); + --gnrc-line-height-content-expressive-medium: round(120%, 2px); + --gnrc-line-height-content-expressive-small: round(120%, 2px); + --gnrc-line-height-content-h1: round(120%, 2px); + --gnrc-line-height-content-h2: round(120%, 2px); + --gnrc-line-height-content-h3: round(120%, 2px); + --gnrc-line-height-content-h4: round(120%, 2px); + --gnrc-line-height-content-h5: round(120%, 2px); + --gnrc-line-height-content-subheadline: round(140%, 2px); + --gnrc-line-height-content-paragraph-large: round(170%, 2px); + --gnrc-line-height-content-paragraph-medium: round(170%, 2px); + --gnrc-line-height-content-paragraph-small: round(170%, 2px); + --gnrc-line-height-content-subtext: round(140%, 2px); + --gnrc-line-height-content-table: round(140%, 2px); + --gnrc-line-height-content-code: round(140%, 2px); + --gnrc-border-radius-base-100: 4px; + --gnrc-border-radius-base-200: 8px; + --gnrc-border-radius-base-300: 12px; + --gnrc-border-radius-base-400: 16px; + --gnrc-border-radius-base-600: 24px; + --gnrc-border-radius-base-700: 28px; + --gnrc-border-radius-circular: 9999px; + --gnrc-spacing-component-base-50: 2px; + --gnrc-spacing-component-base-100: 4px; + --gnrc-spacing-component-base-150: 6px; + --gnrc-spacing-component-base-200: 8px; + --gnrc-spacing-component-base-250: 10px; + --gnrc-spacing-component-base-300: 12px; + --gnrc-spacing-component-base-400: 16px; + --gnrc-spacing-component-base-500: 20px; + --gnrc-spacing-component-base-600: 24px; + --gnrc-spacing-component-base-700: 28px; + --gnrc-spacing-component-base-800: 32px; + --gnrc-spacing-layout-base-100: 8px; + --gnrc-spacing-layout-base-200: 16px; + --gnrc-spacing-layout-base-300: 24px; + --gnrc-spacing-layout-base-400: 32px; + --gnrc-spacing-layout-base-450: 36px; + --gnrc-spacing-layout-base-500: 40px; + --gnrc-spacing-layout-base-600: 48px; + --gnrc-spacing-layout-base-700: 56px; + --gnrc-spacing-layout-base-800: 64px; + --gnrc-spacing-layout-base-1000: 80px; + --gnrc-spacing-layout-base-1200: 96px; + --gnrc-stroke-width-thin: 1px; + --gnrc-stroke-width-thick: 2px; + --gnrc-stroke-width-thicker: 3px; + --gnrc-stroke-width-thickest: 4px; + --gnrc-motion-duration-base-50: 50ms; + --gnrc-motion-duration-base-100: 100ms; + --gnrc-motion-duration-base-200: 200ms; + --gnrc-motion-duration-base-300: 300ms; + --gnrc-motion-duration-base-500: 500ms; + --gnrc-motion-duration-base-1000: 1000ms; + --gnrc-motion-easing-functional-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-functional-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-functional-transition: cubic-bezier(0.33, 0, 0, 1); + --gnrc-motion-easing-functional-linear: cubic-bezier(0, 0, 1, 1); + --gnrc-motion-easing-expressive-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-expressive-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-expressive-transition: cubic-bezier(0.33, 0, 0, 1); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: 0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.06; + --interaction-standard-hover: min(calc(l + 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.985) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / calc(alpha + 0.03); + --interaction-standard-pressed: min(calc(l + 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.992) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / calc(alpha + 0.06); + --interaction-inverse-hover: calc(l - 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / alpha; + --interaction-inverse-pressed: calc(l - 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / alpha; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic-light.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic-light.css new file mode 100644 index 00000000000..0c155116e88 --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic-light.css @@ -0,0 +1,283 @@ +/* Fluent Design — Warm Semantic Tokens (Light Theme) + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +:root, [data-theme="light"] { + --gnrc-color-fixed-white: #ffffff; + --gnrc-color-fixed-black: #000000; + --gnrc-color-expression-accent-heavy: #28231e; + --gnrc-color-expression-accent-loud: #1e0d009a; + --gnrc-color-expression-accent-soft: #4d200028; + --gnrc-color-expression-accent-subtle: #6c31001a; + --gnrc-color-expression-achromatic-heavy: #000000; + --gnrc-color-expression-achromatic-subtle: #ffffff; + --gnrc-color-expression-gray-heavy: #484848; + --gnrc-color-expression-gray-loud: #929292; + --gnrc-color-expression-gray-soft: #dedede; + --gnrc-color-expression-gray-subtle: #f5f5f5; + --gnrc-color-expression-navy-heavy: #294482; + --gnrc-color-expression-navy-loud: #5c8df8; + --gnrc-color-expression-navy-soft: #cedeff; + --gnrc-color-expression-navy-subtle: #f0f5ff; + --gnrc-color-expression-blue-heavy: #0b497f; + --gnrc-color-expression-blue-loud: #2f95f4; + --gnrc-color-expression-blue-soft: #c6e1ff; + --gnrc-color-expression-blue-subtle: #eef6ff; + --gnrc-color-expression-green-heavy: #0c5722; + --gnrc-color-expression-green-loud: #32ad52; + --gnrc-color-expression-green-soft: #baedc1; + --gnrc-color-expression-green-subtle: #e7fce9; + --gnrc-color-expression-lime-heavy: #345200; + --gnrc-color-expression-lime-loud: #6da603; + --gnrc-color-expression-lime-soft: #cbff93; + --gnrc-color-expression-lime-subtle: #e6ffcf; + --gnrc-color-expression-yellow-heavy: #524800; + --gnrc-color-expression-yellow-loud: #fbdf06; + --gnrc-color-expression-yellow-soft: #ffed85; + --gnrc-color-expression-yellow-subtle: #fff7c4; + --gnrc-color-expression-pumpkin-heavy: #762f0e; + --gnrc-color-expression-pumpkin-loud: #fb966e; + --gnrc-color-expression-pumpkin-soft: #ffd3c2; + --gnrc-color-expression-pumpkin-subtle: #fef2ee; + --gnrc-color-expression-red-heavy: #772b28; + --gnrc-color-expression-red-loud: #e7615b; + --gnrc-color-expression-red-soft: #ffd2cd; + --gnrc-color-expression-red-subtle: #fff2f0; + --gnrc-color-expression-pink-heavy: #6f2b53; + --gnrc-color-expression-pink-loud: #d961a6; + --gnrc-color-expression-pink-soft: #ffcee6; + --gnrc-color-expression-pink-subtle: #fff1f7; + --gnrc-color-expression-purple-heavy: #523778; + --gnrc-color-expression-purple-loud: #a575e8; + --gnrc-color-expression-purple-soft: #e4d6ff; + --gnrc-color-expression-purple-subtle: #f7f3ff; + --gnrc-color-overlay-neutral-translucent: #00000026; + --gnrc-color-surface-neutral-farther: #f0eae5; + --gnrc-color-surface-neutral-far: #faf4f0; + --gnrc-color-surface-neutral-near: #f6f1ec; + --gnrc-color-surface-neutral-nearer: #ffffff; + --gnrc-color-surface-neutral-translucent: #ffffff80; + --gnrc-material-background-thick: #fffffff1; + --gnrc-material-background-regular: #ffffffd7; + --gnrc-material-background-thin: #ffffff7e; + --gnrc-color-background-neutral-heavy: #28231e; + --gnrc-color-background-neutral-loud: #1e0d009a; + --gnrc-color-background-neutral-soft: #4d200028; + --gnrc-color-background-neutral-subtle: #6c31001a; + --gnrc-color-background-neutral-transparent: #28231e00; + --gnrc-color-background-neutral-translucent: #e9e9e980; + --gnrc-color-background-neutral-disabled: #00000008; + --gnrc-color-background-neutral-heavy-disabled: #0000001a; + --gnrc-color-background-neutral-subtle-disabled: #0000000d; + --gnrc-color-background-brand-heavy: #28231e; + --gnrc-color-background-brand-loud: #1e0d009a; + --gnrc-color-background-brand-soft: #4d200028; + --gnrc-color-background-brand-subtle: #6c31001a; + --gnrc-color-background-brand-transparent: #28231e00; + --gnrc-color-background-danger-loud: #c02e56; + --gnrc-color-background-danger-soft: #ffe3e6; + --gnrc-color-background-danger-subtle: #fff1f3; + --gnrc-color-background-warning-loud: #bb4001; + --gnrc-color-background-warning-soft: #ffe5dc; + --gnrc-color-background-warning-subtle: #fff2ee; + --gnrc-color-background-success-loud: #008455; + --gnrc-color-background-success-soft: #c9f8dd; + --gnrc-color-background-success-subtle: #e3fcee; + --gnrc-color-stroke-neutral-heavy: #28231e; + --gnrc-color-stroke-neutral-loud: #776d65; + --gnrc-color-stroke-neutral-soft: #250f0076; + --gnrc-color-stroke-neutral-subtle: #4d200028; + --gnrc-color-stroke-neutral-transparent: #28231e00; + --gnrc-color-stroke-neutral-onloud: #ffffffff; + --gnrc-color-stroke-neutral-disabled: #00000014; + --gnrc-color-stroke-brand-loud: #776d65; + --gnrc-color-stroke-brand-soft: #250f0076; + --gnrc-color-stroke-brand-subtle: #4d200028; + --gnrc-color-stroke-brand-onloud: #ffffffff; + --gnrc-color-stroke-danger-loud: #c02e56; + --gnrc-color-stroke-danger-soft: #e55e7a; + --gnrc-color-stroke-danger-subtle: #ffd0d6; + --gnrc-color-stroke-danger-onloud: #ffffff; + --gnrc-color-stroke-warning-loud: #cd4808; + --gnrc-color-stroke-warning-soft: #fc9571; + --gnrc-color-stroke-warning-subtle: #ffd3c4; + --gnrc-color-stroke-warning-onloud: #ffffff; + --gnrc-color-stroke-success-loud: #008455; + --gnrc-color-stroke-success-soft: #5dce97; + --gnrc-color-stroke-success-subtle: #b1efcc; + --gnrc-color-stroke-success-onloud: #ffffff; + --gnrc-color-stroke-focus-inner: #ffffff; + --gnrc-color-stroke-focus-outer: #000000; + --gnrc-color-foreground-neutral-primary: #0b0600e1; + --gnrc-color-foreground-neutral-secondary: #190c00ab; + --gnrc-color-foreground-neutral-tertiary: #1e0d009a; + --gnrc-color-foreground-neutral-onloud: #ffffffff; + --gnrc-color-foreground-neutral-disabled: #0000006d; + --gnrc-color-foreground-brand-primary: #0b0600e1; + --gnrc-color-foreground-brand-onloud: #ffffffff; + --gnrc-color-foreground-danger-primary: #a62147; + --gnrc-color-foreground-danger-onloud: #ffffff; + --gnrc-color-foreground-warning-primary: #a93901; + --gnrc-color-foreground-warning-onloud: #ffffff; + --gnrc-color-foreground-success-primary: #017048; + --gnrc-color-foreground-success-onloud: #ffffff; + --gnrc-color-shadow: #000000; + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 5%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-font-weight-functional-regular: 420; + --gnrc-font-weight-functional-medium: 550; + --gnrc-font-weight-functional-semibold: 600; + --gnrc-font-weight-functional-bold: 625; + --gnrc-font-weight-content-regular: 420; + --gnrc-font-weight-content-medium: 550; + --gnrc-font-weight-content-semibold: 600; + --gnrc-font-weight-content-bold: 625; + --gnrc-font-weight-content-editorial-regular: 420; + --gnrc-font-weight-content-editorial-medium: 550; + --gnrc-font-weight-content-editorial-semibold: 600; + --gnrc-font-weight-content-editorial-bold: 625; + --gnrc-font-family-functional: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content-editorial: 'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif; + --gnrc-font-family-content-code: 'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace; + --gnrc-letter-spacing-functional-display: -0.0075em; + --gnrc-letter-spacing-functional-pagetitle: -0.0075em; + --gnrc-letter-spacing-functional-title-large: -0.0015em; + --gnrc-letter-spacing-functional-title-medium: -0.0015em; + --gnrc-letter-spacing-functional-title-small: -0.0015em; + --gnrc-letter-spacing-functional-subtitle: -0.0015em; + --gnrc-letter-spacing-functional-body-large: 0em; + --gnrc-letter-spacing-functional-body-medium: 0em; + --gnrc-letter-spacing-functional-body-small: 0em; + --gnrc-letter-spacing-functional-caption: 0em; + --gnrc-letter-spacing-content-statement: -0.0075em; + --gnrc-letter-spacing-content-expressive-large: -0.0075em; + --gnrc-letter-spacing-content-expressive-medium: -0.0015em; + --gnrc-letter-spacing-content-expressive-small: -0.0015em; + --gnrc-letter-spacing-content-h1: -0.0015em; + --gnrc-letter-spacing-content-h2: -0.0015em; + --gnrc-letter-spacing-content-h3: -0.0015em; + --gnrc-letter-spacing-content-h4: -0.0015em; + --gnrc-letter-spacing-content-h5: -0.0015em; + --gnrc-letter-spacing-content-subheadline: 0em; + --gnrc-letter-spacing-content-paragraph-large: 0em; + --gnrc-letter-spacing-content-paragraph-medium: 0em; + --gnrc-letter-spacing-content-paragraph-small: 0em; + --gnrc-letter-spacing-content-subtext: 0em; + --gnrc-letter-spacing-content-table: 0em; + --gnrc-letter-spacing-content-code: 0em; + --gnrc-font-size-functional-display: 4.25rem; + --gnrc-font-size-functional-pagetitle: 2.5rem; + --gnrc-font-size-functional-title-large: 2rem; + --gnrc-font-size-functional-title-medium: 1.75rem; + --gnrc-font-size-functional-title-small: 1.5rem; + --gnrc-font-size-functional-subtitle: 1.25rem; + --gnrc-font-size-functional-body-large: 1rem; + --gnrc-font-size-functional-body-medium: 0.875rem; + --gnrc-font-size-functional-body-small: 0.75rem; + --gnrc-font-size-functional-caption: 0.625rem; + --gnrc-font-size-content-statement: 3.5rem; + --gnrc-font-size-content-expressive-large: 3rem; + --gnrc-font-size-content-expressive-medium: 2.25rem; + --gnrc-font-size-content-expressive-small: 1.75rem; + --gnrc-font-size-content-h1: 2.25rem; + --gnrc-font-size-content-h2: 2rem; + --gnrc-font-size-content-h3: 1.75rem; + --gnrc-font-size-content-h4: 1.5rem; + --gnrc-font-size-content-h5: 1.25rem; + --gnrc-font-size-content-subheadline: 1rem; + --gnrc-font-size-content-paragraph-large: 1.25rem; + --gnrc-font-size-content-paragraph-medium: 1rem; + --gnrc-font-size-content-paragraph-small: 0.75rem; + --gnrc-font-size-content-subtext: 0.625rem; + --gnrc-font-size-content-table: 1rem; + --gnrc-font-size-content-code: 1rem; + --gnrc-line-height-functional-display: round(120%, 2px); + --gnrc-line-height-functional-pagetitle: round(120%, 2px); + --gnrc-line-height-functional-title-large: round(120%, 2px); + --gnrc-line-height-functional-title-medium: round(120%, 2px); + --gnrc-line-height-functional-title-small: round(120%, 2px); + --gnrc-line-height-functional-subtitle: round(140%, 2px); + --gnrc-line-height-functional-body-large: round(140%, 2px); + --gnrc-line-height-functional-body-medium: round(140%, 2px); + --gnrc-line-height-functional-body-small: round(140%, 2px); + --gnrc-line-height-functional-caption: round(140%, 2px); + --gnrc-line-height-content-statement: round(120%, 2px); + --gnrc-line-height-content-expressive-large: round(120%, 2px); + --gnrc-line-height-content-expressive-medium: round(120%, 2px); + --gnrc-line-height-content-expressive-small: round(120%, 2px); + --gnrc-line-height-content-h1: round(120%, 2px); + --gnrc-line-height-content-h2: round(120%, 2px); + --gnrc-line-height-content-h3: round(120%, 2px); + --gnrc-line-height-content-h4: round(120%, 2px); + --gnrc-line-height-content-h5: round(120%, 2px); + --gnrc-line-height-content-subheadline: round(140%, 2px); + --gnrc-line-height-content-paragraph-large: round(170%, 2px); + --gnrc-line-height-content-paragraph-medium: round(170%, 2px); + --gnrc-line-height-content-paragraph-small: round(170%, 2px); + --gnrc-line-height-content-subtext: round(140%, 2px); + --gnrc-line-height-content-table: round(140%, 2px); + --gnrc-line-height-content-code: round(140%, 2px); + --gnrc-border-radius-base-100: 4px; + --gnrc-border-radius-base-200: 8px; + --gnrc-border-radius-base-300: 12px; + --gnrc-border-radius-base-400: 16px; + --gnrc-border-radius-base-600: 24px; + --gnrc-border-radius-base-700: 28px; + --gnrc-border-radius-circular: 9999px; + --gnrc-spacing-component-base-50: 2px; + --gnrc-spacing-component-base-100: 4px; + --gnrc-spacing-component-base-150: 6px; + --gnrc-spacing-component-base-200: 8px; + --gnrc-spacing-component-base-250: 10px; + --gnrc-spacing-component-base-300: 12px; + --gnrc-spacing-component-base-400: 16px; + --gnrc-spacing-component-base-500: 20px; + --gnrc-spacing-component-base-600: 24px; + --gnrc-spacing-component-base-700: 28px; + --gnrc-spacing-component-base-800: 32px; + --gnrc-spacing-layout-base-100: 8px; + --gnrc-spacing-layout-base-200: 16px; + --gnrc-spacing-layout-base-300: 24px; + --gnrc-spacing-layout-base-400: 32px; + --gnrc-spacing-layout-base-450: 36px; + --gnrc-spacing-layout-base-500: 40px; + --gnrc-spacing-layout-base-600: 48px; + --gnrc-spacing-layout-base-700: 56px; + --gnrc-spacing-layout-base-800: 64px; + --gnrc-spacing-layout-base-1000: 80px; + --gnrc-spacing-layout-base-1200: 96px; + --gnrc-stroke-width-thin: 1px; + --gnrc-stroke-width-thick: 2px; + --gnrc-stroke-width-thicker: 3px; + --gnrc-stroke-width-thickest: 4px; + --gnrc-motion-duration-base-50: 50ms; + --gnrc-motion-duration-base-100: 100ms; + --gnrc-motion-duration-base-200: 200ms; + --gnrc-motion-duration-base-300: 300ms; + --gnrc-motion-duration-base-500: 500ms; + --gnrc-motion-duration-base-1000: 1000ms; + --gnrc-motion-easing-functional-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-functional-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-functional-transition: cubic-bezier(0.33, 0, 0, 1); + --gnrc-motion-easing-functional-linear: cubic-bezier(0, 0, 1, 1); + --gnrc-motion-easing-expressive-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-expressive-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-expressive-transition: cubic-bezier(0.33, 0, 0, 1); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: -0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: -0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.04; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.08; + --interaction-standard-hover: max(calc(l - 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.1) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / calc(alpha + 0.04); + --interaction-standard-pressed: max(calc(l - 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.08) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / calc(alpha + 0.08); + --interaction-inverse-hover: calc(l + 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / alpha; + --interaction-inverse-pressed: calc(l + 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / alpha; +} diff --git a/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic.css b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic.css new file mode 100644 index 00000000000..dfe8416dffb --- /dev/null +++ b/packages/agentic/design/scripts/token-mappings/__fixtures__/x3/warm/semantic.css @@ -0,0 +1,351 @@ +/* Fluent Design — Warm Semantic Tokens (Light-Dark Adaptive) + * Auto-generated by scripts/build.mjs — do not edit manually. + */ + +:root { + color-scheme: light dark; + --gnrc-color-fixed-white: #ffffff; + --gnrc-color-fixed-black: #000000; + --gnrc-color-expression-accent-heavy: light-dark(#28231e, #ffffff); + --gnrc-color-expression-accent-loud: light-dark(#1e0d009a, #ffeee39a); + --gnrc-color-expression-accent-soft: light-dark(#4d200028, #ffe3cb40); + --gnrc-color-expression-accent-subtle: light-dark(#6c31001a, #fff4ef14); + --gnrc-color-expression-achromatic-heavy: light-dark(#000000, #ffffff); + --gnrc-color-expression-achromatic-subtle: light-dark(#ffffff, #000000); + --gnrc-color-expression-gray-heavy: light-dark(#484848, #f5f5f5); + --gnrc-color-expression-gray-loud: light-dark(#929292, #dedede); + --gnrc-color-expression-gray-soft: light-dark(#dedede, #929292); + --gnrc-color-expression-gray-subtle: light-dark(#f5f5f5, #484848); + --gnrc-color-expression-navy-heavy: light-dark(#294482, #f0f5ff); + --gnrc-color-expression-navy-loud: light-dark(#5c8df8, #cedeff); + --gnrc-color-expression-navy-soft: light-dark(#cedeff, #5c8df8); + --gnrc-color-expression-navy-subtle: light-dark(#f0f5ff, #294482); + --gnrc-color-expression-blue-heavy: light-dark(#0b497f, #eef6ff); + --gnrc-color-expression-blue-loud: light-dark(#2f95f4, #c6e1ff); + --gnrc-color-expression-blue-soft: light-dark(#c6e1ff, #2f95f4); + --gnrc-color-expression-blue-subtle: light-dark(#eef6ff, #0b497f); + --gnrc-color-expression-green-heavy: light-dark(#0c5722, #e7fce9); + --gnrc-color-expression-green-loud: light-dark(#32ad52, #baedc1); + --gnrc-color-expression-green-soft: light-dark(#baedc1, #32ad52); + --gnrc-color-expression-green-subtle: light-dark(#e7fce9, #0c5722); + --gnrc-color-expression-lime-heavy: light-dark(#345200, #e6ffcf); + --gnrc-color-expression-lime-loud: light-dark(#6da603, #cbff93); + --gnrc-color-expression-lime-soft: light-dark(#cbff93, #6da603); + --gnrc-color-expression-lime-subtle: light-dark(#e6ffcf, #345200); + --gnrc-color-expression-yellow-heavy: light-dark(#524800, #fff7c4); + --gnrc-color-expression-yellow-loud: light-dark(#fbdf06, #ffed85); + --gnrc-color-expression-yellow-soft: light-dark(#ffed85, #fbdf06); + --gnrc-color-expression-yellow-subtle: light-dark(#fff7c4, #524800); + --gnrc-color-expression-pumpkin-heavy: light-dark(#762f0e, #fef2ee); + --gnrc-color-expression-pumpkin-loud: light-dark(#fb966e, #ffd3c2); + --gnrc-color-expression-pumpkin-soft: light-dark(#ffd3c2, #fb966e); + --gnrc-color-expression-pumpkin-subtle: light-dark(#fef2ee, #762f0e); + --gnrc-color-expression-red-heavy: light-dark(#772b28, #fff2f0); + --gnrc-color-expression-red-loud: light-dark(#e7615b, #ffd2cd); + --gnrc-color-expression-red-soft: light-dark(#ffd2cd, #e7615b); + --gnrc-color-expression-red-subtle: light-dark(#fff2f0, #772b28); + --gnrc-color-expression-pink-heavy: light-dark(#6f2b53, #fff1f7); + --gnrc-color-expression-pink-loud: light-dark(#d961a6, #ffcee6); + --gnrc-color-expression-pink-soft: light-dark(#ffcee6, #d961a6); + --gnrc-color-expression-pink-subtle: light-dark(#fff1f7, #6f2b53); + --gnrc-color-expression-purple-heavy: light-dark(#523778, #f7f3ff); + --gnrc-color-expression-purple-loud: light-dark(#a575e8, #e4d6ff); + --gnrc-color-expression-purple-soft: light-dark(#e4d6ff, #a575e8); + --gnrc-color-expression-purple-subtle: light-dark(#f7f3ff, #523778); + --gnrc-color-overlay-neutral-translucent: light-dark(#00000026, #00000099); + --gnrc-color-surface-neutral-farther: light-dark(#f0eae5, #1e1916); + --gnrc-color-surface-neutral-far: light-dark(#faf4f0, #231e1a); + --gnrc-color-surface-neutral-near: light-dark(#f6f1ec, #1c1714); + --gnrc-color-surface-neutral-nearer: light-dark(#ffffff, #2e2823); + --gnrc-color-surface-neutral-translucent: light-dark(#ffffff80, #00000080); + --gnrc-material-background-thick: light-dark(#fffffff1, #262626ea); + --gnrc-material-background-regular: light-dark(#ffffffd7, #2f2f2fd1); + --gnrc-material-background-thin: light-dark(#ffffff7e, #3434348b); + --gnrc-color-background-neutral-heavy: light-dark(#28231e, #ffffff); + --gnrc-color-background-neutral-loud: light-dark(#1e0d009a, #ffeee39a); + --gnrc-color-background-neutral-soft: light-dark(#4d200028, #ffe3cb40); + --gnrc-color-background-neutral-subtle: light-dark(#6c31001a, #fff4ef14); + --gnrc-color-background-neutral-transparent: light-dark(#28231e00, #ffffff00); + --gnrc-color-background-neutral-translucent: light-dark(#e9e9e980, #3c3c3c80); + --gnrc-color-background-neutral-disabled: light-dark(#00000008, #ffffff07); + --gnrc-color-background-neutral-heavy-disabled: light-dark(#0000001a, #ffffff20); + --gnrc-color-background-neutral-subtle-disabled: light-dark(#0000000d, #ffffff1b); + --gnrc-color-background-brand-heavy: light-dark(#28231e, #ffffff); + --gnrc-color-background-brand-loud: light-dark(#1e0d009a, #ffeee39a); + --gnrc-color-background-brand-soft: light-dark(#4d200028, #ffe3cb40); + --gnrc-color-background-brand-subtle: light-dark(#6c31001a, #fff4ef14); + --gnrc-color-background-brand-transparent: light-dark(#28231e00, #ffffff00); + --gnrc-color-background-danger-loud: light-dark(#c02e56, #e55e7a); + --gnrc-color-background-danger-soft: light-dark(#ffe3e6, #5a2932); + --gnrc-color-background-danger-subtle: light-dark(#fff1f3, #402529); + --gnrc-color-background-warning-loud: light-dark(#bb4001, #e56738); + --gnrc-color-background-warning-soft: light-dark(#ffe5dc, #592c1c); + --gnrc-color-background-warning-subtle: light-dark(#fff2ee, #40261d); + --gnrc-color-background-success-loud: light-dark(#008455, #05ad72); + --gnrc-color-background-success-soft: light-dark(#c9f8dd, #0c462d); + --gnrc-color-background-success-subtle: light-dark(#e3fcee, #193426); + --gnrc-color-stroke-neutral-heavy: light-dark(#28231e, #e3dcd7); + --gnrc-color-stroke-neutral-loud: light-dark(#776d65, #9a9089); + --gnrc-color-stroke-neutral-soft: light-dark(#250f0076, #ffe6d35c); + --gnrc-color-stroke-neutral-subtle: light-dark(#4d200028, #ffe3cb40); + --gnrc-color-stroke-neutral-transparent: light-dark(#28231e00, #ffffff00); + --gnrc-color-stroke-neutral-onloud: light-dark(#ffffffff, #0b0600e1); + --gnrc-color-stroke-neutral-disabled: light-dark(#00000014, #ffffff24); + --gnrc-color-stroke-brand-loud: light-dark(#776d65, #9a9089); + --gnrc-color-stroke-brand-soft: light-dark(#250f0076, #ffe6d35c); + --gnrc-color-stroke-brand-subtle: light-dark(#4d200028, #ffe3cb40); + --gnrc-color-stroke-brand-onloud: light-dark(#ffffffff, #0b0600e1); + --gnrc-color-stroke-danger-loud: light-dark(#c02e56, #e55e7a); + --gnrc-color-stroke-danger-soft: light-dark(#e55e7a, #d14164); + --gnrc-color-stroke-danger-subtle: light-dark(#ffd0d6, #76293a); + --gnrc-color-stroke-danger-onloud: light-dark(#ffffff, #242424); + --gnrc-color-stroke-warning-loud: light-dark(#cd4808, #e56738); + --gnrc-color-stroke-warning-soft: light-dark(#fc9571, #cd4808); + --gnrc-color-stroke-warning-subtle: light-dark(#ffd3c4, #762e12); + --gnrc-color-stroke-warning-onloud: light-dark(#ffffff, #242424); + --gnrc-color-stroke-success-loud: light-dark(#008455, #05ad72); + --gnrc-color-stroke-success-soft: light-dark(#5dce97, #008e5c); + --gnrc-color-stroke-success-subtle: light-dark(#b1efcc, #025636); + --gnrc-color-stroke-success-onloud: light-dark(#ffffff, #242424); + --gnrc-color-stroke-focus-inner: light-dark(#ffffff, #000000); + --gnrc-color-stroke-focus-outer: light-dark(#000000, #ffffff); + --gnrc-color-foreground-neutral-primary: light-dark(#0b0600e1, #fff7f2e3); + --gnrc-color-foreground-neutral-secondary: light-dark(#190c00ab, #fff2e8b5); + --gnrc-color-foreground-neutral-tertiary: light-dark(#1e0d009a, #ffeee39a); + --gnrc-color-foreground-neutral-onloud: light-dark(#ffffffff, #0b0600e1); + --gnrc-color-foreground-neutral-disabled: light-dark(#0000006d, #ffffff61); + --gnrc-color-foreground-brand-primary: light-dark(#0b0600e1, #fff7f2e3); + --gnrc-color-foreground-brand-onloud: light-dark(#ffffffff, #0b0600e1); + --gnrc-color-foreground-danger-primary: light-dark(#a62147, #fd8ea1); + --gnrc-color-foreground-danger-onloud: light-dark(#ffffff, #000000db); + --gnrc-color-foreground-warning-primary: light-dark(#a93901, #fc9571); + --gnrc-color-foreground-warning-onloud: light-dark(#ffffff, #000000db); + --gnrc-color-foreground-success-primary: light-dark(#017048, #5dce97); + --gnrc-color-foreground-success-onloud: light-dark(#ffffff, #000000db); + --gnrc-color-shadow: #000000; + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 5%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-font-weight-functional-regular: 420; + --gnrc-font-weight-functional-medium: 550; + --gnrc-font-weight-functional-semibold: 600; + --gnrc-font-weight-functional-bold: 625; + --gnrc-font-weight-content-regular: 420; + --gnrc-font-weight-content-medium: 550; + --gnrc-font-weight-content-semibold: 600; + --gnrc-font-weight-content-bold: 625; + --gnrc-font-weight-content-editorial-regular: 420; + --gnrc-font-weight-content-editorial-medium: 550; + --gnrc-font-weight-content-editorial-semibold: 600; + --gnrc-font-weight-content-editorial-bold: 625; + --gnrc-font-family-functional: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content: 'Segoe Sans', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif; + --gnrc-font-family-content-editorial: 'Segoe Serif', 'Georgia Pro', Georgia, 'Times New Roman', serif; + --gnrc-font-family-content-code: 'Consolas', 'Courier New', 'Monaco', 'Lucida Console', monospace; + --gnrc-letter-spacing-functional-display: -0.0075em; + --gnrc-letter-spacing-functional-pagetitle: -0.0075em; + --gnrc-letter-spacing-functional-title-large: -0.0015em; + --gnrc-letter-spacing-functional-title-medium: -0.0015em; + --gnrc-letter-spacing-functional-title-small: -0.0015em; + --gnrc-letter-spacing-functional-subtitle: -0.0015em; + --gnrc-letter-spacing-functional-body-large: 0em; + --gnrc-letter-spacing-functional-body-medium: 0em; + --gnrc-letter-spacing-functional-body-small: 0em; + --gnrc-letter-spacing-functional-caption: 0em; + --gnrc-letter-spacing-content-statement: -0.0075em; + --gnrc-letter-spacing-content-expressive-large: -0.0075em; + --gnrc-letter-spacing-content-expressive-medium: -0.0015em; + --gnrc-letter-spacing-content-expressive-small: -0.0015em; + --gnrc-letter-spacing-content-h1: -0.0015em; + --gnrc-letter-spacing-content-h2: -0.0015em; + --gnrc-letter-spacing-content-h3: -0.0015em; + --gnrc-letter-spacing-content-h4: -0.0015em; + --gnrc-letter-spacing-content-h5: -0.0015em; + --gnrc-letter-spacing-content-subheadline: 0em; + --gnrc-letter-spacing-content-paragraph-large: 0em; + --gnrc-letter-spacing-content-paragraph-medium: 0em; + --gnrc-letter-spacing-content-paragraph-small: 0em; + --gnrc-letter-spacing-content-subtext: 0em; + --gnrc-letter-spacing-content-table: 0em; + --gnrc-letter-spacing-content-code: 0em; + --gnrc-font-size-functional-display: 4.25rem; + --gnrc-font-size-functional-pagetitle: 2.5rem; + --gnrc-font-size-functional-title-large: 2rem; + --gnrc-font-size-functional-title-medium: 1.75rem; + --gnrc-font-size-functional-title-small: 1.5rem; + --gnrc-font-size-functional-subtitle: 1.25rem; + --gnrc-font-size-functional-body-large: 1rem; + --gnrc-font-size-functional-body-medium: 0.875rem; + --gnrc-font-size-functional-body-small: 0.75rem; + --gnrc-font-size-functional-caption: 0.625rem; + --gnrc-font-size-content-statement: 3.5rem; + --gnrc-font-size-content-expressive-large: 3rem; + --gnrc-font-size-content-expressive-medium: 2.25rem; + --gnrc-font-size-content-expressive-small: 1.75rem; + --gnrc-font-size-content-h1: 2.25rem; + --gnrc-font-size-content-h2: 2rem; + --gnrc-font-size-content-h3: 1.75rem; + --gnrc-font-size-content-h4: 1.5rem; + --gnrc-font-size-content-h5: 1.25rem; + --gnrc-font-size-content-subheadline: 1rem; + --gnrc-font-size-content-paragraph-large: 1.25rem; + --gnrc-font-size-content-paragraph-medium: 1rem; + --gnrc-font-size-content-paragraph-small: 0.75rem; + --gnrc-font-size-content-subtext: 0.625rem; + --gnrc-font-size-content-table: 1rem; + --gnrc-font-size-content-code: 1rem; + --gnrc-line-height-functional-display: round(120%, 2px); + --gnrc-line-height-functional-pagetitle: round(120%, 2px); + --gnrc-line-height-functional-title-large: round(120%, 2px); + --gnrc-line-height-functional-title-medium: round(120%, 2px); + --gnrc-line-height-functional-title-small: round(120%, 2px); + --gnrc-line-height-functional-subtitle: round(140%, 2px); + --gnrc-line-height-functional-body-large: round(140%, 2px); + --gnrc-line-height-functional-body-medium: round(140%, 2px); + --gnrc-line-height-functional-body-small: round(140%, 2px); + --gnrc-line-height-functional-caption: round(140%, 2px); + --gnrc-line-height-content-statement: round(120%, 2px); + --gnrc-line-height-content-expressive-large: round(120%, 2px); + --gnrc-line-height-content-expressive-medium: round(120%, 2px); + --gnrc-line-height-content-expressive-small: round(120%, 2px); + --gnrc-line-height-content-h1: round(120%, 2px); + --gnrc-line-height-content-h2: round(120%, 2px); + --gnrc-line-height-content-h3: round(120%, 2px); + --gnrc-line-height-content-h4: round(120%, 2px); + --gnrc-line-height-content-h5: round(120%, 2px); + --gnrc-line-height-content-subheadline: round(140%, 2px); + --gnrc-line-height-content-paragraph-large: round(170%, 2px); + --gnrc-line-height-content-paragraph-medium: round(170%, 2px); + --gnrc-line-height-content-paragraph-small: round(170%, 2px); + --gnrc-line-height-content-subtext: round(140%, 2px); + --gnrc-line-height-content-table: round(140%, 2px); + --gnrc-line-height-content-code: round(140%, 2px); + --gnrc-border-radius-base-100: 4px; + --gnrc-border-radius-base-200: 8px; + --gnrc-border-radius-base-300: 12px; + --gnrc-border-radius-base-400: 16px; + --gnrc-border-radius-base-600: 24px; + --gnrc-border-radius-base-700: 28px; + --gnrc-border-radius-circular: 9999px; + --gnrc-spacing-component-base-50: 2px; + --gnrc-spacing-component-base-100: 4px; + --gnrc-spacing-component-base-150: 6px; + --gnrc-spacing-component-base-200: 8px; + --gnrc-spacing-component-base-250: 10px; + --gnrc-spacing-component-base-300: 12px; + --gnrc-spacing-component-base-400: 16px; + --gnrc-spacing-component-base-500: 20px; + --gnrc-spacing-component-base-600: 24px; + --gnrc-spacing-component-base-700: 28px; + --gnrc-spacing-component-base-800: 32px; + --gnrc-spacing-layout-base-100: 8px; + --gnrc-spacing-layout-base-200: 16px; + --gnrc-spacing-layout-base-300: 24px; + --gnrc-spacing-layout-base-400: 32px; + --gnrc-spacing-layout-base-450: 36px; + --gnrc-spacing-layout-base-500: 40px; + --gnrc-spacing-layout-base-600: 48px; + --gnrc-spacing-layout-base-700: 56px; + --gnrc-spacing-layout-base-800: 64px; + --gnrc-spacing-layout-base-1000: 80px; + --gnrc-spacing-layout-base-1200: 96px; + --gnrc-stroke-width-thin: 1px; + --gnrc-stroke-width-thick: 2px; + --gnrc-stroke-width-thicker: 3px; + --gnrc-stroke-width-thickest: 4px; + --gnrc-motion-duration-base-50: 50ms; + --gnrc-motion-duration-base-100: 100ms; + --gnrc-motion-duration-base-200: 200ms; + --gnrc-motion-duration-base-300: 300ms; + --gnrc-motion-duration-base-500: 500ms; + --gnrc-motion-duration-base-1000: 1000ms; + --gnrc-motion-easing-functional-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-functional-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-functional-transition: cubic-bezier(0.33, 0, 0, 1); + --gnrc-motion-easing-functional-linear: cubic-bezier(0, 0, 1, 1); + --gnrc-motion-easing-expressive-enter: cubic-bezier(0, 0, 0, 1); + --gnrc-motion-easing-expressive-exit: cubic-bezier(0.6, 0, 0.75, 0.4); + --gnrc-motion-easing-expressive-transition: cubic-bezier(0.33, 0, 0, 1); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: -0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: -0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.04; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.08; + --interaction-standard-hover: max(calc(l - 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.1) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / calc(alpha + 0.04); + --interaction-standard-pressed: max(calc(l - 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.08) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / calc(alpha + 0.08); + --interaction-inverse-hover: calc(l + 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / alpha; + --interaction-inverse-pressed: calc(l + 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / alpha; +} + +@media (prefers-color-scheme: dark) { + :root { + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 12%); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: 0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.06; + --interaction-standard-hover: min(calc(l + 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.985) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / calc(alpha + 0.03); + --interaction-standard-pressed: min(calc(l + 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.992) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / calc(alpha + 0.06); + --interaction-inverse-hover: calc(l - 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / alpha; + --interaction-inverse-pressed: calc(l - 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / alpha; + } +} + +[data-theme="light"] { + color-scheme: light; + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 5%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 8%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 6%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 3%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 6%); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: -0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: -0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.04; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.08; + --interaction-standard-hover: max(calc(l - 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.1) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / calc(alpha + 0.04); + --interaction-standard-pressed: max(calc(l - 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.08) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / calc(alpha + 0.08); + --interaction-inverse-hover: calc(l + 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / alpha; + --interaction-inverse-pressed: calc(l + 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / alpha; +} + +[data-theme="dark"] { + color-scheme: dark; + --gnrc-shadow-lowest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 1px 2px oklch(from var(--gnrc-color-shadow) l c h / 10%); + --gnrc-shadow-lower: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-low: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 2px 4px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 16%); + --gnrc-shadow-high: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 4px 8px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-higher: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 16px 32px oklch(from var(--gnrc-color-shadow) l c h / 12%); + --gnrc-shadow-highest: 0px 0px 2px oklch(from var(--gnrc-color-shadow) l c h / 20%), 0px 8px 16px oklch(from var(--gnrc-color-shadow) l c h / 12%), 0px 32px 64px oklch(from var(--gnrc-color-shadow) l c h / 12%); + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --lightness-press: 0.06; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-hover: 0.03; + /* @deprecated Interaction fragments now contain mode-specific values directly. Retained for compatibility; remove in 1.0.0. */ + --alpha-press: 0.06; + --interaction-standard-hover: min(calc(l + 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.985) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / calc(alpha + 0.03); + --interaction-standard-pressed: min(calc(l + 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)), 0.992) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / calc(alpha + 0.06); + --interaction-inverse-hover: calc(l - 0.03 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.003,calc(c * .04)),0.006)) h / alpha; + --interaction-inverse-pressed: calc(l - 0.06 * clamp(1,(.5 - l)/.1,3) * clamp(.35,calc(alpha + .35),1)) calc(c + min(max(0.006,calc(c * .08)),0.012)) h / alpha; +} diff --git a/packages/agentic/design/scripts/token-mappings/check-mappings.cjs b/packages/agentic/design/scripts/token-mappings/check-mappings.cjs index 3da0ad61f25..52d2e05776a 100644 --- a/packages/agentic/design/scripts/token-mappings/check-mappings.cjs +++ b/packages/agentic/design/scripts/token-mappings/check-mappings.cjs @@ -9,14 +9,15 @@ const { parse: parseYaml } = nodeRequire(path.join(yamlPackageRoot, 'dist/index. const packageRoot = path.resolve(__dirname, '../..'); const defaultPaths = { - defaultTokens: path.join(packageRoot, 'src/tokens/defaultTokens.ts'), + defaultTokens: path.join(packageRoot, 'src/flex/adapters/fluentFallbackTokens.ts'), flexFromTheme: path.join(packageRoot, 'src/tokens/mappings/flex-from-theme.json'), flexTokenMap: path.join(packageRoot, 'src/tokens/mappings/flex-token-map.yaml'), - flexTypes: path.join(packageRoot, 'src/tokens/flex.types.ts'), + flexTypes: path.join(packageRoot, 'src/flex/tokens.types.ts'), themeFromFlex: path.join(packageRoot, 'src/tokens/mappings/theme-from-flex.json'), }; -const reverseTransforms = new Set(['identity', 'numberToPx']); +const reverseTransforms = new Set(['identity', 'numberToPx', 'shadowLayersToToken']); +const shadowReverseTransform = 'shadowLayersToToken'; function isRecord(value) { return value !== null && typeof value === 'object' && !Array.isArray(value); @@ -44,6 +45,27 @@ function getThemeSource(entry, tokenPath, violations) { return source; } +function getGenericSource(entry, tokenPath, violations) { + if (!Object.hasOwn(entry, 'generic') || entry.generic === null) { + return undefined; + } + + const source = entry.generic; + if (typeof source !== 'string' || !source.startsWith('--gnrc-')) { + addViolation(violations, 'schema', tokenPath, 'a --gnrc-* custom property name or no generic field', source); + return undefined; + } + + return source; +} + +function createMappingEntry(entry, tokenPath, violations) { + return { + genericSource: getGenericSource(entry, tokenPath, violations), + themeSource: getThemeSource(entry, tokenPath, violations), + }; +} + function flattenTokenMappings(mapping, violations) { const entries = new Map(); if (!isRecord(mapping.tokens)) { @@ -58,27 +80,23 @@ function flattenTokenMappings(mapping, violations) { } if (basePath.startsWith('color.') && Object.hasOwn(mappingEntry, 'rest')) { - const colorName = basePath.slice('color.'.length); for (const state of ['rest', 'hover', 'pressed']) { if (!Object.hasOwn(mappingEntry, state)) { continue; } const stateEntry = mappingEntry[state]; - const destination = state === 'rest' ? basePath : `color.${state}.${colorName}`; + const destination = `${basePath}.${state}`; if (!isRecord(stateEntry)) { addViolation(violations, 'schema', destination, 'a color-state mapping object', stateEntry); continue; } - entries.set(destination, { - themeSource: getThemeSource(stateEntry, destination, violations), - }); + entries.set(destination, createMappingEntry(stateEntry, destination, violations)); } } else { - entries.set(basePath, { - themeSource: getThemeSource(mappingEntry, basePath, violations), - }); + const destination = basePath.startsWith('color.') ? `${basePath}.rest` : basePath; + entries.set(destination, createMappingEntry(mappingEntry, destination, violations)); } } @@ -209,6 +227,9 @@ function buildReverseProjection(mapping, mappingEntries, supportedTypePaths, vio descriptor.transform = transform; } } + if (source.startsWith('shadow.') && descriptor.transform !== shadowReverseTransform) { + addViolation(violations, 'reverse-transform', themePath, shadowReverseTransform, transform ?? '<missing>'); + } projectionEntries.push([themePath, descriptor]); } @@ -355,9 +376,9 @@ function readTypePaths(typesPath, typeName) { const paths = new Set(); for (const [groupName, groupType] of resolveProperties(declaration, aliases)) { for (const [tokenName, tokenType] of resolveProperties(groupType, aliases)) { - if (groupName === 'color' && (tokenName === 'hover' || tokenName === 'pressed')) { - for (const stateTokenName of resolveProperties(tokenType, aliases).keys()) { - paths.add(`${groupName}.${tokenName}.${stateTokenName}`); + if (groupName === 'color') { + for (const state of resolveProperties(tokenType, aliases).keys()) { + paths.add(`${groupName}.${tokenName}.${state}`); } } else { paths.add(`${groupName}.${tokenName}`); @@ -408,6 +429,8 @@ function findVariableInitializer(program, variableName) { throw new Error(`Unable to find ${variableName}.`); } +const colorTokenPattern = /^color\.[^.]+$/; + function readNonFluentValues(defaultTokensPath, supportedTypePaths) { const sourceText = fs.readFileSync(defaultTokensPath, 'utf8'); const program = parseTypeScript(sourceText, { @@ -419,7 +442,19 @@ function readNonFluentValues(defaultTokensPath, supportedTypePaths) { const values = new Map(); function collect(expression, prefix) { - const value = unwrapExpression(expression); + let value = unwrapExpression(expression); + if (colorTokenPattern.test(prefix)) { + if (value.type === 'CallExpression' && value.callee.type === 'Identifier' && value.callee.name === 'flexColor') { + value = unwrapExpression(value.arguments[0]); + } + const isOptions = + value.type === 'ObjectExpression' && + value.properties.some((property) => property.type === 'ObjectProperty' && getPropertyName(property) === 'rest'); + if (!isOptions) { + values.set(`${prefix}.rest`, sourceText.slice(value.start, value.end)); + return; + } + } if (prefix && supportedTypePaths.has(prefix)) { values.set(prefix, sourceText.slice(value.start, value.end)); return; @@ -437,6 +472,9 @@ function readNonFluentValues(defaultTokensPath, supportedTypePaths) { } const name = getPropertyName(property); + if (name === 'type' && colorTokenPattern.test(prefix)) { + continue; + } collect(property.value, prefix ? `${prefix}.${name}` : name); } } @@ -462,8 +500,8 @@ function loadMappingInputs(paths = defaultPaths) { } function getInteractionRestPath(tokenPath) { - const match = /^color\.(?:hover|pressed)\.(.+)$/.exec(tokenPath); - return match ? `color.${match[1]}` : undefined; + const match = /^color\.([^.]+)\.(?:hover|pressed)$/.exec(tokenPath); + return match ? `color.${match[1]}.rest` : undefined; } function validateMappingInputs(inputs) { @@ -499,6 +537,18 @@ function validateMappingInputs(inputs) { } } + // Every rest and non-color destination needs a generic source for generated defaults; interaction states are optional. + for (const tokenPath of supportedTypePaths) { + if (getInteractionRestPath(tokenPath) === undefined && !supportedEntries.has(tokenPath)) { + addViolation(violations, 'mapping-coverage', tokenPath, 'a destination in flex-token-map.yaml', '<missing>'); + } + } + for (const [tokenPath, entry] of supportedEntries) { + if (entry.genericSource === undefined) { + addViolation(violations, 'generic-source', tokenPath, 'a generic custom property', '<missing>'); + } + } + for (const [tokenPath, entry] of supportedEntries) { const projectedSource = themeProjection[tokenPath]; if (entry.themeSource === undefined) { diff --git a/packages/agentic/design/scripts/token-mappings/upstream-drift.cjs b/packages/agentic/design/scripts/token-mappings/upstream-drift.cjs index 96fe89570c4..de2d38a22b4 100644 --- a/packages/agentic/design/scripts/token-mappings/upstream-drift.cjs +++ b/packages/agentic/design/scripts/token-mappings/upstream-drift.cjs @@ -4,7 +4,26 @@ const path = require('node:path'); const packageRoot = path.resolve(__dirname, '../..'); const pinPath = path.join(packageRoot, 'src/tokens/mappings/upstream-pin.json'); -const requiredFileIds = ['semanticCss', 'interactionFallbackCss', 'mappings']; +// Every pinned source and how its contents are compared. `css` sources compare custom-property declarations; +// `tokenSections` sources compare the token names listed in their generics and interaction sections. +const requiredFileKinds = { + semanticCss: 'css', + semanticLightCss: 'css', + semanticDarkCss: 'css', + interactionFallbackCss: 'css', + interactionFallbackLightCss: 'css', + interactionFallbackDarkCss: 'css', + warmSemanticCss: 'css', + warmSemanticLightCss: 'css', + warmSemanticDarkCss: 'css', + warmInteractionFallbackCss: 'css', + warmInteractionFallbackLightCss: 'css', + warmInteractionFallbackDarkCss: 'css', + mappings: 'tokenSections', + tokens: 'tokenSections', +}; +const requiredFileIds = Object.keys(requiredFileKinds); +const tokenSectionNames = ['generics', 'interaction']; class UpstreamFetchError extends Error {} @@ -163,17 +182,17 @@ function gitBlobSha(source) { return crypto.createHash('sha1').update(`blob ${content.length}\0`).update(content).digest('hex'); } -function namesFromMappingSection(source, sectionName) { +function namesFromTokenSection(fileId, source, sectionName) { const parsed = JSON.parse(source); const section = parsed[sectionName]; if (!Array.isArray(section)) { - throw new Error(`Upstream mappings.json section ${sectionName} must be an array.`); + throw new Error(`Upstream ${fileId} section ${sectionName} must be an array.`); } return new Set( section.map((entry, index) => { if (!entry || typeof entry.name !== 'string') { - throw new Error(`Upstream mappings.json ${sectionName}[${index}] must have a string name.`); + throw new Error(`Upstream ${fileId} ${sectionName}[${index}] must have a string name.`); } return entry.name; }), @@ -200,17 +219,19 @@ function validateUpstreamContents(contents) { } } - for (const sectionName of ['generics', 'interaction']) { - if (namesFromMappingSection(contents.mappings, sectionName).size === 0) { - throw new Error(`Upstream mappings.json section ${sectionName} must not be empty.`); + for (const [fileId, kind] of Object.entries(requiredFileKinds)) { + if (kind === 'css') { + if (cssDeclarations(contents[fileId]).size === 0) { + throw new Error(`Upstream ${fileId} must declare at least one custom property.`); + } + } else { + for (const sectionName of tokenSectionNames) { + if (namesFromTokenSection(fileId, contents[fileId], sectionName).size === 0) { + throw new Error(`Upstream ${fileId} section ${sectionName} must not be empty.`); + } + } } } - if (cssDeclarations(contents.semanticCss).size === 0) { - throw new Error('Upstream semantic.css must declare at least one custom property.'); - } - if (cssDeclarations(contents.interactionFallbackCss).size === 0) { - throw new Error('Upstream interaction-fallback.css must declare at least one custom property.'); - } } function compareNames(baseline, candidate) { @@ -240,22 +261,25 @@ function hasNameChanges(comparison) { function createReport(pin, baseline, candidate, candidateRef, mode) { const normalizedBaseline = Object.fromEntries(Object.entries(baseline).map(([id, source]) => [id, normalizeSourceContent(source)])); const normalizedCandidate = Object.fromEntries(Object.entries(candidate).map(([id, source]) => [id, normalizeSourceContent(source)])); - const genericTokens = compareNames( - namesFromMappingSection(normalizedBaseline.mappings, 'generics'), - namesFromMappingSection(normalizedCandidate.mappings, 'generics'), - ); - const interactionTokens = compareNames( - namesFromMappingSection(normalizedBaseline.mappings, 'interaction'), - namesFromMappingSection(normalizedCandidate.mappings, 'interaction'), - ); - const semanticProperties = compareNames( - new Set(cssDeclarations(normalizedBaseline.semanticCss).keys()), - new Set(cssDeclarations(normalizedCandidate.semanticCss).keys()), - ); - const interactionFallbackTokens = compareDeclarations( - cssDeclarations(normalizedBaseline.interactionFallbackCss), - cssDeclarations(normalizedCandidate.interactionFallbackCss), - ); + const tokenSections = {}; + const css = {}; + for (const [fileId, kind] of Object.entries(requiredFileKinds)) { + if (kind === 'css') { + css[fileId] = { + customProperties: compareDeclarations(cssDeclarations(normalizedBaseline[fileId]), cssDeclarations(normalizedCandidate[fileId])), + }; + } else { + tokenSections[fileId] = Object.fromEntries( + tokenSectionNames.map((sectionName) => [ + sectionName, + compareNames( + namesFromTokenSection(fileId, normalizedBaseline[fileId], sectionName), + namesFromTokenSection(fileId, normalizedCandidate[fileId], sectionName), + ), + ]), + ); + } + } const contentChangedFiles = pin.files .filter((file) => normalizedBaseline[file.id] !== normalizedCandidate[file.id]) .map((file) => file.upstreamPath); @@ -271,11 +295,8 @@ function createReport(pin, baseline, candidate, candidateRef, mode) { const hasDrift = contentChangedFiles.length > 0 || snapshotIntegrity.some((file) => !file.matches) || - hasNameChanges(genericTokens) || - hasNameChanges(interactionTokens) || - hasNameChanges(semanticProperties) || - hasNameChanges(interactionFallbackTokens) || - interactionFallbackTokens.changed.length > 0; + Object.values(tokenSections).some((sections) => Object.values(sections).some(hasNameChanges)) || + Object.values(css).some(({ customProperties }) => hasNameChanges(customProperties) || customProperties.changed.length > 0); return { repository: pin.repository, @@ -286,16 +307,8 @@ function createReport(pin, baseline, candidate, candidateRef, mode) { hasDrift, contentChangedFiles, snapshotIntegrity, - mappings: { - generics: genericTokens, - interaction: interactionTokens, - }, - semanticCss: { - customProperties: semanticProperties, - }, - interactionFallbackCss: { - tokens: interactionFallbackTokens, - }, + tokenSections, + css, }; } diff --git a/packages/agentic/design/src/color-lib/colorLib.test.ts b/packages/agentic/design/src/color-lib/colorLib.test.ts index 6c6f4f27575..5b851724339 100644 --- a/packages/agentic/design/src/color-lib/colorLib.test.ts +++ b/packages/agentic/design/src/color-lib/colorLib.test.ts @@ -1,12 +1,5 @@ import { PlatformColor } from 'react-native'; -import { - x3BebopWarmInteractionConformance, - x3InteractionConformance, - x3WarmVariantDeviations, -} from '../testing/color-validation/x3InteractionConformance'; -import { defaultFlexTokens } from '../tokens/defaultTokens'; -import type { SemanticColorTokenValues } from '../tokens/flex.types'; import { compositeColor, compositeRgba, @@ -14,38 +7,13 @@ import { getHoverColor, getInteractionColor, getPressColor, - isInverseInteractionToken, oklchToRgb, parseColorValue, resolveContrastColors, rgbaToHex, rgbToOklch, } from './index'; -import type { ColorMode, InteractionColorState } from './index'; -import { getInteractionColorOverrides, getInteractionColors, INTERACTIVE_COLOR_TOKENS } from './interaction'; - -const modeIndexes = { - light: { rest: 0, hover: 1, pressed: 2 }, - dark: { rest: 3, hover: 4, pressed: 5 }, -} as const; - -function conformanceColors(mode: ColorMode): SemanticColorTokenValues { - const { hover: _hover, pressed: _pressed, ...colors } = defaultFlexTokens.color; - for (const token of INTERACTIVE_COLOR_TOKENS) { - colors[token] = x3InteractionConformance[token][modeIndexes[mode].rest]; - } - return colors; -} - -function getStateColor( - state: InteractionColorState, - color: string, - token: (typeof INTERACTIVE_COLOR_TOKENS)[number], - mode: ColorMode, - variant: 'default' | 'bebopWarm', -) { - return state === 'hover' ? getHoverColor(color, token, mode, { variant }) : getPressColor(color, token, mode, { variant }); -} +import type { InteractionColorOptions } from './index'; describe('color parsing and conversion', () => { it('parses supported literal formats', () => { @@ -153,112 +121,84 @@ describe('color compositing and contrast', () => { }); }); -describe.each(['light', 'dark'] as const)('%s interaction colors', (mode) => { - it.each(INTERACTIVE_COLOR_TOKENS)('matches default and Bebop Warm output for %s', (token) => { - const vector = x3InteractionConformance[token]; - const warmVector = x3BebopWarmInteractionConformance[token]; - for (const state of ['hover', 'pressed'] as const) { - const deviationKey = `${token}.${state}.${mode}` as keyof typeof x3WarmVariantDeviations; - const deviation = x3WarmVariantDeviations[deviationKey]; - const upstreamValue = vector[modeIndexes[mode][state]]; - const warmValue = warmVector[modeIndexes[mode][state]]; +describe('raw interaction colors', () => { + it('defaults to the cool tone, standard direction, and direct compositing', () => { + const explicit: InteractionColorOptions = { colorTone: 'cool', direction: 'standard', compositing: 'direct' }; - expect(getStateColor(state, vector[modeIndexes[mode].rest], token, mode, 'default')).toEqual({ - status: 'derived', - value: deviation?.defaultValue ?? upstreamValue, - }); - expect(getStateColor(state, warmVector[modeIndexes[mode].rest], token, mode, 'bebopWarm')).toEqual({ - status: 'derived', - value: warmValue, - }); - if (deviation) { - expect(upstreamValue).toBe(deviation.warmValue); + expect(getHoverColor('#ebebeb', 'light')).toEqual({ status: 'derived', value: '#e1e1e1' }); + expect(getPressColor('#ebebeb', 'light')).toEqual({ status: 'derived', value: '#d7d7d7' }); + for (const state of ['hover', 'pressed'] as const) { + for (const mode of ['light', 'dark'] as const) { + expect(getInteractionColor('#e9e9e980', mode, state)).toEqual(getInteractionColor('#e9e9e980', mode, state, explicit)); } } }); - it('generates a complete override map', () => { - const colors = conformanceColors(mode); - for (const token of INTERACTIVE_COLOR_TOKENS) { - colors[token] = x3BebopWarmInteractionConformance[token][modeIndexes[mode].rest]; - } - const result = getInteractionColorOverrides(colors, mode, 'hover', { variant: 'bebopWarm' }); - - expect(result.diagnostics).toEqual([]); - expect(Object.keys(result.overrides)).toHaveLength(59); + it('shifts standard colors with the scheme and inverted colors against it', () => { + expect(getHoverColor('#242424', 'light', { direction: 'inverted' })).toEqual({ status: 'derived', value: '#363636' }); + expect(getHoverColor('#ffffff', 'dark', { direction: 'inverted' })).toEqual({ status: 'derived', value: '#f5f5f5' }); + expect(getHoverColor('#1b1b1b', 'dark')).toEqual({ status: 'derived', value: '#2f2f2f' }); }); -}); -describe('interaction color API', () => { - it('classifies every inverse token with the upstream heavy/loud/onloud rule', () => { - const expected = [ - 'backgroundNeutralHeavy', - 'backgroundNeutralLoud', - 'backgroundBrandHeavy', - 'backgroundBrandLoud', - 'backgroundDangerLoud', - 'backgroundWarningLoud', - 'backgroundSuccessLoud', - 'strokeNeutralHeavy', - 'strokeNeutralLoud', - 'strokeNeutralOnloud', - 'strokeBrandLoud', - 'strokeBrandOnloud', - 'strokeDangerLoud', - 'strokeDangerOnloud', - 'strokeWarningLoud', - 'strokeWarningOnloud', - 'strokeSuccessLoud', - 'strokeSuccessOnloud', - 'foregroundNeutralOnloud', - 'foregroundBrandOnloud', - 'foregroundDangerOnloud', - 'foregroundWarningOnloud', - 'foregroundSuccessOnloud', - ]; + it('raises standard alpha and keeps inverted alpha', () => { + expect(getHoverColor('#e9e9e980', 'light')).toEqual({ status: 'derived', value: '#dfdfdf8a' }); + const inverted = getHoverColor('#00000080', 'light', { direction: 'inverted' }); - expect(INTERACTIVE_COLOR_TOKENS.filter(isInverseInteractionToken)).toEqual(expected); - expect(INTERACTIVE_COLOR_TOKENS).toHaveLength(59); - expect(Object.keys(x3WarmVariantDeviations)).toHaveLength(10); + expect(inverted.status).toBe('derived'); + expect(inverted.value).toMatch(/80$/); }); - it('fills missing values without replacing authored interaction colors', () => { - const input = { - ...conformanceColors('light'), - hover: { surfaceNeutralFarther: '#123456' }, - }; - const result = getInteractionColors(input, 'light'); + it('applies the warm reference backdrop only to translucent backdrop colors', () => { + const backdrop = getHoverColor('#e9e9e980', 'light', { colorTone: 'warm', compositing: 'backdrop' }); + const direct = getHoverColor('#e9e9e980', 'light', { colorTone: 'warm', compositing: 'direct' }); - expect(result.colors.hover.surfaceNeutralFarther).toBe('#123456'); - expect(result.colors.hover.surfaceNeutralFar).toBe('#e8e8e8'); - expect(result.colors.pressed.surfaceNeutralFarther).toBe('#d7d7d7'); - expect(result.diagnostics).toEqual([]); + expect(backdrop).toEqual({ status: 'derived', value: '#dcdcd68a' }); + expect(direct.status).toBe('derived'); + expect(direct.value).not.toBe(backdrop.value); + expect(direct.value).toMatch(/8a$/); + expect(getHoverColor('#ebebeb', 'light', { colorTone: 'warm', compositing: 'backdrop' })).toEqual( + getHoverColor('#ebebeb', 'light', { colorTone: 'warm', compositing: 'direct' }), + ); }); - it('preserves identity when every interaction value is authored', () => { - const colors = conformanceColors('light'); - const hover = getInteractionColorOverrides(colors, 'light', 'hover').overrides; - const pressed = getInteractionColorOverrides(colors, 'light', 'pressed').overrides; - const input = { ...colors, hover, pressed }; + it('ignores compositing for the cool tone', () => { + expect(getPressColor('#e9e9e980', 'dark', { compositing: 'backdrop' })).toEqual(getPressColor('#e9e9e980', 'dark')); + }); + + it('adds chroma for the warm tone and preserves it for the cool tone', () => { + const cool = getPressColor('#808080', 'light'); + const warm = getPressColor('#808080', 'light', { colorTone: 'warm' }); - expect(getInteractionColors(input, 'light').colors).toBe(input); + expect(cool.status).toBe('derived'); + expect(warm.status).toBe('derived'); + expect(rgbToOklch(hexChannels(cool.value as string)).C).toBeCloseTo(0, 6); + expect(rgbToOklch(hexChannels(warm.value as string)).C).toBeGreaterThan(0.005); }); it('reports opaque platform colors instead of deriving a wrong value', () => { - expect(getInteractionColor(PlatformColor('labelColor'), 'foregroundNeutralPrimary', 'light', 'hover')).toMatchObject({ + const rest = PlatformColor('labelColor'); + const result = getInteractionColor(rest, 'light', 'hover', { colorTone: 'warm' }); + + expect(result).toMatchObject({ status: 'unresolvable', - diagnostic: { - reason: 'non-literal-color', - token: 'foregroundNeutralPrimary', - state: 'hover', - }, + diagnostic: { reason: 'non-literal-color', state: 'hover' }, }); + expect(result.value).toBe(rest); + expect(result.status === 'unresolvable' && 'token' in result.diagnostic).toBe(false); }); it('reports malformed literals', () => { - expect(getPressColor('rgb(12oops 0 0)', 'foregroundDangerPrimary', 'light')).toMatchObject({ + expect(getPressColor('rgb(12oops 0 0)', 'light')).toMatchObject({ status: 'unresolvable', - diagnostic: { reason: 'unsupported-color-format' }, + diagnostic: { reason: 'unsupported-color-format', state: 'pressed' }, }); }); }); + +function hexChannels(value: string) { + const parsed = parseColorValue(value); + if (parsed.status !== 'resolved') { + throw new Error(`Expected a literal color: ${value}`); + } + return parsed.color; +} diff --git a/packages/agentic/design/src/color-lib/index.ts b/packages/agentic/design/src/color-lib/index.ts index fd24af8f2eb..2d431367665 100644 --- a/packages/agentic/design/src/color-lib/index.ts +++ b/packages/agentic/design/src/color-lib/index.ts @@ -3,14 +3,11 @@ export type { ColorDiagnosticReason, ColorMode, InteractionColorDiagnostic, - InteractionColorInput, InteractionColorOptions, - InteractionColorOverridesResult, InteractionColorResult, - InteractionColorsResult, InteractionColorState, - InteractionColorVariant, - InteractiveColorToken, + InteractionCompositing, + InteractionDirection, OklchColor, ParsedColorValue, ResolvedContrastColors, @@ -20,4 +17,4 @@ export type { export { parseColorValue, rgbaToHex } from './parsing'; export { oklchToRgb, rgbToOklch } from './conversion'; export { compositeColor, compositeRgba, getContrastRatio, resolveContrastColors } from './compositing'; -export { getHoverColor, getInteractionColor, getPressColor, isInverseInteractionToken } from './interaction'; +export { getHoverColor, getInteractionColor, getPressColor } from './interaction'; diff --git a/packages/agentic/design/src/color-lib/interaction.ts b/packages/agentic/design/src/color-lib/interaction.ts index 6a824c9b72b..d86a04948b1 100644 --- a/packages/agentic/design/src/color-lib/interaction.ts +++ b/packages/agentic/design/src/color-lib/interaction.ts @@ -3,89 +3,13 @@ import type { ColorValue } from 'react-native'; import { rgbToOklch, oklchToRgb } from './conversion'; import { channelToByte, clamp } from './math'; import { parseColorValue, rgbaToHex } from './parsing'; -import type { - ColorMode, - InteractionColorDiagnostic, - InteractionColorInput, - InteractionColorOptions, - InteractionColorOverridesResult, - InteractionColorResult, - InteractionColorsResult, - InteractionColorState, - InteractiveColorToken, - RgbColor, - RgbaColor, -} from './types'; -import type { InteractiveColorOverrides, SemanticColors, SemanticColorTokenValues } from '../tokens/flex.types'; +import type { ColorMode, InteractionColorOptions, InteractionColorResult, InteractionColorState, RgbColor, RgbaColor } from './types'; /** - * Interactive subset of the Flex semantic color tokens. + * Default interaction lightness and alpha shifts for each state and mode. * - * Source: x3-design/fluent-design@d334acf5cbad813f2b7cd554da942b09a7ff8f10. + * Source: x3-design/fluent-design@206e890b645fb450ad7c5df2ff981765349a2b58. */ -export const INTERACTIVE_COLOR_TOKENS = [ - 'surfaceNeutralFarther', - 'surfaceNeutralFar', - 'surfaceNeutralNear', - 'surfaceNeutralNearer', - 'surfaceNeutralTranslucent', - 'backgroundNeutralHeavy', - 'backgroundNeutralLoud', - 'backgroundNeutralSoft', - 'backgroundNeutralSubtle', - 'backgroundNeutralTransparent', - 'backgroundNeutralTranslucent', - 'backgroundBrandHeavy', - 'backgroundBrandLoud', - 'backgroundBrandSoft', - 'backgroundBrandSubtle', - 'backgroundBrandTransparent', - 'backgroundDangerLoud', - 'backgroundDangerSoft', - 'backgroundDangerSubtle', - 'backgroundWarningLoud', - 'backgroundWarningSoft', - 'backgroundWarningSubtle', - 'backgroundSuccessLoud', - 'backgroundSuccessSoft', - 'backgroundSuccessSubtle', - 'strokeNeutralHeavy', - 'strokeNeutralLoud', - 'strokeNeutralSoft', - 'strokeNeutralSubtle', - 'strokeNeutralTransparent', - 'strokeNeutralOnloud', - 'strokeBrandLoud', - 'strokeBrandSoft', - 'strokeBrandSubtle', - 'strokeBrandOnloud', - 'strokeDangerLoud', - 'strokeDangerSoft', - 'strokeDangerSubtle', - 'strokeDangerOnloud', - 'strokeWarningLoud', - 'strokeWarningSoft', - 'strokeWarningSubtle', - 'strokeWarningOnloud', - 'strokeSuccessLoud', - 'strokeSuccessSoft', - 'strokeSuccessSubtle', - 'strokeSuccessOnloud', - 'foregroundNeutralPrimary', - 'foregroundNeutralSecondary', - 'foregroundNeutralTertiary', - 'foregroundNeutralOnloud', - 'foregroundBrandPrimary', - 'foregroundBrandOnloud', - 'foregroundDangerPrimary', - 'foregroundDangerOnloud', - 'foregroundWarningPrimary', - 'foregroundWarningOnloud', - 'foregroundSuccessPrimary', - 'foregroundSuccessOnloud', -] as const satisfies readonly InteractiveColorToken[]; - -/** Default interaction lightness and alpha shifts for each state and mode. */ export const INTERACTION_COLOR_DELTAS = { hover: { light: { lightness: -0.03, alpha: 0.04 }, @@ -97,28 +21,26 @@ export const INTERACTION_COLOR_DELTAS = { }, } as const; -/** Reference surfaces used to solve translucent Bebop Warm source colors. */ -export const BEBOP_WARM_REFERENCE_BACKDROP = { - light: '#ffffff', - dark: '#292929', -} as const; - /** - * Return whether a semantic interaction token shifts opposite the standard - * lightness direction. + * Reference surfaces, as 8-bit sRGB channels, that the warm transform uses to + * solve translucent colors: `#ffffff` in light mode and `#292929` in dark mode. */ -export function isInverseInteractionToken(token: InteractiveColorToken): boolean { - return /heavy|loud|onloud/i.test(token); -} +export const WARM_REFERENCE_BACKDROP = { + light: [255, 255, 255], + dark: [41, 41, 41], +} as const; function interactionCurveMultiplier(lightness: number): number { return clamp((0.5 - lightness) / 0.1, 1, 3); } -function defaultInteractionColor(color: RgbaColor, token: InteractiveColorToken, mode: ColorMode, state: InteractionColorState): string { +function isTranslucent(alpha: number): boolean { + return alpha > 1e-9 && alpha < 1 - 1e-9; +} + +function coolInteractionColor(color: RgbaColor, mode: ColorMode, state: InteractionColorState, inverse: boolean): string { const oklch = rgbToOklch(color); const delta = INTERACTION_COLOR_DELTAS[state][mode]; - const inverse = isInverseInteractionToken(token); const rgb = oklchToRgb({ ...oklch, L: clamp(oklch.L + (inverse ? -1 : 1) * delta.lightness * interactionCurveMultiplier(oklch.L)), @@ -169,23 +91,24 @@ function warmInteractionRgb(color: RgbColor, alpha: number, mode: ColorMode, sta return oklchToRgb({ L: clamp(nextLightness), C: C + chromaDelta, h }); } -function isTranslucentSurfaceToken(token: InteractiveColorToken, alpha: number): boolean { - return (token.startsWith('background') || token.startsWith('stroke')) && alpha > 1e-9 && alpha < 1 - 1e-9; -} - -function bebopWarmInteractionColor(color: RgbaColor, token: InteractiveColorToken, mode: ColorMode, state: InteractionColorState): string { - const inverse = isInverseInteractionToken(token); +function warmInteractionColor( + color: RgbaColor, + mode: ColorMode, + state: InteractionColorState, + inverse: boolean, + backdrop: boolean, +): string { const alpha = inverse ? color.a : clamp(color.a + INTERACTION_COLOR_DELTAS[state][mode].alpha); - if (isTranslucentSurfaceToken(token, color.a)) { + if (backdrop && isTranslucent(color.a)) { const source = [channelToByte(color.r), channelToByte(color.g), channelToByte(color.b)]; - const backdrop = mode === 'light' ? [255, 255, 255] : [41, 41, 41]; + const reference = WARM_REFERENCE_BACKDROP[mode]; const sourceAlpha = channelToByte(color.a); const targetAlpha = channelToByte(alpha); - const apparent = source.map((channel, index) => compositeChannel(channel, backdrop[index], sourceAlpha)); + const apparent = source.map((channel, index) => compositeChannel(channel, reference[index], sourceAlpha)); const shifted = warmInteractionRgb({ r: apparent[0] / 255, g: apparent[1] / 255, b: apparent[2] / 255 }, color.a, mode, state, inverse); const target = [channelToByte(shifted.r), channelToByte(shifted.g), channelToByte(shifted.b)]; - const solved = target.map((channel, index) => solveSourceChannel(channel, backdrop[index], targetAlpha)); + const solved = target.map((channel, index) => solveSourceChannel(channel, reference[index], targetAlpha)); return rgbaToHex({ r: solved[0] / 255, g: solved[1] / 255, b: solved[2] / 255, a: targetAlpha / 255 }); } @@ -196,12 +119,12 @@ function bebopWarmInteractionColor(color: RgbaColor, token: InteractiveColorToke } /** - * Generate one interaction-state color with either the default or Bebop Warm - * OKLCH algorithm. + * Generate one interaction-state color from a rest color with the cool or + * warm OKLCH algorithm. Colors JavaScript cannot resolve return a structured + * diagnostic instead of a fabricated value. */ export function getInteractionColor( colorValue: ColorValue, - token: InteractiveColorToken, mode: ColorMode, state: InteractionColorState, options: InteractionColorOptions = {}, @@ -213,98 +136,27 @@ export function getInteractionColor( value: colorValue, diagnostic: { ...parsed.diagnostic, - token, state, }, }; } + const inverse = options.direction === 'inverted'; return { status: 'derived', value: - options.variant === 'bebopWarm' - ? bebopWarmInteractionColor(parsed.color, token, mode, state) - : defaultInteractionColor(parsed.color, token, mode, state), + options.colorTone === 'warm' + ? warmInteractionColor(parsed.color, mode, state, inverse, options.compositing === 'backdrop') + : coolInteractionColor(parsed.color, mode, state, inverse), }; } -/** Generate a hover color from a semantic token's rest value. */ -export function getHoverColor( - colorValue: ColorValue, - token: InteractiveColorToken, - mode: ColorMode, - options?: InteractionColorOptions, -): InteractionColorResult { - return getInteractionColor(colorValue, token, mode, 'hover', options); -} - -/** Generate a pressed color from a semantic token's rest value. */ -export function getPressColor( - colorValue: ColorValue, - token: InteractiveColorToken, - mode: ColorMode, - options?: InteractionColorOptions, -): InteractionColorResult { - return getInteractionColor(colorValue, token, mode, 'pressed', options); -} - -/** - * Generate every interactive token override for one state and collect - * diagnostics for colors that JavaScript cannot resolve. - */ -export function getInteractionColorOverrides( - colors: SemanticColorTokenValues, - mode: ColorMode, - state: InteractionColorState, - options?: InteractionColorOptions, -): InteractionColorOverridesResult { - const overrides: InteractiveColorOverrides = {}; - const diagnostics: InteractionColorDiagnostic[] = []; - - for (const token of INTERACTIVE_COLOR_TOKENS) { - const result = getInteractionColor(colors[token], token, mode, state, options); - if (result.status === 'derived') { - overrides[token] = result.value; - } else { - diagnostics.push(result.diagnostic); - } - } - - return { overrides, diagnostics }; +/** Generate a hover color from a rest color. */ +export function getHoverColor(colorValue: ColorValue, mode: ColorMode, options?: InteractionColorOptions): InteractionColorResult { + return getInteractionColor(colorValue, mode, 'hover', options); } -/** - * Fill missing hover and pressed colors without replacing authored values. - * Callers should not apply this fallback to high-contrast themes. - */ -export function getInteractionColors( - colors: InteractionColorInput, - mode: ColorMode, - options?: InteractionColorOptions, -): InteractionColorsResult { - const hover: InteractiveColorOverrides = { ...colors.hover }; - const pressed: InteractiveColorOverrides = { ...colors.pressed }; - const diagnostics: InteractionColorDiagnostic[] = []; - let changed = colors.hover === undefined || colors.pressed === undefined; - - for (const state of ['hover', 'pressed'] as const) { - const overrides = state === 'hover' ? hover : pressed; - for (const token of INTERACTIVE_COLOR_TOKENS) { - if (overrides[token] !== undefined) { - continue; - } - const result = getInteractionColor(colors[token], token, mode, state, options); - if (result.status === 'derived') { - overrides[token] = result.value; - changed = true; - } else { - diagnostics.push(result.diagnostic); - } - } - } - - return { - colors: changed ? { ...colors, hover, pressed } : (colors as SemanticColors), - diagnostics, - }; +/** Generate a pressed color from a rest color. */ +export function getPressColor(colorValue: ColorValue, mode: ColorMode, options?: InteractionColorOptions): InteractionColorResult { + return getInteractionColor(colorValue, mode, 'pressed', options); } diff --git a/packages/agentic/design/src/color-lib/types.ts b/packages/agentic/design/src/color-lib/types.ts index 74845db0be6..b275ee93909 100644 --- a/packages/agentic/design/src/color-lib/types.ts +++ b/packages/agentic/design/src/color-lib/types.ts @@ -1,7 +1,6 @@ import type { ColorValue } from 'react-native'; -import type { ThemeColorScheme } from '../theming/appearance.types'; -import type { InteractiveColorOverrides, SemanticColors, SemanticColorTokenValues } from '../tokens/flex.types'; +import type { ColorTone, ThemeColorScheme } from '../types/appearance.types'; export type ColorDiagnosticReason = 'non-literal-color' | 'unsupported-color-format'; @@ -47,15 +46,31 @@ export interface ResolvedContrastColors { } export type InteractionColorState = 'hover' | 'pressed'; -export type InteractionColorVariant = 'default' | 'bebopWarm'; -export type InteractiveColorToken = keyof InteractiveColorOverrides; + +/** + * Lightness direction. Inverted colors shift opposite the standard direction + * for the scheme and keep their alpha. + */ +export type InteractionDirection = 'standard' | 'inverted'; + +/** + * How the warm transform treats a translucent color. `backdrop` composites it + * over the scheme's reference backdrop, shifts the apparent color, and solves + * a source color at the target alpha. `direct` shifts the channels in place. + * The cool transform always shifts directly. + */ +export type InteractionCompositing = 'direct' | 'backdrop'; export interface InteractionColorOptions { - readonly variant?: InteractionColorVariant; + /** Interaction algorithm tone. Defaults to cool. */ + readonly colorTone?: ColorTone; + /** Defaults to standard. */ + readonly direction?: InteractionDirection; + /** Defaults to direct. */ + readonly compositing?: InteractionCompositing; } export interface InteractionColorDiagnostic extends ColorDiagnostic { - readonly token: InteractiveColorToken; readonly state: InteractionColorState; } @@ -70,19 +85,4 @@ export type InteractionColorResult = readonly diagnostic: InteractionColorDiagnostic; }; -export interface InteractionColorOverridesResult { - readonly overrides: InteractiveColorOverrides; - readonly diagnostics: readonly InteractionColorDiagnostic[]; -} - -export type InteractionColorInput = SemanticColorTokenValues & { - readonly hover?: InteractiveColorOverrides; - readonly pressed?: InteractiveColorOverrides; -}; - -export interface InteractionColorsResult { - readonly colors: SemanticColors; - readonly diagnostics: readonly InteractionColorDiagnostic[]; -} - export type ColorMode = ThemeColorScheme; diff --git a/packages/agentic/design/src/theming/__tests__/__snapshots__/theming-utils.test.ts.snap b/packages/agentic/design/src/deprecated/__tests__/__snapshots__/mapPipeline.test.ts.snap similarity index 100% rename from packages/agentic/design/src/theming/__tests__/__snapshots__/theming-utils.test.ts.snap rename to packages/agentic/design/src/deprecated/__tests__/__snapshots__/mapPipeline.test.ts.snap diff --git a/packages/agentic/design/src/theming/__tests__/theming-utils.test.ts b/packages/agentic/design/src/deprecated/__tests__/mapPipeline.test.ts similarity index 73% rename from packages/agentic/design/src/theming/__tests__/theming-utils.test.ts rename to packages/agentic/design/src/deprecated/__tests__/mapPipeline.test.ts index ef4cb3989ac..510fde43f29 100644 --- a/packages/agentic/design/src/theming/__tests__/theming-utils.test.ts +++ b/packages/agentic/design/src/deprecated/__tests__/mapPipeline.test.ts @@ -7,40 +7,9 @@ import darkShadowTokens from '@fluentui-react-native/design-tokens-windows/dark/ import lightAliasTokens from '@fluentui-react-native/design-tokens-windows/light/tokens-aliases.json'; import lightShadowTokens from '@fluentui-react-native/design-tokens-windows/light/tokens-shadow.json'; -import { getCurrentAppearance } from '../'; import { mapPipelineToShadow } from '../mapPipelineToShadow'; import { mapPipelineToTheme, mapFontPipelineToTheme } from '../mapPipelineToTheme'; -const fallBackAppearance = 'light'; - -beforeAll(() => { - jest.mock('react-native/Libraries/Utilities/Appearance', () => ({ - getColorScheme: () => 'dark', - })); -}); - -describe('getCurrentAppearanceTable test', () => { - it('light', () => { - expect(getCurrentAppearance('light', fallBackAppearance)).toBe('light'); - }); - - it('dark', () => { - expect(getCurrentAppearance('dark', fallBackAppearance)).toBe('dark'); - }); - - it('highContrast', () => { - expect(getCurrentAppearance('highContrast', fallBackAppearance)).toBe('highContrast'); - }); - - it('dynamic', () => { - expect(getCurrentAppearance('dynamic', fallBackAppearance)).toBe('dark'); - }); - - it('undefined', () => { - expect(getCurrentAppearance(undefined, fallBackAppearance)).toBe(fallBackAppearance); - }); -}); - describe('mapPipelineToTheme test', () => { it('lightAliasTokens', () => { const aliasColorTokens = mapPipelineToTheme(lightAliasTokens); diff --git a/packages/agentic/design/src/deprecated/index.ts b/packages/agentic/design/src/deprecated/index.ts new file mode 100644 index 00000000000..84879e05e5d --- /dev/null +++ b/packages/agentic/design/src/deprecated/index.ts @@ -0,0 +1,5 @@ +export { getAliasTokens, getShadowTokens } from './tokens/getTokens'; +export { default as globalTokens } from './tokens/tokens-global'; +export { hcAliasTokens } from './tokens/highContrast/tokens-alias'; +export { mapFontPipelineToTheme, mapPipelineToTheme } from './mapPipelineToTheme'; +export { mapPipelineToShadow } from './mapPipelineToShadow'; diff --git a/packages/agentic/design/src/theming/mapPipelineToShadow.ts b/packages/agentic/design/src/deprecated/mapPipelineToShadow.ts similarity index 95% rename from packages/agentic/design/src/theming/mapPipelineToShadow.ts rename to packages/agentic/design/src/deprecated/mapPipelineToShadow.ts index fcde469cfa6..efa5220085f 100644 --- a/packages/agentic/design/src/theming/mapPipelineToShadow.ts +++ b/packages/agentic/design/src/deprecated/mapPipelineToShadow.ts @@ -1,4 +1,4 @@ -import type { ThemeShadowDefinition } from './types/Shadow.types'; +import type { ThemeShadowDefinition } from '../fluent/types/Shadow.types'; /** * Given design token pipeline output for shadow tokens, creates an object that can be used in Theme object. diff --git a/packages/agentic/design/src/theming/mapPipelineToTheme.android.ts b/packages/agentic/design/src/deprecated/mapPipelineToTheme.android.ts similarity index 98% rename from packages/agentic/design/src/theming/mapPipelineToTheme.android.ts rename to packages/agentic/design/src/deprecated/mapPipelineToTheme.android.ts index 1fc2744f005..38082d5900d 100644 --- a/packages/agentic/design/src/theming/mapPipelineToTheme.android.ts +++ b/packages/agentic/design/src/deprecated/mapPipelineToTheme.android.ts @@ -1,5 +1,5 @@ -import type { AliasColorTokens } from './types/Color.types'; -import type { Variants, VariantValue } from './types/Typography.types'; +import type { AliasColorTokens } from '../fluent/types/Color.types'; +import type { Variants, VariantValue } from '../fluent/types/Typography.types'; // API that maps tokens coming from the android token pipeline to Theme color values. export function mapPipelineToTheme(pipelineOutput: any): AliasColorTokens { diff --git a/packages/agentic/design/src/theming/mapPipelineToTheme.ios.ts b/packages/agentic/design/src/deprecated/mapPipelineToTheme.ios.ts similarity index 97% rename from packages/agentic/design/src/theming/mapPipelineToTheme.ios.ts rename to packages/agentic/design/src/deprecated/mapPipelineToTheme.ios.ts index 960624f783b..e4e9cc19c7f 100644 --- a/packages/agentic/design/src/theming/mapPipelineToTheme.ios.ts +++ b/packages/agentic/design/src/deprecated/mapPipelineToTheme.ios.ts @@ -1,6 +1,6 @@ -import type { FontStyleTokens } from '../styling/tokens'; -import type { AliasColorTokens } from './types/Color.types'; -import type { FontDynamicTypeRamp, Variants, VariantValue } from './types/Typography.types'; +import type { FontStyleTokens } from '../fluent/styling/tokens'; +import type { AliasColorTokens } from '../fluent/types/Color.types'; +import type { FontDynamicTypeRamp, Variants, VariantValue } from '../fluent/types/Typography.types'; // API that maps tokens coming from the iOS token pipeline to Theme color values. export function mapPipelineToTheme(pipelineOutput: any): AliasColorTokens { diff --git a/packages/agentic/design/src/theming/mapPipelineToTheme.ts b/packages/agentic/design/src/deprecated/mapPipelineToTheme.ts similarity index 98% rename from packages/agentic/design/src/theming/mapPipelineToTheme.ts rename to packages/agentic/design/src/deprecated/mapPipelineToTheme.ts index 2d948624d63..c6a5d1c70c2 100644 --- a/packages/agentic/design/src/theming/mapPipelineToTheme.ts +++ b/packages/agentic/design/src/deprecated/mapPipelineToTheme.ts @@ -1,5 +1,5 @@ -import type { AliasColorTokens } from './types/Color.types'; -import type { Variants } from './types/Typography.types'; +import type { AliasColorTokens } from '../fluent/types/Color.types'; +import type { Variants } from '../fluent/types/Typography.types'; export function mapPipelineToTheme(pipelineOutput: any): AliasColorTokens { return { diff --git a/packages/agentic/design/src/tokens/legacy/getTokens.android.ts b/packages/agentic/design/src/deprecated/tokens/getTokens.android.ts similarity index 94% rename from packages/agentic/design/src/tokens/legacy/getTokens.android.ts rename to packages/agentic/design/src/deprecated/tokens/getTokens.android.ts index cc8275e33b4..b81860e14fc 100644 --- a/packages/agentic/design/src/tokens/legacy/getTokens.android.ts +++ b/packages/agentic/design/src/deprecated/tokens/getTokens.android.ts @@ -2,7 +2,7 @@ import darkAliasTokens from '@fluentui-react-native/design-tokens-android/dark/t import darkShadowTokens from '@fluentui-react-native/design-tokens-android/dark/tokens-shadow.json'; import lightAliasTokens from '@fluentui-react-native/design-tokens-android/light/tokens-aliases.json'; import lightShadowTokens from '@fluentui-react-native/design-tokens-android/light/tokens-shadow.json'; -import type { AppearanceOptions } from '../../theming'; +import type { AppearanceOptions } from '../../fluent/types/Theme.types'; export function getAliasTokens(mode: AppearanceOptions) { if (mode === 'light') { diff --git a/packages/agentic/design/src/tokens/legacy/getTokens.ios.ts b/packages/agentic/design/src/deprecated/tokens/getTokens.ios.ts similarity index 95% rename from packages/agentic/design/src/tokens/legacy/getTokens.ios.ts rename to packages/agentic/design/src/deprecated/tokens/getTokens.ios.ts index 1103fd1a050..328eefa3021 100644 --- a/packages/agentic/design/src/tokens/legacy/getTokens.ios.ts +++ b/packages/agentic/design/src/deprecated/tokens/getTokens.ios.ts @@ -3,7 +3,7 @@ import iOSDarkShadowTokens from '@fluentui-react-native/design-tokens-ios/dark/t import iOSDarkElevatedAliasTokens from '@fluentui-react-native/design-tokens-ios/elevateddark/tokens-aliases.json'; import iOSLightAliasTokens from '@fluentui-react-native/design-tokens-ios/light/tokens-aliases.json'; import iOSLightShadowTokens from '@fluentui-react-native/design-tokens-ios/light/tokens-shadow.json'; -import type { AppearanceOptions } from '../../theming'; +import type { AppearanceOptions } from '../../fluent/types/Theme.types'; import { assertNever } from 'assert-never'; export function getAliasTokens(mode: AppearanceOptions) { diff --git a/packages/agentic/design/src/tokens/legacy/getTokens.ts b/packages/agentic/design/src/deprecated/tokens/getTokens.ts similarity index 94% rename from packages/agentic/design/src/tokens/legacy/getTokens.ts rename to packages/agentic/design/src/deprecated/tokens/getTokens.ts index 86cf9063edb..b3ced7533d6 100644 --- a/packages/agentic/design/src/tokens/legacy/getTokens.ts +++ b/packages/agentic/design/src/deprecated/tokens/getTokens.ts @@ -3,7 +3,7 @@ import darkAliasTokens from '@fluentui-react-native/design-tokens-windows/dark/t import darkShadowTokens from '@fluentui-react-native/design-tokens-windows/dark/tokens-shadow.json'; import lightAliasTokens from '@fluentui-react-native/design-tokens-windows/light/tokens-aliases.json'; import lightShadowTokens from '@fluentui-react-native/design-tokens-windows/light/tokens-shadow.json'; -import type { AppearanceOptions } from '../../theming'; +import type { AppearanceOptions } from '../../fluent/types/Theme.types'; import { assertNever } from 'assert-never'; import { hcAliasTokens } from './highContrast/tokens-alias'; diff --git a/packages/agentic/design/src/tokens/legacy/highContrast/__tests__/processAliasTokens.test.ts b/packages/agentic/design/src/deprecated/tokens/highContrast/__tests__/processAliasTokens.test.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/highContrast/__tests__/processAliasTokens.test.ts rename to packages/agentic/design/src/deprecated/tokens/highContrast/__tests__/processAliasTokens.test.ts diff --git a/packages/agentic/design/src/tokens/legacy/highContrast/processAliasTokens.ts b/packages/agentic/design/src/deprecated/tokens/highContrast/processAliasTokens.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/highContrast/processAliasTokens.ts rename to packages/agentic/design/src/deprecated/tokens/highContrast/processAliasTokens.ts diff --git a/packages/agentic/design/src/tokens/legacy/highContrast/tokens-alias.ts b/packages/agentic/design/src/deprecated/tokens/highContrast/tokens-alias.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/highContrast/tokens-alias.ts rename to packages/agentic/design/src/deprecated/tokens/highContrast/tokens-alias.ts diff --git a/packages/agentic/design/src/tokens/legacy/highContrast/tokens-alias.win32.ts b/packages/agentic/design/src/deprecated/tokens/highContrast/tokens-alias.win32.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/highContrast/tokens-alias.win32.ts rename to packages/agentic/design/src/deprecated/tokens/highContrast/tokens-alias.win32.ts diff --git a/packages/agentic/design/src/tokens/legacy/tokens-global.android.ts b/packages/agentic/design/src/deprecated/tokens/tokens-global.android.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/tokens-global.android.ts rename to packages/agentic/design/src/deprecated/tokens/tokens-global.android.ts diff --git a/packages/agentic/design/src/tokens/legacy/tokens-global.ios.ts b/packages/agentic/design/src/deprecated/tokens/tokens-global.ios.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/tokens-global.ios.ts rename to packages/agentic/design/src/deprecated/tokens/tokens-global.ios.ts diff --git a/packages/agentic/design/src/tokens/legacy/tokens-global.ts b/packages/agentic/design/src/deprecated/tokens/tokens-global.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/tokens-global.ts rename to packages/agentic/design/src/deprecated/tokens/tokens-global.ts diff --git a/packages/agentic/design/src/tokens/legacy/tokens-global.win32.ts b/packages/agentic/design/src/deprecated/tokens/tokens-global.win32.ts similarity index 100% rename from packages/agentic/design/src/tokens/legacy/tokens-global.win32.ts rename to packages/agentic/design/src/deprecated/tokens/tokens-global.win32.ts diff --git a/packages/agentic/design/src/flex/adapters/flexTokensFromTheme.test.ts b/packages/agentic/design/src/flex/adapters/flexTokensFromTheme.test.ts new file mode 100644 index 00000000000..cbb1a1f4b49 --- /dev/null +++ b/packages/agentic/design/src/flex/adapters/flexTokensFromTheme.test.ts @@ -0,0 +1,92 @@ +import * as interaction from '../../color-lib/interaction'; +import type { Theme } from '../../theming'; +import { mockTheme } from '../../test/fixtures/mockTheme'; +import { defaultFlexTokens } from '../defaults/defaultTokens'; +import { fluentFallbackFlexTokens } from './fluentFallbackTokens'; +import { flexTokensFromTheme } from './flexTokensFromTheme'; + +function createTheme(): Theme { + return { + ...mockTheme, + colors: { + ...mockTheme.colors, + brandBackground2: '#112233', + neutralBackground2: '#223344', + neutralBackground2Hover: '#334455', + neutralBackground2Pressed: '#445566', + }, + components: { + Button: { + tokens: { + borderRadius: 10, + }, + }, + }, + }; +} + +describe('flexTokensFromTheme', () => { + it('merges mapped Theme values over non-Fluent defaults', () => { + const theme = createTheme(); + const tokens = flexTokensFromTheme(theme); + + expect(tokens.color.backgroundNeutralSubtle).toEqual({ rest: '#223344', hover: '#334455', pressed: '#445566' }); + expect(tokens.color.backgroundBrandSoft).toEqual({ rest: '#112233', hover: '#112233', pressed: '#112233' }); + expect(tokens.color.backgroundNeutralSoft).toEqual({ rest: '#0000001a', hover: '#0000001a', pressed: '#0000001a' }); + expect(tokens.color.expressionAccentHeavy).toEqual({ rest: '#242424', hover: '#242424', pressed: '#242424' }); + expect(tokens.borderRadius.base100).toBe(2); + expect(tokens.borderRadius.base200).toBe(10); + expect(tokens.borderRadius.base300).toBe(10); + expect(tokens.borderRadius.base400).toBe(6); + expect(tokens.fontWeight.functionalMedium).toBe(theme.typography.weights.semiBold); + }); + + it('uses native defaults when an optional mapped Theme path is absent', () => { + const tokens = flexTokensFromTheme({ ...createTheme(), components: {} }); + + expect(tokens.borderRadius.base200).toBe(4); + expect(tokens.borderRadius.base300).toBe(4); + expect(tokens.color.backgroundBrandHeavy.rest).toBe('#185abd'); + }); + + it('converts legacy { ambient, key } Theme shadows to [ambient, key] layers', () => { + const tokens = flexTokensFromTheme(createTheme()); + + expect(tokens.shadow.lowest).toEqual([mockTheme.shadows.shadow2.ambient, mockTheme.shadows.shadow2.key]); + expect(tokens.shadow.highest).toEqual([mockTheme.shadows.shadow64.ambient, mockTheme.shadows.shadow64.key]); + }); + + it('keeps layered shadows and drops missing legacy layers', () => { + const layers = [mockTheme.shadows.shadow4.key, mockTheme.shadows.shadow8.key, mockTheme.shadows.shadow16.key]; + const shadows = { ...mockTheme.shadows, shadow4: layers, shadow8: { ambient: mockTheme.shadows.shadow8.ambient } }; + const tokens = flexTokensFromTheme({ ...createTheme(), shadows } as unknown as Theme); + + expect(tokens.shadow.lower).toBe(layers); + expect(tokens.shadow.low).toEqual([mockTheme.shadows.shadow8.ambient]); + }); + + it('uses the Fluent fallback shadow when the Theme omits one', () => { + const { shadow2: _omitted, ...shadows } = mockTheme.shadows; + const tokens = flexTokensFromTheme({ ...createTheme(), shadows } as Theme); + + expect(tokens.shadow.lowest).toEqual(fluentFallbackFlexTokens.shadow.lowest); + }); + + it('resolves every color and never runs the interaction engine', () => { + const spy = jest.spyOn(interaction, 'getInteractionColor'); + try { + const tokens = flexTokensFromTheme(createTheme(), { colorScheme: 'dark' }); + for (const color of Object.values(tokens.color)) { + void color.hover; + void color.pressed; + } + + expect(spy).not.toHaveBeenCalled(); + expect(Object.isFrozen(tokens)).toBe(true); + expect(Object.isFrozen(tokens.color)).toBe(true); + expect(Object.keys(tokens.color).sort()).toEqual(Object.keys(defaultFlexTokens.color).sort()); + } finally { + spy.mockRestore(); + } + }); +}); diff --git a/packages/agentic/design/src/flex/adapters/flexTokensFromTheme.ts b/packages/agentic/design/src/flex/adapters/flexTokensFromTheme.ts new file mode 100644 index 00000000000..54aff51fc2f --- /dev/null +++ b/packages/agentic/design/src/flex/adapters/flexTokensFromTheme.ts @@ -0,0 +1,70 @@ +import { immutableMerge } from '@fluentui-react-native/framework-base'; +import type { ColorValue } from 'react-native'; + +import type { ShadowToken } from '../../fluent/types/Shadow.types'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { defaultResolvedThemeAppearance } from '../../theming/appearance'; +import { mapObjectFromObject } from '../../utilities/objects'; +import { normalizeFlexColor, resolveExplicitFlexColor } from '../colors/flexColor'; +import type { ColorSchemeSelector } from '../colors/flexColor'; +import { createInteractiveColor } from '../colors/interactiveColor'; +import type { FlexColorInput, FlexShadow, FlexShadowLayer, FlexTokens, InteractiveColor, SemanticColors } from '../tokens.types'; +import { fluentFallbackFlexTokens, nonFluentFlexTokens } from './fluentFallbackTokens'; +import flexFromTheme from '../../tokens/mappings/flex-from-theme.json' with { type: 'json' }; + +type MappedColor = { rest: ColorValue; hover?: ColorValue; pressed?: ColorValue }; +type MappedFlexTokens = Omit<Partial<FlexTokens>, 'color'> & { color?: Record<string, MappedColor> }; + +const defaultMappedFlexTokens = mapObjectFromObject<MappedFlexTokens>( + fluentFallbackFlexTokens, + Object.fromEntries(Object.keys(flexFromTheme).map((destinationPath) => [destinationPath, destinationPath])), +); + +const { color: nonFluentColors, ...nonFluentGroups } = nonFluentFlexTokens; +const nonFluentColorDescriptions = Object.entries(nonFluentColors as Record<string, FlexColorInput>).map( + ([name, value]) => [name, normalizeFlexColor(value, 'standard', `color.${name}`)] as const, +); + +/** Convert a legacy Theme { ambient, key } shadow to [ambient, key] layers. */ +function shadowLayersFromTheme(shadow: Partial<ShadowToken> | FlexShadow): FlexShadow { + if (Array.isArray(shadow)) { + return shadow; + } + const { ambient, key } = shadow as Partial<ShadowToken>; + return [ambient, key].filter((layer): layer is FlexShadowLayer => layer !== undefined); +} + +function mapThemeTokens(theme: Theme): MappedFlexTokens { + const mapped = mapObjectFromObject<MappedFlexTokens>(theme, flexFromTheme); + if (mapped.shadow === undefined) { + return mapped; + } + const shadow: Record<string, FlexShadow> = {}; + for (const [name, value] of Object.entries(mapped.shadow)) { + shadow[name] = shadowLayersFromTheme(value); + } + return { ...mapped, shadow: shadow as MappedFlexTokens['shadow'] }; +} + +/** + * Build Flex tokens from the values exposed by a FURN Theme. Interaction + * states the Theme does not map equal rest; no interaction algorithm runs. + * Legacy { ambient, key } Theme shadows become [ambient, key] layers. + * The scheme selects light/dark tuples in values without a Theme source. + */ +export function flexTokensFromTheme(theme: Theme, appearance: ColorSchemeSelector = defaultResolvedThemeAppearance): FlexTokens { + const { color: mappedColors = {}, ...mappedGroups } = immutableMerge(defaultMappedFlexTokens, mapThemeTokens(theme)) as MappedFlexTokens; + + const color: Record<string, InteractiveColor> = {}; + for (const [name, description] of nonFluentColorDescriptions) { + color[name] = resolveExplicitFlexColor(description, appearance); + } + for (const [name, { rest, hover, pressed }] of Object.entries(mappedColors)) { + color[name] = createInteractiveColor(rest, hover ?? rest, pressed ?? rest); + } + + return Object.freeze({ + color: Object.freeze(color) as SemanticColors, + ...immutableMerge(nonFluentGroups as object, mappedGroups as object), + }) as FlexTokens; +} diff --git a/packages/agentic/design/src/flex/adapters/fluentFallbackTokens.test.ts b/packages/agentic/design/src/flex/adapters/fluentFallbackTokens.test.ts new file mode 100644 index 00000000000..9c6ecc64a0e --- /dev/null +++ b/packages/agentic/design/src/flex/adapters/fluentFallbackTokens.test.ts @@ -0,0 +1,73 @@ +import { INTERACTIVE_COLOR_TOKENS } from '../colors/interactiveTokens'; +import { fluentFallbackFlexTokens, nonFluentFlexTokens } from './fluentFallbackTokens'; + +const flexFromTheme = jest.requireActual<Record<string, string>>('../../tokens/mappings/flex-from-theme.json'); +const interactiveTokens = new Set<string>(INTERACTIVE_COLOR_TOKENS); + +function isColorOptions(value: unknown): value is Record<string, unknown> { + return typeof value === 'object' && value !== null && !Array.isArray(value) && 'rest' in value; +} + +function getGroupPaths(tokens: object): string[] { + return Object.entries(tokens) + .filter(([group]) => group !== 'color') + .flatMap(([group, values]) => Object.keys(values).map((name) => `${group}.${name}`)); +} + +// Authored color paths: rest always, and hover or pressed only when present. +function getAuthoredPaths(tokens: { color: object }): string[] { + const colorPaths = Object.entries(tokens.color).flatMap(([name, value]) => { + const states = isColorOptions(value) ? ['rest', 'hover', 'pressed'].filter((state) => value[state] !== undefined) : ['rest']; + return states.map((state) => `color.${name}.${state}`); + }); + return [...colorPaths, ...getGroupPaths(tokens)].sort(); +} + +// Every interactive fallback authors explicit states; other colors author rest only. +function getFallbackPaths(tokens: { color: object }): string[] { + const colorPaths = Object.keys(tokens.color).flatMap((name) => + (interactiveTokens.has(name) ? ['rest', 'hover', 'pressed'] : ['rest']).map((state) => `color.${name}.${state}`), + ); + return [...colorPaths, ...getGroupPaths(tokens)].sort(); +} + +describe('Fluent fallback Flex tokens', () => { + it('builds fallbacks from values without FURN Theme sources', () => { + const themeBackedPaths = new Set(Object.keys(flexFromTheme)); + const expectedNonFluentPaths = getFallbackPaths(fluentFallbackFlexTokens).filter((path) => { + if (themeBackedPaths.has(path)) { + return false; + } + + const interactiveColor = /^color\.([^.]+)\.(?:hover|pressed)$/.exec(path); + return !interactiveColor || !themeBackedPaths.has(`color.${interactiveColor[1]}.rest`); + }); + + expect(getAuthoredPaths(nonFluentFlexTokens)).toEqual(expectedNonFluentPaths); + expect(Object.keys(nonFluentFlexTokens)).toEqual(['color', 'lineHeight', 'borderRadius', 'spacing', 'strokeWidth', 'motion']); + expect(nonFluentFlexTokens.color.backgroundNeutralSoft).toEqual({ rest: '#0000001a', hover: '#0000001a', pressed: '#0000001a' }); + expect(nonFluentFlexTokens.borderRadius.base100).toBe(2); + expect('backgroundBrandHeavy' in nonFluentFlexTokens.color).toBe(false); + expect('backgroundBrandSoft' in nonFluentFlexTokens.color).toBe(false); + expect('surfaceNeutralFarther' in nonFluentFlexTokens.color).toBe(false); + expect('base200' in nonFluentFlexTokens.borderRadius).toBe(false); + expect(fluentFallbackFlexTokens.lineHeight).toBe(nonFluentFlexTokens.lineHeight); + expect(fluentFallbackFlexTokens.motion).toBe(nonFluentFlexTokens.motion); + expect(fluentFallbackFlexTokens.color.backgroundNeutralSoft.rest).toBe(nonFluentFlexTokens.color.backgroundNeutralSoft.rest); + }); + + it('keeps the Fluent-native fallback values', () => { + expect(fluentFallbackFlexTokens.color.surfaceNeutralFarther).toEqual({ rest: '#ebebeb', hover: '#f5f5f5', pressed: '#f0f0f0' }); + expect(fluentFallbackFlexTokens.color.backgroundBrandHeavy.rest).toBe('#185abd'); + expect(fluentFallbackFlexTokens.color.backgroundBrandSoft.hover).toBe('#d2e0f4'); + expect(fluentFallbackFlexTokens.spacing.componentBase800).toBe(32); + expect(fluentFallbackFlexTokens.shadow.lowest).toEqual([ + { x: 0, y: 0, blur: 2, color: '#0000001f' }, + { x: 0, y: 1, blur: 2, color: '#00000024' }, + ]); + expect(fluentFallbackFlexTokens.shadow.highest).toEqual([ + { x: 0, y: 0, blur: 8, color: '#00000033' }, + { x: 0, y: 32, blur: 64, color: '#0000003d' }, + ]); + }); +}); diff --git a/packages/agentic/design/src/flex/adapters/fluentFallbackTokens.ts b/packages/agentic/design/src/flex/adapters/fluentFallbackTokens.ts new file mode 100644 index 00000000000..4d7d3f27623 --- /dev/null +++ b/packages/agentic/design/src/flex/adapters/fluentFallbackTokens.ts @@ -0,0 +1,354 @@ +import { + cornerRadius120, + cornerRadius20, + cornerRadius40, + cornerRadius60, + cornerRadius80, + cornerRadiusCircular, + fontFamilyBase, + fontFamilyMonospace, + fontLineHeight100, + fontLineHeight200, + fontLineHeight300, + fontLineHeight400, + fontLineHeight500, + fontLineHeight600, + fontLineHeight800, + fontLineHeight900, + fontLineHeight1000, + fontSize100, + fontSize200, + fontSize300, + fontSize400, + fontSize500, + fontSize600, + fontSize700, + fontSize800, + fontSize900, + fontSize1000, + fontWeightBold, + fontWeightMedium, + fontWeightRegular, + fontWeightSemibold, + size20, + size40, + size60, + size80, + size100, + size120, + size160, + size200, + size240, + size280, + size320, + size360, + size400, + size480, + size560, + size640, + size800, + strokeWidth10, + strokeWidth20, + strokeWidth30, + strokeWidth40, +} from '../../tokens/global.generated'; +import { defaultResolvedThemeAppearance } from '../../theming/appearance'; +import { createFlexTokenDescription, resolveExplicitFlexTokenDescription } from '../flexTokenDescription'; +import type { FlexTokens, PartialFlexTokens } from '../tokens.types'; + +type NonFluentFlexTokens = Omit<PartialFlexTokens, 'shadow' | 'fontWeight' | 'fontFamily' | 'fontSize'>; + +/** + * Fallback values for Flex tokens that cannot be populated from a FURN Theme. + * The forward Theme adapter layers projected Theme values over these. They are + * Fluent-native values, not the x3 defaults. Fluent and Theme have no motion + * tokens, so motion uses the x3 values pinned at 206e890b. + */ +export const nonFluentFlexTokens = { + color: { + surfaceNeutralTranslucent: { rest: '#ffffff80', hover: '#ffffff80', pressed: '#ffffff80' }, + backgroundNeutralSoft: { rest: '#0000001a', hover: '#0000001a', pressed: '#0000001a' }, + backgroundNeutralTranslucent: { rest: '#ffffff80', hover: '#ffffff80', pressed: '#ffffff80' }, + expressionAccentHeavy: '#242424', + expressionAccentLoud: '#707070', + expressionAccentSoft: '#0000001a', + expressionAccentSubtle: '#0000000d', + expressionGrayHeavy: '#474747', + expressionGrayLoud: '#949494', + expressionGraySoft: '#e0e0e0', + expressionGraySubtle: '#f5f5f5', + expressionNavyHeavy: '#001e89', + expressionNavyLoud: '#546fd2', + expressionNavySoft: '#ccd5f3', + expressionNavySubtle: '#f2f4fc', + expressionBlueHeavy: '#004377', + expressionBlueLoud: '#3595de', + expressionBlueSoft: '#d0e7f8', + expressionBlueSubtle: '#f3f9fd', + expressionGreenHeavy: '#0c5e0c', + expressionGreenLoud: '#54b054', + expressionGreenSoft: '#c9eac9', + expressionGreenSubtle: '#f1faf1', + expressionLimeHeavy: '#405f14', + expressionLimeLoud: '#689920', + expressionLimeSoft: '#cfe5af', + expressionLimeSubtle: '#e5f1d3', + expressionYellowHeavy: '#4c4400', + expressionYellowLoud: '#fde300', + expressionYellowSoft: '#feee66', + expressionYellowSubtle: '#fef7b2', + expressionPumpkinHeavy: '#712d09', + expressionPumpkinLoud: '#df8e64', + expressionPumpkinSoft: '#f7dfd2', + expressionPumpkinSubtle: '#fdf7f4', + expressionRedHeavy: '#751d1f', + expressionRedLoud: '#dc5e62', + expressionRedSoft: '#f8dadb', + expressionRedSubtle: '#fdf6f6', + expressionPinkHeavy: '#80215d', + expressionPinkLoud: '#e750b0', + expressionPinkSoft: '#f7c0e3', + expressionPinkSubtle: '#fef6fb', + expressionPurpleHeavy: '#532982', + expressionPurpleLoud: '#9470bd', + expressionPurpleSoft: '#e0d3ed', + expressionPurpleSubtle: '#f7f4fb', + overlayNeutralTranslucent: '#ffffff80', + materialBackgroundThick: '#ffffffe6', + materialBackgroundRegular: '#ffffffcc', + materialBackgroundThin: '#ffffff80', + }, + lineHeight: { + functionalDisplay: fontLineHeight1000, + functionalPagetitle: fontLineHeight900, + functionalTitleLarge: fontLineHeight800, + functionalTitleMedium: fontLineHeight600, + functionalTitleSmall: fontLineHeight500, + functionalSubtitle: fontLineHeight500, + functionalBodyLarge: fontLineHeight400, + functionalBodyMedium: fontLineHeight300, + functionalBodySmall: fontLineHeight200, + functionalCaption: fontLineHeight100, + contentStatement: fontLineHeight900, + contentExpressiveLarge: fontLineHeight900, + contentExpressiveMedium: fontLineHeight800, + contentExpressiveSmall: fontLineHeight600, + contentH1: fontLineHeight800, + contentH2: fontLineHeight800, + contentH3: fontLineHeight600, + contentH4: fontLineHeight500, + contentH5: fontLineHeight400, + contentSubheadline: fontLineHeight400, + contentParagraphLarge: fontLineHeight600, + contentParagraphMedium: fontLineHeight500, + contentParagraphSmall: fontLineHeight300, + contentSubtext: fontLineHeight100, + contentTable: fontLineHeight400, + contentCode: fontLineHeight400, + }, + borderRadius: { + base100: cornerRadius20, + base400: cornerRadius60, + base600: cornerRadius80, + base700: cornerRadius120, + circular: cornerRadiusCircular, + }, + spacing: { + componentBase50: size20, + componentBase100: size40, + componentBase150: size60, + componentBase200: size80, + componentBase250: size100, + componentBase300: size120, + componentBase400: size160, + componentBase500: size200, + componentBase600: size240, + componentBase700: size280, + componentBase800: size320, + layoutBase100: size80, + layoutBase200: size160, + layoutBase300: size240, + layoutBase400: size320, + layoutBase450: size360, + layoutBase500: size400, + layoutBase600: size480, + layoutBase700: size560, + layoutBase800: size640, + layoutBase1000: size800, + layoutBase1200: size800, + }, + strokeWidth: { + thin: strokeWidth10, + thick: strokeWidth20, + thicker: strokeWidth30, + thickest: strokeWidth40, + }, + motion: { + durationBase50: 50, + durationBase100: 100, + durationBase200: 200, + durationBase300: 300, + durationBase500: 500, + durationBase1000: 1000, + easingFunctionalEnter: [0, 0, 0, 1], + easingFunctionalExit: [0.6, 0, 0.75, 0.4], + easingFunctionalTransition: [0.33, 0, 0, 1], + easingFunctionalLinear: [0, 0, 1, 1], + easingExpressiveEnter: [0, 0, 0, 1], + easingExpressiveExit: [0.6, 0, 0.75, 0.4], + easingExpressiveTransition: [0.33, 0, 0, 1], + }, +} satisfies NonFluentFlexTokens; + +const ambient = { x: 0, y: 0, blur: 2, color: '#0000001f' }; +const ambientHigh = { x: 0, y: 0, blur: 8, color: '#00000033' }; + +/** + * Fluent-native fallback token values for the default appearance, layered + * under values that have no FURN Theme source. The forward Theme adapter uses + * them when a Theme omits a mapped value. Every interactive fallback authors + * explicit states, so no interaction algorithm runs. + */ +const fluentFallbackFlexTokenDescription = createFlexTokenDescription({ + ...nonFluentFlexTokens, + color: { + ...nonFluentFlexTokens.color, + surfaceNeutralFarther: { rest: '#ebebeb', hover: '#f5f5f5', pressed: '#f0f0f0' }, + surfaceNeutralFar: { rest: '#f5f5f5', hover: '#ebebeb', pressed: '#d6d6d6' }, + surfaceNeutralNear: { rest: '#fafafa', hover: '#f0f0f0', pressed: '#dbdbdb' }, + surfaceNeutralNearer: { rest: '#ffffff', hover: '#f5f5f5', pressed: '#e0e0e0' }, + backgroundNeutralHeavy: { rest: '#616161', hover: '#616161', pressed: '#616161', type: 'inverted' }, + backgroundNeutralLoud: { rest: '#616161', hover: '#616161', pressed: '#616161', type: 'inverted' }, + backgroundNeutralSubtle: { rest: '#fafafa', hover: '#f0f0f0', pressed: '#dbdbdb' }, + backgroundNeutralTransparent: { rest: '#00000000', hover: '#00000000', pressed: '#00000000' }, + backgroundBrandHeavy: { rest: '#185abd', hover: '#1651aa', pressed: '#0e336a', type: 'inverted' }, + backgroundBrandLoud: { rest: '#185abd', hover: '#1651aa', pressed: '#0e336a', type: 'inverted' }, + backgroundBrandSoft: { rest: '#d2e0f4', hover: '#d2e0f4', pressed: '#d2e0f4' }, + backgroundBrandSubtle: { rest: '#d2e0f4', hover: '#d2e0f4', pressed: '#d2e0f4' }, + backgroundBrandTransparent: { rest: '#00000000', hover: '#00000000', pressed: '#00000000' }, + backgroundDangerLoud: { rest: '#d13438', hover: '#d13438', pressed: '#d13438', type: 'inverted' }, + backgroundDangerSoft: { rest: '#f1bbbc', hover: '#f1bbbc', pressed: '#f1bbbc' }, + backgroundDangerSubtle: { rest: '#fdf6f6', hover: '#fdf6f6', pressed: '#fdf6f6' }, + backgroundWarningLoud: { rest: '#fde300', hover: '#fde300', pressed: '#fde300', type: 'inverted' }, + backgroundWarningSoft: { rest: '#fef7b2', hover: '#fef7b2', pressed: '#fef7b2' }, + backgroundWarningSubtle: { rest: '#fffef5', hover: '#fffef5', pressed: '#fffef5' }, + backgroundSuccessLoud: { rest: '#107c10', hover: '#107c10', pressed: '#107c10', type: 'inverted' }, + backgroundSuccessSoft: { rest: '#9fd89f', hover: '#9fd89f', pressed: '#9fd89f' }, + backgroundSuccessSubtle: { rest: '#f1faf1', hover: '#f1faf1', pressed: '#f1faf1' }, + strokeNeutralHeavy: { rest: '#616161', hover: '#575757', pressed: '#4d4d4d', type: 'inverted' }, + strokeNeutralLoud: { rest: '#d1d1d1', hover: '#c7c7c7', pressed: '#b3b3b3', type: 'inverted' }, + strokeNeutralSoft: { rest: '#d1d1d1', hover: '#c7c7c7', pressed: '#b3b3b3' }, + strokeNeutralSubtle: { rest: '#e0e0e0', hover: '#e0e0e0', pressed: '#e0e0e0' }, + strokeNeutralTransparent: { rest: '#00000000', hover: '#00000000', pressed: '#00000000' }, + strokeNeutralOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + strokeBrandLoud: { rest: '#185abd', hover: '#185abd', pressed: '#185abd', type: 'inverted' }, + strokeBrandSoft: { rest: '#185abd', hover: '#185abd', pressed: '#185abd' }, + strokeBrandSubtle: { rest: '#6794d7', hover: '#6794d7', pressed: '#6794d7' }, + strokeBrandOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + strokeDangerLoud: { rest: '#d13438', hover: '#d13438', pressed: '#d13438', type: 'inverted' }, + strokeDangerSoft: { rest: '#f1bbbc', hover: '#f1bbbc', pressed: '#f1bbbc' }, + strokeDangerSubtle: { rest: '#f1bbbc', hover: '#f1bbbc', pressed: '#f1bbbc' }, + strokeDangerOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + strokeWarningLoud: { rest: '#fde300', hover: '#fde300', pressed: '#fde300', type: 'inverted' }, + strokeWarningSoft: { rest: '#fef7b2', hover: '#fef7b2', pressed: '#fef7b2' }, + strokeWarningSubtle: { rest: '#fef7b2', hover: '#fef7b2', pressed: '#fef7b2' }, + strokeWarningOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + strokeSuccessLoud: { rest: '#107c10', hover: '#107c10', pressed: '#107c10', type: 'inverted' }, + strokeSuccessSoft: { rest: '#9fd89f', hover: '#9fd89f', pressed: '#9fd89f' }, + strokeSuccessSubtle: { rest: '#9fd89f', hover: '#9fd89f', pressed: '#9fd89f' }, + strokeSuccessOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + foregroundNeutralPrimary: { rest: '#242424', hover: '#242424', pressed: '#242424' }, + foregroundNeutralSecondary: { rest: '#424242', hover: '#242424', pressed: '#242424' }, + foregroundNeutralTertiary: { rest: '#616161', hover: '#424242', pressed: '#424242' }, + foregroundNeutralOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + foregroundBrandPrimary: { rest: '#185abd', hover: '#185abd', pressed: '#185abd' }, + foregroundBrandOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + foregroundDangerPrimary: { rest: '#bc2f32', hover: '#bc2f32', pressed: '#bc2f32' }, + foregroundDangerOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + foregroundWarningPrimary: { rest: '#817400', hover: '#817400', pressed: '#817400' }, + foregroundWarningOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + foregroundSuccessPrimary: { rest: '#0e700e', hover: '#0e700e', pressed: '#0e700e' }, + foregroundSuccessOnloud: { rest: '#ffffff', hover: '#ffffff', pressed: '#ffffff', type: 'inverted' }, + fixedWhite: '#ffffff', + fixedBlack: '#000000', + expressionAchromaticHeavy: '#000000', + expressionAchromaticSubtle: '#ffffff', + backgroundNeutralDisabled: '#f0f0f0', + backgroundNeutralHeavyDisabled: '#f0f0f0', + backgroundNeutralSubtleDisabled: '#f0f0f0', + strokeNeutralDisabled: '#e0e0e0', + foregroundNeutralDisabled: '#bdbdbd', + strokeFocusInner: '#ffffff', + strokeFocusOuter: '#000000', + shadow: '#000000', + }, + shadow: { + lowest: [ambient, { x: 0, y: 1, blur: 2, color: '#00000024' }], + lower: [ambient, { x: 0, y: 2, blur: 4, color: '#00000024' }], + low: [ambient, { x: 0, y: 4, blur: 8, color: '#00000024' }], + high: [ambient, { x: 0, y: 8, blur: 16, color: '#00000024' }], + higher: [ambientHigh, { x: 0, y: 14, blur: 28, color: '#0000003d' }], + highest: [ambientHigh, { x: 0, y: 32, blur: 64, color: '#0000003d' }], + }, + fontWeight: { + functionalRegular: fontWeightRegular, + functionalMedium: fontWeightMedium, + functionalSemibold: fontWeightSemibold, + functionalBold: fontWeightBold, + contentRegular: fontWeightRegular, + contentMedium: fontWeightMedium, + contentSemibold: fontWeightSemibold, + contentBold: fontWeightBold, + contentEditorialRegular: fontWeightRegular, + contentEditorialMedium: fontWeightMedium, + contentEditorialSemibold: fontWeightSemibold, + contentEditorialBold: fontWeightBold, + }, + fontFamily: { + functional: fontFamilyBase, + content: fontFamilyBase, + contentEditorial: fontFamilyBase, + contentCode: fontFamilyMonospace, + }, + fontSize: { + functionalDisplay: fontSize1000, + functionalPagetitle: fontSize900, + functionalTitleLarge: fontSize800, + functionalTitleMedium: fontSize700, + functionalTitleSmall: fontSize600, + functionalSubtitle: fontSize500, + functionalBodyLarge: fontSize400, + functionalBodyMedium: fontSize300, + functionalBodySmall: fontSize200, + functionalCaption: fontSize100, + contentStatement: fontSize1000, + contentExpressiveLarge: fontSize900, + contentExpressiveMedium: fontSize800, + contentExpressiveSmall: fontSize700, + contentH1: fontSize800, + contentH2: fontSize800, + contentH3: fontSize700, + contentH4: fontSize600, + contentH5: fontSize500, + contentSubheadline: fontSize400, + contentParagraphLarge: fontSize500, + contentParagraphMedium: fontSize400, + contentParagraphSmall: fontSize200, + contentSubtext: fontSize100, + contentTable: fontSize400, + contentCode: fontSize400, + }, + borderRadius: { + ...nonFluentFlexTokens.borderRadius, + base200: cornerRadius40, + base300: cornerRadius40, + }, +}); + +/** + * Fluent-native fallback tokens resolved for the default appearance. + */ +export const fluentFallbackFlexTokens: FlexTokens = resolveExplicitFlexTokenDescription( + fluentFallbackFlexTokenDescription, + defaultResolvedThemeAppearance, +); diff --git a/packages/agentic/design/src/flex/colors/flexColor.test.ts b/packages/agentic/design/src/flex/colors/flexColor.test.ts new file mode 100644 index 00000000000..828ee90e50a --- /dev/null +++ b/packages/agentic/design/src/flex/colors/flexColor.test.ts @@ -0,0 +1,109 @@ +import { PlatformColor } from 'react-native'; + +import type { FlexColorInput, InteractiveColorType } from '../tokens.types'; +import { flexColor, normalizeFlexColor, resolveExplicitFlexColor, selectColorEntry } from './flexColor'; +import { createInteractiveColor } from './interactiveColor'; + +const light = { colorScheme: 'light' } as const; +const dark = { colorScheme: 'dark' } as const; + +describe('flexColor', () => { + it('describes a single value with the requested type', () => { + expect(flexColor('#123456')).toEqual({ rest: '#123456', type: 'standard' }); + expect(flexColor('#123456', 'inverted')).toEqual({ rest: '#123456', type: 'inverted' }); + }); + + it('lets an explicit value type win over the second argument', () => { + expect(flexColor({ rest: '#123456', type: 'fixed' }, 'inverted')).toEqual({ rest: '#123456', type: 'fixed' }); + expect(flexColor({ rest: '#123456' }, 'inverted')).toEqual({ rest: '#123456', type: 'inverted' }); + }); + + it('returns a new frozen description without mutating the input', () => { + const tuple = ['#ffffff', '#000000'] as const; + const input = { rest: tuple, hover: '#eeeeee' }; + const snapshot = structuredClone(input); + + const result = flexColor(input, 'inverted'); + + expect(result).not.toBe(input); + expect(input).toEqual(snapshot); + expect(Object.isFrozen(result)).toBe(true); + expect(Object.isFrozen(result.rest)).toBe(true); + expect(result.rest).not.toBe(tuple); + expect(result).toEqual({ rest: ['#ffffff', '#000000'], hover: '#eeeeee', type: 'inverted' }); + expect(Object.keys(result)).toEqual(['rest', 'hover', 'type']); + }); + + it('accepts frozen inputs and native colors', () => { + const native = PlatformColor('controlAccentColor'); + + expect(flexColor(Object.freeze({ rest: native, pressed: '#000000' }))).toEqual({ rest: native, pressed: '#000000', type: 'standard' }); + expect(flexColor([native, '#000000']).rest).toEqual([native, '#000000']); + }); + + it('validates tuples, options, and types', () => { + expect(() => flexColor(['#ffffff'] as unknown as FlexColorInput)).toThrow('exactly two colors'); + expect(() => flexColor(['#ffffff', '#000000', '#111111'] as unknown as FlexColorInput)).toThrow('exactly two colors'); + expect(() => flexColor({ rest: '#ffffff', focused: '#000000' } as unknown as FlexColorInput)).toThrow('unknown option "focused"'); + expect(() => flexColor({ hover: '#000000' } as unknown as FlexColorInput)).toThrow('must include rest'); + expect(() => flexColor({ rest: { rest: '#000000' } } as unknown as FlexColorInput)).toThrow('not nested interaction options'); + expect(() => flexColor({ rest: ['#ffffff', { rest: '#000000' }] } as unknown as FlexColorInput)).toThrow( + 'not nested interaction options', + ); + expect(() => flexColor({ rest: '#ffffff', type: 'loud' as InteractiveColorType })).toThrow('invalid type loud'); + expect(() => flexColor('#ffffff', 'loud' as InteractiveColorType)).toThrow('invalid type loud'); + expect(() => flexColor(true as unknown as FlexColorInput)).toThrow('must be a color value'); + }); + + it('rejects resolved colors as authored input', () => { + const resolved = createInteractiveColor('#ffffff', '#eeeeee', '#dddddd'); + + expect(() => flexColor(resolved as unknown as FlexColorInput)).toThrow('resolved InteractiveColor'); + expect(() => flexColor({ rest: resolved } as unknown as FlexColorInput)).toThrow('resolved InteractiveColor'); + }); +}); + +describe('normalizeFlexColor', () => { + it('returns a package-normalized description unchanged', () => { + const description = flexColor('#123456', 'inverted'); + + expect(normalizeFlexColor(description)).toBe(description); + expect(normalizeFlexColor(description, 'fixed')).toBe(description); + }); + + it('uses the default type for plain inputs', () => { + expect(normalizeFlexColor('#123456')).toEqual({ rest: '#123456', type: 'standard' }); + expect(normalizeFlexColor({ rest: '#123456' }, 'inverted')).toEqual({ rest: '#123456', type: 'inverted' }); + }); + + it('labels validation errors with the token path', () => { + expect(() => normalizeFlexColor({ hover: '#000000' } as unknown as FlexColorInput, 'standard', 'color.backgroundBrandHeavy')).toThrow( + 'color.backgroundBrandHeavy must include rest', + ); + }); +}); + +describe('selectColorEntry', () => { + it('uses a single value for every scheme', () => { + expect(selectColorEntry('#123456', light)).toBe('#123456'); + expect(selectColorEntry('#123456', dark)).toBe('#123456'); + }); + + it('selects light at index zero and dark at index one', () => { + expect(selectColorEntry(['#ffffff', '#000000'], light)).toBe('#ffffff'); + expect(selectColorEntry(['#ffffff', '#000000'], dark)).toBe('#000000'); + }); + + it('rejects malformed tuples', () => { + expect(() => selectColorEntry(['#ffffff'] as unknown as readonly [string, string], light)).toThrow('exactly [light, dark]'); + }); +}); + +describe('resolveExplicitFlexColor', () => { + it('resolves omitted states to rest and keeps explicit states', () => { + const resolved = resolveExplicitFlexColor(normalizeFlexColor({ rest: ['#ffffff', '#000000'], pressed: ['#dddddd', '#222222'] }), dark); + + expect(resolved).toEqual({ rest: '#000000', hover: '#000000', pressed: '#222222' }); + expect(Object.isFrozen(resolved)).toBe(true); + }); +}); diff --git a/packages/agentic/design/src/flex/colors/flexColor.ts b/packages/agentic/design/src/flex/colors/flexColor.ts new file mode 100644 index 00000000000..bf084449aa2 --- /dev/null +++ b/packages/agentic/design/src/flex/colors/flexColor.ts @@ -0,0 +1,163 @@ +import type { ColorValue } from 'react-native'; + +import type { ThemeColorScheme } from '../../types/appearance.types'; +import type { + ColorEntry, + ColorTuple, + FlexColorDescription, + FlexColorInput, + InteractiveColor, + InteractiveColorOptions, + InteractiveColorType, +} from '../tokens.types'; +import { createInteractiveColor, isInteractiveColor } from './interactiveColor'; + +/** The appearance field that selects a light/dark color tuple entry. */ +export type ColorSchemeSelector = { readonly colorScheme: ThemeColorScheme }; + +type MutableDescription = { rest: ColorEntry; hover?: ColorEntry; pressed?: ColorEntry; type: InteractiveColorType }; + +const colorTypes: ReadonlySet<string> = new Set<InteractiveColorType>(['standard', 'inverted', 'fixed']); +const optionKeys: ReadonlySet<string> = new Set(['rest', 'hover', 'pressed', 'type']); +const descriptions = new WeakSet<object>(); + +function isPlainObject(value: unknown): value is Record<string, unknown> { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return false; + } + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; +} + +function hasOptionKey(value: Record<string, unknown>): boolean { + return Object.keys(value).some((key) => optionKeys.has(key)); +} + +function rejectResolved(value: unknown, label: string): void { + if (isInteractiveColor(value)) { + throw new TypeError( + `${label} is a resolved InteractiveColor. Resolved colors are appearance-bound outputs; author rest and any explicit hover or pressed values instead.`, + ); + } +} + +function validateColorType(type: unknown, label: string): InteractiveColorType { + if (typeof type !== 'string' || !colorTypes.has(type)) { + throw new TypeError(`${label} has invalid type ${String(type)}. Expected "standard", "inverted", or "fixed".`); + } + return type as InteractiveColorType; +} + +function normalizeColorValue(value: unknown, label: string): ColorValue { + if (typeof value === 'string' || typeof value === 'number') { + return value as ColorValue; + } + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + rejectResolved(value, label); + if (isPlainObject(value) && hasOptionKey(value)) { + throw new TypeError(`${label} must be a color value, not nested interaction options.`); + } + return value as ColorValue; + } + throw new TypeError(`${label} must be a color value.`); +} + +function normalizeColorEntry(value: unknown, label: string): ColorEntry { + if (!Array.isArray(value)) { + return normalizeColorValue(value, label); + } + if (value.length !== 2) { + throw new TypeError(`${label} must be a [light, dark] tuple with exactly two colors.`); + } + return Object.freeze([normalizeColorValue(value[0], `${label}[0]`), normalizeColorValue(value[1], `${label}[1]`)]) as ColorTuple; +} + +function createDescription(rest: ColorEntry, hover: ColorEntry | undefined, pressed: ColorEntry | undefined, type: InteractiveColorType) { + const description: MutableDescription = { rest } as MutableDescription; + if (hover !== undefined) { + description.hover = hover; + } + if (pressed !== undefined) { + description.pressed = pressed; + } + description.type = type; + Object.freeze(description); + descriptions.add(description); + return description as FlexColorDescription; +} + +function normalizeOptions(options: Record<string, unknown>, defaultType: InteractiveColorType, label: string): FlexColorDescription { + for (const key of Object.keys(options)) { + if (!optionKeys.has(key)) { + throw new TypeError(`${label} has unknown option "${key}". Expected rest, hover, pressed, or type.`); + } + } + if (options.rest === undefined) { + throw new TypeError(`${label} must include rest when it supplies interaction options.`); + } + return createDescription( + normalizeColorEntry(options.rest, `${label}.rest`), + options.hover === undefined ? undefined : normalizeColorEntry(options.hover, `${label}.hover`), + options.pressed === undefined ? undefined : normalizeColorEntry(options.pressed, `${label}.pressed`), + options.type === undefined ? defaultType : validateColorType(options.type, label), + ); +} + +/** + * Normalize one authored color into a frozen description with an explicit + * type. Package-normalized descriptions are returned unchanged. + * @internal + */ +export function normalizeFlexColor( + value: FlexColorInput, + defaultType: InteractiveColorType = 'standard', + label = 'Flex color', +): FlexColorDescription { + if (typeof value === 'object' && value !== null && descriptions.has(value)) { + return value as FlexColorDescription; + } + rejectResolved(value, label); + const type = validateColorType(defaultType, label); + if (isPlainObject(value) && hasOptionKey(value)) { + return normalizeOptions(value, type, label); + } + return createDescription(normalizeColorEntry(value, label), undefined, undefined, type); +} + +/** + * Normalize an authored Flex color. A single value applies to every scheme, + * and a tuple selects `[light, dark]`. The second argument sets the + * interaction type unless `value.type` is supplied. Arguments are never + * mutated; the result is a new frozen options object. + */ +export function flexColor(value: FlexColorInput, colorType: InteractiveColorType = 'standard'): InteractiveColorOptions { + return normalizeFlexColor(value, colorType, 'flexColor value'); +} + +/** + * Select the color for a scheme from an authored rest or explicit state entry. + */ +export function selectColorEntry(entry: ColorEntry, appearance: ColorSchemeSelector): ColorValue { + if (!Array.isArray(entry)) { + return entry as ColorValue; + } + if (entry.length !== 2) { + throw new TypeError('A Flex color tuple must contain exactly [light, dark].'); + } + return entry[appearance.colorScheme === 'dark' ? 1 : 0]; +} + +/** + * Resolve a description without interaction algorithms: omitted states equal + * rest. Used by defaults and legacy adapters, whose fallback ownership must + * not change. + * @internal + */ +export function resolveExplicitFlexColor(description: FlexColorDescription, appearance: ColorSchemeSelector): InteractiveColor { + const rest = selectColorEntry(description.rest, appearance); + return createInteractiveColor( + rest, + description.hover === undefined ? rest : selectColorEntry(description.hover, appearance), + description.pressed === undefined ? rest : selectColorEntry(description.pressed, appearance), + ); +} diff --git a/packages/agentic/design/src/flex/colors/interactionLaziness.test.tsx b/packages/agentic/design/src/flex/colors/interactionLaziness.test.tsx new file mode 100644 index 00000000000..e12454fbc9b --- /dev/null +++ b/packages/agentic/design/src/flex/colors/interactionLaziness.test.tsx @@ -0,0 +1,116 @@ +import { act, create } from 'react-test-renderer'; +import type { ReactTestRenderer } from 'react-test-renderer'; + +import * as interaction from '../../color-lib/interaction'; +import { ThemedRoot } from '../../theming/ThemedRoot'; +import type { NormalizedThemeAppearance } from '../../types/appearance.types'; +import { defaultFlexTokenDescription } from '../defaults/defaultTokens'; +import { FlexThemeReference } from '../flexThemeReference'; +import { mergeFlexTokenDescription } from '../flexTokenDescription'; +import type { FlexTokens } from '../tokens.types'; +import { useThemeState } from '../useThemeState'; +import { flexColor, normalizeFlexColor } from './flexColor'; +import { resolveFlexColor, resolveFlexTokenDescription } from './interactionPolicy'; + +const lightCool: NormalizedThemeAppearance = { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base', colorTone: 'cool' }; + +describe('interaction derivation laziness', () => { + let engine: jest.SpyInstance; + + beforeEach(() => { + engine = jest.spyOn(interaction, 'getInteractionColor'); + }); + + afterEach(() => { + engine.mockRestore(); + }); + + it('computes nothing when tokens resolve and only rest values are read', () => { + const description = mergeFlexTokenDescription(defaultFlexTokenDescription, { + color: { backgroundBrandHeavy: flexColor('#123456', 'inverted'), backgroundNeutralSubtle: '#fafafa' }, + }); + + const tokens = resolveFlexTokenDescription(description, lightCool); + for (const color of Object.values(tokens.color)) { + void color.rest; + } + + expect(Object.keys(tokens.color)).toContain('backgroundBrandHeavy'); + expect(engine).not.toHaveBeenCalled(); + }); + + it('computes only the read state, once', () => { + const color = resolveFlexColor('backgroundBrandHeavy', normalizeFlexColor('#123456', 'inverted'), lightCool); + + const first = color.hover; + const second = color.hover; + + expect(second).toBe(first); + expect(engine).toHaveBeenCalledTimes(1); + expect(engine).toHaveBeenCalledWith('#123456', 'light', 'hover', expect.objectContaining({ direction: 'inverted' })); + + void color.pressed; + void color.pressed; + + expect(engine).toHaveBeenCalledTimes(2); + expect(engine).toHaveBeenLastCalledWith('#123456', 'light', 'pressed', expect.objectContaining({ direction: 'inverted' })); + }); + + it('never computes explicit states', () => { + const color = resolveFlexColor( + 'backgroundBrandHeavy', + normalizeFlexColor({ rest: '#123456', hover: '#234567', pressed: '#345678' }), + lightCool, + ); + + expect(color).toEqual({ rest: '#123456', hover: '#234567', pressed: '#345678' }); + expect(engine).not.toHaveBeenCalled(); + }); + + it('does not compute states while merging descriptions or resolving a theme reference', () => { + const reference = new FlexThemeReference({ base: { color: { backgroundBrandHeavy: flexColor('#123456', 'inverted') } } }); + const child = new FlexThemeReference({ base: reference }, { color: { backgroundBrandSoft: '#eeeeff' } }); + + const tokens = child.resolveFlexTokens(lightCool); + + expect(tokens.color.backgroundBrandHeavy.rest).toBe('#123456'); + expect(engine).not.toHaveBeenCalled(); + + void tokens.color.backgroundBrandSoft.hover; + expect(engine).toHaveBeenCalledTimes(1); + }); + + it('computes nothing when a provider mounts and a consumer reads rest', () => { + const reference = new FlexThemeReference({ base: { color: { backgroundBrandHeavy: flexColor('#123456', 'inverted') } } }); + const seen: FlexTokens[] = []; + function Probe() { + const { tokens } = useThemeState(); + seen.push(tokens); + void tokens.color.backgroundBrandHeavy.rest; + return null; + } + + let component: ReactTestRenderer; + act(() => { + component = create( + <ThemedRoot theme={reference} appearance={{ colorScheme: 'light', contrast: 'standard' }}> + <Probe /> + </ThemedRoot>, + ); + }); + + expect(seen[0].color.backgroundBrandHeavy.rest).toBe('#123456'); + expect(engine).not.toHaveBeenCalled(); + act(() => component!.unmount()); + }); + + it('does not read states when resolved colors are copied by reference', () => { + const reference = new FlexThemeReference({ base: { color: { backgroundBrandHeavy: flexColor('#123456', 'inverted') } } }); + const tokens = reference.resolveFlexTokens(lightCool); + + const copy = { ...tokens, color: { ...tokens.color } }; + + expect(copy.color.backgroundBrandHeavy).toBe(tokens.color.backgroundBrandHeavy); + expect(engine).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/agentic/design/src/flex/colors/interactionPolicy.test.ts b/packages/agentic/design/src/flex/colors/interactionPolicy.test.ts new file mode 100644 index 00000000000..c7a3a73b021 --- /dev/null +++ b/packages/agentic/design/src/flex/colors/interactionPolicy.test.ts @@ -0,0 +1,255 @@ +import { PlatformColor } from 'react-native'; + +import { getInteractionColorOverrides, restColorValues } from '../../test/fixtures/interactionColors'; +import { x3WarmInteractionConformance, x3InteractionConformance, x3CoolExplicitStates } from '../../test/fixtures/x3InteractionConformance'; +import type { InteractionConformanceVector } from '../../test/fixtures/x3InteractionConformance'; +import type { ColorMode } from '../../color-lib/types'; +import type { ColorTone, NormalizedThemeAppearance } from '../../types/appearance.types'; +import { defaultFlexTokenDescription, defaultFlexTokens } from '../defaults/defaultTokens'; +import type { SemanticColorTokenValues } from '../tokens.types'; +import { normalizeFlexColor, selectColorEntry } from './flexColor'; +import { deriveInteractionColor, resolveFlexColor, resolveFlexTokenDescription } from './interactionPolicy'; +import { + getInteractionCompositing, + getInteractionDirection, + INTERACTIVE_COLOR_TOKENS, + isInverseInteractionToken, +} from './interactiveTokens'; +import type { InteractiveColorToken } from './interactiveTokens'; + +const modeIndexes = { + light: { rest: 0, hover: 1, pressed: 2 }, + dark: { rest: 3, hover: 4, pressed: 5 }, +} as const; + +function appearance(colorScheme: ColorMode, colorTone: ColorTone = 'cool'): NormalizedThemeAppearance { + return { colorScheme, contrast: 'standard', interfaceLevel: 'base', colorTone }; +} + +function restColors( + mode: ColorMode, + conformance: Readonly<Record<InteractiveColorToken, InteractionConformanceVector>> = x3InteractionConformance, +): SemanticColorTokenValues { + const colors = restColorValues(defaultFlexTokens.color); + for (const token of INTERACTIVE_COLOR_TOKENS) { + colors[token] = conformance[token][modeIndexes[mode].rest]; + } + return colors; +} + +describe('interactive token classification', () => { + it('classifies every inverse token with the upstream heavy/loud/onloud rule', () => { + const expected = [ + 'backgroundNeutralHeavy', + 'backgroundNeutralLoud', + 'backgroundBrandHeavy', + 'backgroundBrandLoud', + 'backgroundDangerLoud', + 'backgroundWarningLoud', + 'backgroundSuccessLoud', + 'strokeNeutralHeavy', + 'strokeNeutralLoud', + 'strokeNeutralOnloud', + 'strokeBrandLoud', + 'strokeBrandOnloud', + 'strokeDangerLoud', + 'strokeDangerOnloud', + 'strokeWarningLoud', + 'strokeWarningOnloud', + 'strokeSuccessLoud', + 'strokeSuccessOnloud', + 'foregroundNeutralOnloud', + 'foregroundBrandOnloud', + 'foregroundDangerOnloud', + 'foregroundWarningOnloud', + 'foregroundSuccessOnloud', + ]; + + expect(INTERACTIVE_COLOR_TOKENS.filter(isInverseInteractionToken)).toEqual(expected); + expect(INTERACTIVE_COLOR_TOKENS.filter((token) => getInteractionDirection(token) === 'inverted')).toEqual(expected); + expect(INTERACTIVE_COLOR_TOKENS).toHaveLength(59); + expect(Object.keys(x3CoolExplicitStates)).toHaveLength(10); + }); + + it('composites only background and stroke tokens against the warm backdrop', () => { + for (const token of INTERACTIVE_COLOR_TOKENS) { + const expected = token.startsWith('background') || token.startsWith('stroke') ? 'backdrop' : 'direct'; + expect([token, getInteractionCompositing(token)]).toEqual([token, expected]); + } + }); +}); + +describe('default explicit interaction states', () => { + it('authors exactly the cool table states the policy cannot reproduce', () => { + const authored = Object.entries(defaultFlexTokenDescription.color).flatMap(([token, color]) => + (['hover', 'pressed'] as const).filter((state) => color[state] !== undefined).map((state) => `${token}.${state}`), + ); + const fixtureStates = new Set(Object.keys(x3CoolExplicitStates).map((key) => key.slice(0, key.lastIndexOf('.')))); + + expect(authored.sort()).toEqual([...fixtureStates].sort()); + for (const [key, { sourceValue }] of Object.entries(x3CoolExplicitStates)) { + const [token, state, mode] = key.split('.') as [keyof SemanticColorTokenValues, 'hover' | 'pressed', ColorMode]; + const entry = defaultFlexTokenDescription.color[token][state]; + + expect([key, entry === undefined ? undefined : selectColorEntry(entry, appearance(mode))]).toEqual([key, sourceValue]); + } + }); +}); + +describe.each(['light', 'dark'] as const)('%s Flex interaction policy', (mode) => { + it.each(INTERACTIVE_COLOR_TOKENS)('matches the cool and warm conformance values for %s', (token) => { + const vector = x3InteractionConformance[token]; + const warmVector = x3WarmInteractionConformance[token]; + for (const state of ['hover', 'pressed'] as const) { + const explicitKey = `${token}.${state}.${mode}` as keyof typeof x3CoolExplicitStates; + const explicitState = x3CoolExplicitStates[explicitKey]; + const upstreamValue = vector[modeIndexes[mode][state]]; + + const direction = getInteractionDirection(token); + + expect(deriveInteractionColor(vector[modeIndexes[mode].rest], token, state, direction, appearance(mode))).toBe( + explicitState?.derivedValue ?? upstreamValue, + ); + expect(deriveInteractionColor(warmVector[modeIndexes[mode].rest], token, state, direction, appearance(mode, 'warm'))).toBe( + warmVector[modeIndexes[mode][state]], + ); + if (explicitState) { + expect(upstreamValue).toBe(explicitState.sourceValue); + } + } + }); + + it.each(['cool', 'warm'] as const)('derives a complete %s override map', (colorTone) => { + const conformance = colorTone === 'warm' ? x3WarmInteractionConformance : x3InteractionConformance; + const result = getInteractionColorOverrides(restColors(mode, conformance), mode, 'hover', colorTone); + + expect(result.diagnostics).toEqual([]); + expect(Object.keys(result.overrides)).toHaveLength(59); + }); +}); + +describe('deriveInteractionColor', () => { + it('returns rest in high contrast', () => { + expect( + deriveInteractionColor('#ebebeb', 'surfaceNeutralFarther', 'hover', 'standard', { + ...appearance('light', 'warm'), + contrast: 'highContrast', + }), + ).toBe('#ebebeb'); + }); + + it('returns the same rest value when the engine cannot resolve it', () => { + const rest = PlatformColor('labelColor'); + + expect(deriveInteractionColor(rest, 'foregroundNeutralPrimary', 'pressed', 'standard', appearance('dark'))).toBe(rest); + }); + + it('does not swallow unexpected engine failures', () => { + jest.isolateModules(() => { + jest.doMock('../../color-lib/interaction', () => ({ + getInteractionColor: () => { + throw new Error('engine failure'); + }, + })); + const policy = require('./interactionPolicy') as typeof import('./interactionPolicy'); + + expect(() => policy.deriveInteractionColor('#ebebeb', 'surfaceNeutralFarther', 'hover', 'standard', appearance('light'))).toThrow( + 'engine failure', + ); + }); + }); +}); + +describe('resolveFlexColor', () => { + it('derives omitted interactive states from rest and keeps explicit states', () => { + const color = resolveFlexColor('surfaceNeutralFarther', normalizeFlexColor({ rest: '#ffffff', hover: '#123456' }), appearance('light')); + + expect(color.rest).toBe('#ffffff'); + expect(color.hover).toBe('#123456'); + expect(color.pressed).toBe(deriveInteractionColor('#ffffff', 'surfaceNeutralFarther', 'pressed', 'standard', appearance('light'))); + expect(color.pressed).not.toBe('#ffffff'); + }); + + it('uses the description type as the direction', () => { + const rest = x3InteractionConformance.backgroundBrandHeavy[modeIndexes.light.rest]; + const inverted = resolveFlexColor('backgroundBrandHeavy', normalizeFlexColor(rest, 'inverted'), appearance('light')); + const standard = resolveFlexColor('backgroundBrandHeavy', normalizeFlexColor(rest), appearance('light')); + + expect(inverted.hover).toBe(deriveInteractionColor(rest, 'backgroundBrandHeavy', 'hover', 'inverted', appearance('light'))); + expect(standard.hover).toBe(deriveInteractionColor(rest, 'backgroundBrandHeavy', 'hover', 'standard', appearance('light'))); + expect(standard.hover).not.toBe(inverted.hover); + }); + + it('selects tuple entries for the appearance scheme', () => { + const description = normalizeFlexColor({ rest: ['#ffffff', '#000000'], hover: ['#eeeeee', '#111111'] }); + + expect(resolveFlexColor('surfaceNeutralFarther', description, appearance('light'))).toMatchObject({ + rest: '#ffffff', + hover: '#eeeeee', + }); + expect(resolveFlexColor('surfaceNeutralFarther', description, appearance('dark'))).toMatchObject({ rest: '#000000', hover: '#111111' }); + }); + + it('resolves omitted states to rest in high contrast and for non-interactive tokens', () => { + const highContrast = resolveFlexColor('surfaceNeutralFarther', normalizeFlexColor('#ffffff'), { + ...appearance('dark'), + contrast: 'highContrast', + }); + const nonInteractive = resolveFlexColor('fixedBlack', normalizeFlexColor('#000000'), appearance('light')); + + expect([highContrast.hover, highContrast.pressed]).toEqual(['#ffffff', '#ffffff']); + expect([nonInteractive.hover, nonInteractive.pressed]).toEqual(['#000000', '#000000']); + }); + + it('keeps an unmappable native rest value by identity', () => { + const rest = PlatformColor('controlAccentColor'); + const color = resolveFlexColor('backgroundBrandHeavy', normalizeFlexColor(rest, 'inverted'), appearance('light')); + + expect(color.rest).toBe(rest); + expect(color.hover).toBe(rest); + expect(color.pressed).toBe(rest); + }); + + it('requires explicit states for a fixed derivable color', () => { + const fixed = normalizeFlexColor({ rest: '#0f6cbd', hover: '#115ea3', type: 'fixed' }); + const complete = normalizeFlexColor({ rest: '#0f6cbd', hover: '#115ea3', pressed: '#0c3b5e', type: 'fixed' }); + + expect(() => resolveFlexColor('backgroundBrandHeavy', fixed, appearance('light'))).toThrow( + 'type "fixed" and no explicit pressed value', + ); + expect(resolveFlexColor('backgroundBrandHeavy', fixed, { ...appearance('light'), contrast: 'highContrast' })).toEqual({ + rest: '#0f6cbd', + hover: '#115ea3', + pressed: '#0f6cbd', + }); + expect(resolveFlexColor('backgroundBrandHeavy', complete, appearance('light'))).toEqual({ + rest: '#0f6cbd', + hover: '#115ea3', + pressed: '#0c3b5e', + }); + }); + + it('accepts a fixed native color without explicit states', () => { + const rest = PlatformColor('controlAccentColor'); + const color = resolveFlexColor('backgroundBrandHeavy', normalizeFlexColor(rest, 'fixed'), appearance('light')); + + expect(color.hover).toBe(rest); + }); +}); + +describe('resolveFlexTokenDescription', () => { + it('resolves every default color and shares non-color groups', () => { + const tokens = resolveFlexTokenDescription(defaultFlexTokenDescription, appearance('light')); + + expect(Object.keys(tokens.color)).toEqual(Object.keys(defaultFlexTokenDescription.color)); + expect(tokens.spacing).toBe(defaultFlexTokenDescription.spacing); + expect(Object.isFrozen(tokens)).toBe(true); + expect(Object.isFrozen(tokens.color)).toBe(true); + }); + + it('matches the default explicit states', () => { + const tokens = resolveFlexTokenDescription(defaultFlexTokenDescription, appearance('light')); + + expect(tokens.color).toEqual(defaultFlexTokens.color); + }); +}); diff --git a/packages/agentic/design/src/flex/colors/interactionPolicy.ts b/packages/agentic/design/src/flex/colors/interactionPolicy.ts new file mode 100644 index 00000000000..a3db1251616 --- /dev/null +++ b/packages/agentic/design/src/flex/colors/interactionPolicy.ts @@ -0,0 +1,95 @@ +import type { ColorValue } from 'react-native'; + +import { getInteractionColor } from '../../color-lib/interaction'; +import { parseColorValue } from '../../color-lib/parsing'; +import type { InteractionColorState, InteractionDirection } from '../../color-lib/types'; +import type { NormalizedThemeAppearance } from '../../types/appearance.types'; +import { resolveFlexTokenDescriptionWith } from '../flexTokenDescription'; +import type { FlexColorDescription, FlexTokenDescription, FlexTokens, InteractiveColor } from '../tokens.types'; +import { selectColorEntry } from './flexColor'; +import { createInteractiveColor } from './interactiveColor'; +import type { InteractiveColorState } from './interactiveColor'; +import { getInteractionCompositing, isInteractiveColorToken } from './interactiveTokens'; +import type { InteractiveColorToken } from './interactiveTokens'; + +/** + * Compute one interaction state for a Flex token from its rest value. High + * contrast and rest values the raw engine cannot map, such as native platform + * colors, resolve to the rest value itself. + */ +export function deriveInteractionColor( + rest: ColorValue, + token: InteractiveColorToken, + state: InteractionColorState, + direction: InteractionDirection, + appearance: Readonly<NormalizedThemeAppearance>, +): ColorValue { + if (appearance.contrast === 'highContrast') { + return rest; + } + + const result = getInteractionColor(rest, appearance.colorScheme, state, { + colorTone: appearance.colorTone, + direction, + compositing: getInteractionCompositing(token), + }); + return result.status === 'derived' ? result.value : rest; +} + +function resolveState( + token: string, + description: FlexColorDescription, + state: InteractionColorState, + rest: ColorValue, + appearance: Readonly<NormalizedThemeAppearance>, +): InteractiveColorState { + const explicit = description[state]; + if (explicit !== undefined) { + return selectColorEntry(explicit, appearance); + } + if (!isInteractiveColorToken(token)) { + return rest; + } + if (appearance.contrast === 'highContrast') { + return rest; + } + + const { type } = description; + if (type === 'fixed') { + if (parseColorValue(rest).status === 'resolved') { + throw new Error( + `Flex color "${token}" has type "fixed" and no explicit ${state} value. Fixed interaction derivation is not defined; author explicit hover and pressed values.`, + ); + } + return rest; + } + return () => deriveInteractionColor(rest, token, state, type, appearance); +} + +/** + * Resolve one authored color for an appearance. Explicit states win. Omitted + * states of interactive tokens are computed on first read from rest, using the + * description's type for direction; other tokens and high contrast use rest. + * Outside high contrast, a fixed interactive color whose rest the engine can + * map must author every state, and throws here otherwise. + */ +export function resolveFlexColor( + token: string, + description: FlexColorDescription, + appearance: Readonly<NormalizedThemeAppearance>, +): InteractiveColor { + const rest = selectColorEntry(description.rest, appearance); + return createInteractiveColor( + rest, + resolveState(token, description, 'hover', rest, appearance), + resolveState(token, description, 'pressed', rest, appearance), + ); +} + +/** Resolve a normalized token description for an appearance. */ +export function resolveFlexTokenDescription( + description: FlexTokenDescription, + appearance: Readonly<NormalizedThemeAppearance>, +): FlexTokens { + return resolveFlexTokenDescriptionWith(description, appearance, resolveFlexColor); +} diff --git a/packages/agentic/design/src/flex/colors/interactiveColor.ts b/packages/agentic/design/src/flex/colors/interactiveColor.ts new file mode 100644 index 00000000000..f981fb24103 --- /dev/null +++ b/packages/agentic/design/src/flex/colors/interactiveColor.ts @@ -0,0 +1,48 @@ +import type { ColorValue } from 'react-native'; + +import type { InteractiveColor } from '../tokens.types'; + +/** An explicit state value, or a function that computes it on first read. */ +export type InteractiveColorState = ColorValue | (() => ColorValue); + +// Used only to reject resolved envelopes passed back as authored input. +const resolvedColors = new WeakSet<object>(); + +/** Return whether a value is a package-created resolved `InteractiveColor`. */ +export function isInteractiveColor(value: unknown): value is InteractiveColor { + return typeof value === 'object' && value !== null && resolvedColors.has(value); +} + +function defineState(target: object, name: 'hover' | 'pressed', state: InteractiveColorState): void { + if (typeof state !== 'function') { + Object.defineProperty(target, name, { value: state, enumerable: true }); + return; + } + + let resolved = false; + let value: ColorValue; + Object.defineProperty(target, name, { + enumerable: true, + get: () => { + if (!resolved) { + value = state(); + resolved = true; + } + return value; + }, + }); +} + +/** + * Create a frozen resolved color. Function states run on first read and are + * memoized independently. + */ +export function createInteractiveColor(rest: ColorValue, hover: InteractiveColorState, pressed: InteractiveColorState): InteractiveColor { + const color = {}; + Object.defineProperty(color, 'rest', { value: rest, enumerable: true }); + defineState(color, 'hover', hover); + defineState(color, 'pressed', pressed); + Object.freeze(color); + resolvedColors.add(color); + return color as InteractiveColor; +} diff --git a/packages/agentic/design/src/flex/colors/interactiveTokens.ts b/packages/agentic/design/src/flex/colors/interactiveTokens.ts new file mode 100644 index 00000000000..e780bc9b7aa --- /dev/null +++ b/packages/agentic/design/src/flex/colors/interactiveTokens.ts @@ -0,0 +1,105 @@ +import type { InteractionCompositing, InteractionDirection } from '../../color-lib/types'; +import type { SemanticColorName } from '../tokens.types'; + +/** + * Interactive subset of the Flex semantic color tokens. Only these tokens + * compute omitted hover and pressed states; every other token's states equal + * rest unless authored explicitly. + * + * Source: x3-design/fluent-design@206e890b645fb450ad7c5df2ff981765349a2b58. + */ +export const INTERACTIVE_COLOR_TOKENS = [ + 'surfaceNeutralFarther', + 'surfaceNeutralFar', + 'surfaceNeutralNear', + 'surfaceNeutralNearer', + 'surfaceNeutralTranslucent', + 'backgroundNeutralHeavy', + 'backgroundNeutralLoud', + 'backgroundNeutralSoft', + 'backgroundNeutralSubtle', + 'backgroundNeutralTransparent', + 'backgroundNeutralTranslucent', + 'backgroundBrandHeavy', + 'backgroundBrandLoud', + 'backgroundBrandSoft', + 'backgroundBrandSubtle', + 'backgroundBrandTransparent', + 'backgroundDangerLoud', + 'backgroundDangerSoft', + 'backgroundDangerSubtle', + 'backgroundWarningLoud', + 'backgroundWarningSoft', + 'backgroundWarningSubtle', + 'backgroundSuccessLoud', + 'backgroundSuccessSoft', + 'backgroundSuccessSubtle', + 'strokeNeutralHeavy', + 'strokeNeutralLoud', + 'strokeNeutralSoft', + 'strokeNeutralSubtle', + 'strokeNeutralTransparent', + 'strokeNeutralOnloud', + 'strokeBrandLoud', + 'strokeBrandSoft', + 'strokeBrandSubtle', + 'strokeBrandOnloud', + 'strokeDangerLoud', + 'strokeDangerSoft', + 'strokeDangerSubtle', + 'strokeDangerOnloud', + 'strokeWarningLoud', + 'strokeWarningSoft', + 'strokeWarningSubtle', + 'strokeWarningOnloud', + 'strokeSuccessLoud', + 'strokeSuccessSoft', + 'strokeSuccessSubtle', + 'strokeSuccessOnloud', + 'foregroundNeutralPrimary', + 'foregroundNeutralSecondary', + 'foregroundNeutralTertiary', + 'foregroundNeutralOnloud', + 'foregroundBrandPrimary', + 'foregroundBrandOnloud', + 'foregroundDangerPrimary', + 'foregroundDangerOnloud', + 'foregroundWarningPrimary', + 'foregroundWarningOnloud', + 'foregroundSuccessPrimary', + 'foregroundSuccessOnloud', +] as const satisfies readonly SemanticColorName[]; + +/** A Flex semantic color token whose omitted hover and pressed states are computed. */ +export type InteractiveColorToken = (typeof INTERACTIVE_COLOR_TOKENS)[number]; + +const interactiveColorTokens: ReadonlySet<string> = new Set(INTERACTIVE_COLOR_TOKENS); + +/** Return whether a color token computes omitted hover and pressed states. */ +export function isInteractiveColorToken(token: string): token is InteractiveColorToken { + return interactiveColorTokens.has(token); +} + +/** + * Return whether an interactive token's default color type is inverted. Heavy, + * loud, and on-loud roles shift opposite the standard lightness direction. + * Defaults and legacy adapters use this classification; newly authored colors + * declare their type explicitly. + */ +export function isInverseInteractionToken(token: InteractiveColorToken): boolean { + const name = token.toLowerCase(); + return name.includes('heavy') || name.includes('loud'); +} + +/** The raw interaction direction for an interactive token. */ +export function getInteractionDirection(token: InteractiveColorToken): InteractionDirection { + return isInverseInteractionToken(token) ? 'inverted' : 'standard'; +} + +/** + * The raw compositing intent for an interactive token. Translucent backgrounds + * and strokes are solved against the reference backdrop. + */ +export function getInteractionCompositing(token: InteractiveColorToken): InteractionCompositing { + return token.startsWith('background') || token.startsWith('stroke') ? 'backdrop' : 'direct'; +} diff --git a/packages/agentic/design/src/flex/defaults/defaultTokens.generated.ts b/packages/agentic/design/src/flex/defaults/defaultTokens.generated.ts new file mode 100644 index 00000000000..c99af744640 --- /dev/null +++ b/packages/agentic/design/src/flex/defaults/defaultTokens.generated.ts @@ -0,0 +1,423 @@ +// Generated by scripts/flex-defaults/generate-defaults.mjs. Do not edit; run `yarn gen:flex-defaults`. +// Source: x3-design/fluent-design@206e890b645fb450ad7c5df2ff981765349a2b58 +// cool: dev/web/flex-themes/css/semantic.css, dev/web/flex-themes/css/interaction-fallback.css +// warm: dev/web/flex-themes/css/warm/semantic.css, dev/web/flex-themes/css/warm/interaction-fallback.css +// Generic sources: src/tokens/mappings/flex-token-map.yaml +// Coverage: scripts/flex-defaults/coverage.generated.json + +import { + fontFamilyBase, + fontFamilyMonospace, + fontWeightBold, + fontWeightMedium, + fontWeightRegular, + fontWeightSemibold, +} from '../../tokens/global.generated'; +import type { CompleteFlexTokenInput } from '../tokens.types'; + +const inverted = 'inverted'; +const rgb000000 = '#000000'; +const rgb00000008 = '#00000008'; +const rgb0000000d = '#0000000d'; +const rgb0000000f = '#0000000f'; +const rgb00000014 = '#00000014'; +const rgb0000001a = '#0000001a'; +const rgb0000001f = '#0000001f'; +const rgb00000029 = '#00000029'; +const rgb000000db = '#000000db'; +const rgb0b0600e1 = '#0b0600e1'; +const rgb0b497f = '#0b497f'; +const rgb0c5722 = '#0c5722'; +const rgb242424 = '#242424'; +const rgb28231e = '#28231e'; +const rgb294482 = '#294482'; +const rgb2f95f4 = '#2f95f4'; +const rgb32ad52 = '#32ad52'; +const rgb345200 = '#345200'; +const rgb3c3c3c80 = '#3c3c3c80'; +const rgb484848 = '#484848'; +const rgb523778 = '#523778'; +const rgb524800 = '#524800'; +const rgb5c8df8 = '#5c8df8'; +const rgb5dce97 = '#5dce97'; +const rgb6da603 = '#6da603'; +const rgb6f2b53 = '#6f2b53'; +const rgb762f0e = '#762f0e'; +const rgb772b28 = '#772b28'; +const rgb929292 = '#929292'; +const rgba575e8 = '#a575e8'; +const rgbbaedc1 = '#baedc1'; +const rgbc6e1ff = '#c6e1ff'; +const rgbcbff93 = '#cbff93'; +const rgbcd4808 = '#cd4808'; +const rgbcedeff = '#cedeff'; +const rgbd961a6 = '#d961a6'; +const rgbdedede = '#dedede'; +const rgbe4d6ff = '#e4d6ff'; +const rgbe55e7a = '#e55e7a'; +const rgbe56738 = '#e56738'; +const rgbe6ffcf = '#e6ffcf'; +const rgbe7615b = '#e7615b'; +const rgbe7fce9 = '#e7fce9'; +const rgbeef6ff = '#eef6ff'; +const rgbf0f5ff = '#f0f5ff'; +const rgbf5f5f5 = '#f5f5f5'; +const rgbf7f3ff = '#f7f3ff'; +const rgbfb966e = '#fb966e'; +const rgbfbdf06 = '#fbdf06'; +const rgbfc9571 = '#fc9571'; +const rgbfef2ee = '#fef2ee'; +const rgbffcee6 = '#ffcee6'; +const rgbffd2cd = '#ffd2cd'; +const rgbffd3c2 = '#ffd3c2'; +const rgbffed85 = '#ffed85'; +const rgbfff1f7 = '#fff1f7'; +const rgbfff2f0 = '#fff2f0'; +const rgbfff7c4 = '#fff7c4'; +const rgbffffff = '#ffffff'; +const rgbffffff00 = '#ffffff00'; +const rgbffffff14 = '#ffffff14'; +const rgbffffff80 = '#ffffff80'; + +const backgroundNeutralDisabled = [rgb00000008, '#ffffff07'] as const; +const backgroundNeutralSoft1 = [rgb00000014, '#ffffff1f'] as const; +const backgroundNeutralSoft2 = ['#4d200028', '#ffe3cb40'] as const; +const backgroundNeutralSubtle = ['#6c31001a', '#fff4ef14'] as const; +const backgroundNeutralTransparent1 = ['#24242400', rgbffffff00] as const; +const backgroundNeutralTransparent2 = ['#28231e00', rgbffffff00] as const; +const easingFunctionalEnter = [0, 0, 0, 1] as const; +const easingFunctionalExit = [0.6, 0, 0.75, 0.4] as const; +const easingFunctionalTransition = [0.33, 0, 0, 1] as const; +const foregroundNeutralPrimary = [rgb0b0600e1, '#fff7f2e3'] as const; +const rest1 = ['#6f6f6f', rgb929292] as const; +const rest2 = ['#e9e9e980', rgb3c3c3c80] as const; +const rest3 = ['#0000006d', '#ffffff61'] as const; +const rest4 = ['#1e0d009a', '#ffeee39a'] as const; +const shadowLayer1 = { x: 0, y: 0, blur: 2, color: rgb0000001a } as const; +const shadowLayer2 = { x: 0, y: 0, blur: 2, color: '#00000033' } as const; +const shadowLayer3 = { x: 0, y: 8, blur: 16, color: rgb0000001f } as const; +const shadowLayer4 = { x: 0, y: 8, blur: 16, color: rgb00000008 } as const; +const strokeNeutralSoft2 = ['#250f0076', '#ffe6d35c'] as const; + +const backgroundDangerLoud = { rest: ['#c02e56', rgbe55e7a], type: inverted } as const; +const backgroundNeutralHeavy1 = { rest: [rgb242424, rgbffffff], type: inverted } as const; +const backgroundNeutralHeavy2 = { rest: [rgb28231e, rgbffffff], type: inverted } as const; +const backgroundNeutralLoud1 = { rest: rest1, type: inverted } as const; +const backgroundNeutralLoud2 = { rest: rest4, type: inverted } as const; +const backgroundSuccessLoud = { rest: ['#008455', '#05ad72'], type: inverted } as const; +const strokeBrandOnloud = { rest: [rgbffffff, rgb242424], type: inverted } as const; +const strokeNeutralLoud = { rest: ['#776d65', '#9a9089'], type: inverted } as const; +const strokeNeutralOnloud1 = { rest: [rgbffffff, rgb000000db], type: inverted } as const; +const strokeNeutralOnloud2 = { rest: [rgbffffff, rgb0b0600e1], type: inverted } as const; +const strokeNeutralSoft1 = { rest: rest3, hover: ['#02020277', '#ffffff69'], pressed: ['#04040481', '#ffffff70'] } as const; +const strokeNeutralSubtle = { rest: ['#00000021', '#ffffff48'], pressed: ['#05050535', '#ffffff57'] } as const; + +const sharedFlexTokenInputColor = { + backgroundDangerLoud, + backgroundDangerSoft: ['#ffe3e6', '#5a2932'], + backgroundDangerSubtle: ['#fff1f3', '#402529'], + backgroundWarningLoud: { rest: ['#bb4001', rgbe56738], type: inverted }, + backgroundWarningSoft: ['#ffe5dc', '#592c1c'], + backgroundWarningSubtle: ['#fff2ee', '#40261d'], + backgroundSuccessLoud, + backgroundSuccessSoft: ['#c9f8dd', '#0c462d'], + backgroundSuccessSubtle: ['#e3fcee', '#193426'], + strokeDangerLoud: backgroundDangerLoud, + strokeDangerSoft: [rgbe55e7a, '#d14164'], + strokeDangerSubtle: ['#ffd0d6', '#76293a'], + strokeDangerOnloud: strokeBrandOnloud, + strokeWarningLoud: { rest: [rgbcd4808, rgbe56738], type: inverted }, + strokeWarningSoft: [rgbfc9571, rgbcd4808], + strokeWarningSubtle: ['#ffd3c4', '#762e12'], + strokeWarningOnloud: strokeBrandOnloud, + strokeSuccessLoud: backgroundSuccessLoud, + strokeSuccessSoft: [rgb5dce97, '#008e5c'], + strokeSuccessSubtle: ['#b1efcc', '#025636'], + strokeSuccessOnloud: strokeBrandOnloud, + foregroundDangerPrimary: ['#a62147', '#fd8ea1'], + foregroundDangerOnloud: strokeNeutralOnloud1, + foregroundWarningPrimary: ['#a93901', rgbfc9571], + foregroundWarningOnloud: strokeNeutralOnloud1, + foregroundSuccessPrimary: ['#017048', rgb5dce97], + foregroundSuccessOnloud: strokeNeutralOnloud1, + fixedWhite: rgbffffff, + fixedBlack: rgb000000, + expressionAchromaticHeavy: [rgb000000, rgbffffff], + expressionAchromaticSubtle: [rgbffffff, rgb000000], + expressionGrayHeavy: [rgb484848, rgbf5f5f5], + expressionGrayLoud: [rgb929292, rgbdedede], + expressionGraySoft: [rgbdedede, rgb929292], + expressionGraySubtle: [rgbf5f5f5, rgb484848], + expressionNavyHeavy: [rgb294482, rgbf0f5ff], + expressionNavyLoud: [rgb5c8df8, rgbcedeff], + expressionNavySoft: [rgbcedeff, rgb5c8df8], + expressionNavySubtle: [rgbf0f5ff, rgb294482], + expressionBlueHeavy: [rgb0b497f, rgbeef6ff], + expressionBlueLoud: [rgb2f95f4, rgbc6e1ff], + expressionBlueSoft: [rgbc6e1ff, rgb2f95f4], + expressionBlueSubtle: [rgbeef6ff, rgb0b497f], + expressionGreenHeavy: [rgb0c5722, rgbe7fce9], + expressionGreenLoud: [rgb32ad52, rgbbaedc1], + expressionGreenSoft: [rgbbaedc1, rgb32ad52], + expressionGreenSubtle: [rgbe7fce9, rgb0c5722], + expressionLimeHeavy: [rgb345200, rgbe6ffcf], + expressionLimeLoud: [rgb6da603, rgbcbff93], + expressionLimeSoft: [rgbcbff93, rgb6da603], + expressionLimeSubtle: [rgbe6ffcf, rgb345200], + expressionYellowHeavy: [rgb524800, rgbfff7c4], + expressionYellowLoud: [rgbfbdf06, rgbffed85], + expressionYellowSoft: [rgbffed85, rgbfbdf06], + expressionYellowSubtle: [rgbfff7c4, rgb524800], + expressionPumpkinHeavy: [rgb762f0e, rgbfef2ee], + expressionPumpkinLoud: [rgbfb966e, rgbffd3c2], + expressionPumpkinSoft: [rgbffd3c2, rgbfb966e], + expressionPumpkinSubtle: [rgbfef2ee, rgb762f0e], + expressionRedHeavy: [rgb772b28, rgbfff2f0], + expressionRedLoud: [rgbe7615b, rgbffd2cd], + expressionRedSoft: [rgbffd2cd, rgbe7615b], + expressionRedSubtle: [rgbfff2f0, rgb772b28], + expressionPinkHeavy: [rgb6f2b53, rgbfff1f7], + expressionPinkLoud: [rgbd961a6, rgbffcee6], + expressionPinkSoft: [rgbffcee6, rgbd961a6], + expressionPinkSubtle: [rgbfff1f7, rgb6f2b53], + expressionPurpleHeavy: [rgb523778, rgbf7f3ff], + expressionPurpleLoud: [rgba575e8, rgbe4d6ff], + expressionPurpleSoft: [rgbe4d6ff, rgba575e8], + expressionPurpleSubtle: [rgbf7f3ff, rgb523778], + overlayNeutralTranslucent: ['#00000026', '#00000099'], + materialBackgroundThick: ['#fffffff1', '#262626ea'], + materialBackgroundRegular: ['#ffffffd7', '#2f2f2fd1'], + materialBackgroundThin: ['#ffffff7e', '#3434348b'], + backgroundNeutralDisabled, + backgroundNeutralHeavyDisabled: [rgb0000001a, '#ffffff20'], + strokeNeutralDisabled: [rgb00000014, '#ffffff24'], + foregroundNeutralDisabled: rest3, + strokeFocusInner: [rgbffffff, rgb000000], + strokeFocusOuter: [rgb000000, rgbffffff], + shadow: rgb000000, +} as const; + +const sharedFlexTokenInput = { + shadow: { + lowest: [[shadowLayer1, { x: 0, y: 1, blur: 2, color: rgb0000000d }], [shadowLayer2, { x: 0, y: 1, blur: 2, color: rgb0000001a }]], + lower: [[shadowLayer1, { x: 0, y: 2, blur: 4, color: rgb00000014 }], [shadowLayer2, { x: 0, y: 2, blur: 4, color: rgb00000029 }]], + low: [ + [shadowLayer1, { x: 0, y: 2, blur: 4, color: rgb00000008 }, { x: 0, y: 4, blur: 8, color: rgb00000014 }], + [shadowLayer2, { x: 0, y: 2, blur: 4, color: rgb0000001f }, { x: 0, y: 4, blur: 8, color: rgb00000029 }], + ], + high: [ + [shadowLayer1, { x: 0, y: 4, blur: 8, color: rgb00000008 }, { x: 0, y: 8, blur: 16, color: rgb0000000f }], + [shadowLayer2, { x: 0, y: 4, blur: 8, color: rgb0000001f }, shadowLayer3], + ], + higher: [ + [shadowLayer1, shadowLayer4, { x: 0, y: 16, blur: 32, color: rgb0000000f }], + [shadowLayer2, shadowLayer3, { x: 0, y: 16, blur: 32, color: rgb0000001f }], + ], + highest: [ + [shadowLayer1, shadowLayer4, { x: 0, y: 32, blur: 64, color: rgb0000000f }], + [shadowLayer2, shadowLayer3, { x: 0, y: 32, blur: 64, color: rgb0000001f }], + ], + }, + fontWeight: { + functionalRegular: fontWeightRegular, + functionalMedium: fontWeightMedium, + functionalSemibold: fontWeightSemibold, + functionalBold: fontWeightBold, + contentRegular: fontWeightRegular, + contentMedium: fontWeightMedium, + contentSemibold: fontWeightSemibold, + contentBold: fontWeightBold, + contentEditorialRegular: fontWeightRegular, + contentEditorialMedium: fontWeightMedium, + contentEditorialSemibold: fontWeightSemibold, + contentEditorialBold: fontWeightBold, + }, + fontFamily: { functional: fontFamilyBase, content: fontFamilyBase, contentEditorial: fontFamilyBase, contentCode: fontFamilyMonospace }, + fontSize: { + functionalDisplay: 68, + functionalPagetitle: 40, + functionalTitleLarge: 32, + functionalTitleMedium: 28, + functionalTitleSmall: 24, + functionalSubtitle: 20, + functionalBodyLarge: 16, + functionalBodyMedium: 14, + functionalBodySmall: 12, + functionalCaption: 10, + contentStatement: 56, + contentExpressiveLarge: 48, + contentExpressiveMedium: 36, + contentExpressiveSmall: 28, + contentH1: 36, + contentH2: 32, + contentH3: 28, + contentH4: 24, + contentH5: 20, + contentSubheadline: 16, + contentParagraphLarge: 20, + contentParagraphMedium: 16, + contentParagraphSmall: 12, + contentSubtext: 10, + contentTable: 16, + contentCode: 16, + }, + lineHeight: { + functionalDisplay: 82, + functionalPagetitle: 48, + functionalTitleLarge: 38, + functionalTitleMedium: 34, + functionalTitleSmall: 28, + functionalSubtitle: 28, + functionalBodyLarge: 22, + functionalBodyMedium: 20, + functionalBodySmall: 16, + functionalCaption: 14, + contentStatement: 68, + contentExpressiveLarge: 58, + contentExpressiveMedium: 44, + contentExpressiveSmall: 34, + contentH1: 44, + contentH2: 38, + contentH3: 34, + contentH4: 28, + contentH5: 24, + contentSubheadline: 22, + contentParagraphLarge: 34, + contentParagraphMedium: 28, + contentParagraphSmall: 20, + contentSubtext: 14, + contentTable: 22, + contentCode: 22, + }, + borderRadius: { base100: 4, base200: 8, base300: 12, base400: 16, base600: 24, base700: 28, circular: 9999 }, + spacing: { + componentBase50: 2, + componentBase100: 4, + componentBase150: 6, + componentBase200: 8, + componentBase250: 10, + componentBase300: 12, + componentBase400: 16, + componentBase500: 20, + componentBase600: 24, + componentBase700: 28, + componentBase800: 32, + layoutBase100: 8, + layoutBase200: 16, + layoutBase300: 24, + layoutBase400: 32, + layoutBase450: 36, + layoutBase500: 40, + layoutBase600: 48, + layoutBase700: 56, + layoutBase800: 64, + layoutBase1000: 80, + layoutBase1200: 96, + }, + strokeWidth: { thin: 1, thick: 2, thicker: 3, thickest: 4 }, + motion: { + durationBase50: 50, + durationBase100: 100, + durationBase200: 200, + durationBase300: 300, + durationBase500: 500, + durationBase1000: 1000, + easingFunctionalEnter, + easingFunctionalExit, + easingFunctionalTransition, + easingFunctionalLinear: [0, 0, 1, 1], + easingExpressiveEnter: easingFunctionalEnter, + easingExpressiveExit: easingFunctionalExit, + easingExpressiveTransition: easingFunctionalTransition, + }, +} as const; + +/** The x3 cool-tone defaults. Omitted interaction states are computed from rest. */ +export const coolFlexTokenInput: CompleteFlexTokenInput = { + ...sharedFlexTokenInput, + color: { + ...sharedFlexTokenInputColor, + surfaceNeutralFarther: ['#ebebeb', '#1b1b1b'], + surfaceNeutralFar: ['#f2f2f2', '#1f1f1f'], + surfaceNeutralNear: ['#fcfcfc', '#181818'], + surfaceNeutralNearer: [rgbffffff, '#292929'], + surfaceNeutralTranslucent: [rgbffffff80, rgb3c3c3c80], + backgroundNeutralHeavy: backgroundNeutralHeavy1, + backgroundNeutralLoud: backgroundNeutralLoud1, + backgroundNeutralSoft: backgroundNeutralSoft1, + backgroundNeutralSubtle: [rgb0000000d, rgbffffff14], + backgroundNeutralTransparent: backgroundNeutralTransparent1, + backgroundNeutralTranslucent: { rest: rest2, hover: ['#d8d8d88a', '#56565688'], pressed: ['#cacaca94', '#6d6d6d8f'] }, + backgroundBrandHeavy: backgroundNeutralHeavy1, + backgroundBrandLoud: backgroundNeutralLoud1, + backgroundBrandSoft: backgroundNeutralSoft1, + backgroundBrandSubtle: ['#0000000a', rgbffffff14], + backgroundBrandTransparent: backgroundNeutralTransparent1, + strokeNeutralHeavy: { rest: [rgb242424, rgbdedede], type: inverted }, + strokeNeutralLoud: backgroundNeutralLoud1, + strokeNeutralSoft: strokeNeutralSoft1, + strokeNeutralSubtle, + strokeNeutralTransparent: backgroundNeutralTransparent1, + strokeNeutralOnloud: strokeNeutralOnloud1, + strokeBrandLoud: backgroundNeutralLoud1, + strokeBrandSoft: strokeNeutralSoft1, + strokeBrandSubtle: strokeNeutralSubtle, + strokeBrandOnloud, + foregroundNeutralPrimary: [rgb000000db, '#ffffffde'], + foregroundNeutralSecondary: ['#000000a2', '#ffffffa1'], + foregroundNeutralTertiary: ['#00000090', rgbffffff80], + foregroundNeutralOnloud: strokeNeutralOnloud1, + foregroundBrandPrimary: [rgb242424, rgbdedede], + foregroundBrandOnloud: strokeNeutralOnloud1, + expressionAccentHeavy: [rgb242424, rgbffffff], + expressionAccentLoud: rest1, + expressionAccentSoft: backgroundNeutralSoft1, + expressionAccentSubtle: [rgb0000000d, rgbffffff14], + backgroundNeutralSubtleDisabled: backgroundNeutralDisabled, + }, +}; + +/** The x3 warm-tone defaults. Omitted interaction states are computed from rest. */ +export const warmFlexTokenInput: CompleteFlexTokenInput = { + ...sharedFlexTokenInput, + color: { + ...sharedFlexTokenInputColor, + surfaceNeutralFarther: ['#f0eae5', '#1e1916'], + surfaceNeutralFar: ['#faf4f0', '#231e1a'], + surfaceNeutralNear: ['#f6f1ec', '#1c1714'], + surfaceNeutralNearer: [rgbffffff, '#2e2823'], + surfaceNeutralTranslucent: [rgbffffff80, '#00000080'], + backgroundNeutralHeavy: backgroundNeutralHeavy2, + backgroundNeutralLoud: backgroundNeutralLoud2, + backgroundNeutralSoft: backgroundNeutralSoft2, + backgroundNeutralSubtle, + backgroundNeutralTransparent: backgroundNeutralTransparent2, + backgroundNeutralTranslucent: rest2, + backgroundBrandHeavy: backgroundNeutralHeavy2, + backgroundBrandLoud: backgroundNeutralLoud2, + backgroundBrandSoft: backgroundNeutralSoft2, + backgroundBrandSubtle: backgroundNeutralSubtle, + backgroundBrandTransparent: backgroundNeutralTransparent2, + strokeNeutralHeavy: { rest: [rgb28231e, '#e3dcd7'], type: inverted }, + strokeNeutralLoud, + strokeNeutralSoft: strokeNeutralSoft2, + strokeNeutralSubtle: backgroundNeutralSoft2, + strokeNeutralTransparent: backgroundNeutralTransparent2, + strokeNeutralOnloud: strokeNeutralOnloud2, + strokeBrandLoud: strokeNeutralLoud, + strokeBrandSoft: strokeNeutralSoft2, + strokeBrandSubtle: backgroundNeutralSoft2, + strokeBrandOnloud: strokeNeutralOnloud2, + foregroundNeutralPrimary, + foregroundNeutralSecondary: ['#190c00ab', '#fff2e8b5'], + foregroundNeutralTertiary: rest4, + foregroundNeutralOnloud: strokeNeutralOnloud2, + foregroundBrandPrimary: foregroundNeutralPrimary, + foregroundBrandOnloud: strokeNeutralOnloud2, + expressionAccentHeavy: [rgb28231e, rgbffffff], + expressionAccentLoud: rest4, + expressionAccentSoft: backgroundNeutralSoft2, + expressionAccentSubtle: backgroundNeutralSubtle, + backgroundNeutralSubtleDisabled: [rgb0000000d, '#ffffff1b'], + }, +}; diff --git a/packages/agentic/design/src/flex/defaults/defaultTokens.ts b/packages/agentic/design/src/flex/defaults/defaultTokens.ts new file mode 100644 index 00000000000..7dbc434388a --- /dev/null +++ b/packages/agentic/design/src/flex/defaults/defaultTokens.ts @@ -0,0 +1,29 @@ +import { defaultResolvedThemeAppearance } from '../../theming/appearance'; +import type { ColorTone } from '../../types/appearance.types'; +import { resolveFlexTokenDescription } from '../colors/interactionPolicy'; +import { createFlexTokenDescription } from '../flexTokenDescription'; +import type { FlexTokenDescription, FlexTokens } from '../tokens.types'; +import { coolFlexTokenInput, warmFlexTokenInput } from './defaultTokens.generated'; + +/** + * The x3 cool-tone default description. Interactive colors author only the + * hover and pressed states the interaction policy cannot reproduce. + */ +export const defaultFlexTokenDescription: FlexTokenDescription = createFlexTokenDescription(coolFlexTokenInput); + +let warmFlexTokenDescription: FlexTokenDescription | undefined; + +/** The x3 default description for a color tone. */ +export function getDefaultFlexTokenDescription(colorTone: ColorTone): FlexTokenDescription { + if (colorTone === 'warm') { + warmFlexTokenDescription ??= createFlexTokenDescription(warmFlexTokenInput); + return warmFlexTokenDescription; + } + return defaultFlexTokenDescription; +} + +/** + * Default resolved Flex tokens for the default appearance. Omitted interaction + * states are computed on first read. + */ +export const defaultFlexTokens: FlexTokens = resolveFlexTokenDescription(defaultFlexTokenDescription, defaultResolvedThemeAppearance); diff --git a/packages/agentic/design/src/flex/defaults/generateDefaults.test.ts b/packages/agentic/design/src/flex/defaults/generateDefaults.test.ts new file mode 100644 index 00000000000..5f29de3a26d --- /dev/null +++ b/packages/agentic/design/src/flex/defaults/generateDefaults.test.ts @@ -0,0 +1,16 @@ +import { spawnSync } from 'node:child_process'; +import path from 'node:path'; +import * as nodeModule from 'node:module'; + +const generatorPath = path.resolve(__dirname, '../../../scripts/flex-defaults/generate-defaults.mjs'); + +// The generator loads TypeScript sources through module hooks and type stripping (Node 22.18+). +const generatorSupported = typeof nodeModule.registerHooks === 'function' && Boolean(process.features.typescript); + +describe('generated Flex defaults', () => { + (generatorSupported ? it : it.skip)('match the pinned x3 sources and mapping', () => { + const result = spawnSync(process.execPath, [generatorPath, '--check'], { encoding: 'utf8' }); + + expect({ status: result.status, stderr: result.stderr }).toEqual({ status: 0, stderr: '' }); + }); +}); diff --git a/packages/agentic/design/src/flex/defaults/x3Defaults.test.ts b/packages/agentic/design/src/flex/defaults/x3Defaults.test.ts new file mode 100644 index 00000000000..27384fa8ffe --- /dev/null +++ b/packages/agentic/design/src/flex/defaults/x3Defaults.test.ts @@ -0,0 +1,273 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import { fontFamilyBase, fontFamilyMonospace } from '../../tokens/global.generated'; +import type { ColorTone, NormalizedThemeAppearance } from '../../types/appearance.types'; +import { selectColorEntry } from '../colors/flexColor'; +import { deriveInteractionColor, resolveFlexTokenDescription } from '../colors/interactionPolicy'; +import { isInteractiveColorToken } from '../colors/interactiveTokens'; +import type { FlexShadow, FlexTokenDescription, FlexTokens } from '../tokens.types'; +import { getDefaultFlexTokenDescription } from './defaultTokens'; + +type MappingEntry = { genericSource?: string }; +type MappingChecks = { + loadMappingInputs(): { mapping: unknown; supportedTypePaths: Set<string>; unsupportedTypePaths: Set<string> }; + createMappingProjections(mapping: unknown, supportedTypePaths: Set<string>): { mappingEntries: Map<string, MappingEntry> }; +}; + +const { createMappingProjections, loadMappingInputs } = jest.requireActual<MappingChecks>( + '../../../scripts/token-mappings/check-mappings.cjs', +); +const mappingInputs = loadMappingInputs(); +const { mappingEntries } = createMappingProjections(mappingInputs.mapping, mappingInputs.supportedTypePaths); + +// These checks read the pinned split light and dark snapshots, not the adaptive +// sources the generator reads, and convert values without generator code. +const fixtureRoot = path.resolve(__dirname, '../../../scripts/token-mappings/__fixtures__/x3'); +const toneDirectories: Record<ColorTone, string> = { cool: '', warm: 'warm' }; +const tones = ['cool', 'warm'] as const; +const schemes = ['light', 'dark'] as const; +type Scheme = (typeof schemes)[number]; + +// Algorithm parameters the interaction engine owns; they are not Flex destinations. +const engineParameters = [ + '--alpha-hover', + '--alpha-press', + '--interaction-inverse-hover', + '--interaction-inverse-pressed', + '--interaction-standard-hover', + '--interaction-standard-pressed', + '--lightness-hover', + '--lightness-press', +]; + +// x3 variable font weights and the static native weights that represent them. +const nativeFontWeights: Record<string, string> = { '420': '400', '550': '500', '600': '600', '625': '700' }; + +type Sources = { semantic: Map<string, string>; fallback: Map<string, string> }; + +function readDeclarations(file: string): Map<string, string> { + const declarations = new Map<string, string>(); + for (const line of fs.readFileSync(file, 'utf8').split('\n')) { + const text = line.trim(); + if (!text.startsWith('--')) { + continue; + } + if (!text.endsWith(';')) { + throw new Error(`Expected a single-line declaration in ${file}: ${text}`); + } + const colon = text.indexOf(':'); + declarations.set(text.slice(0, colon), text.slice(colon + 1, -1).trim()); + } + return declarations; +} + +const sourceCache = new Map<string, Sources>(); + +function readSources(tone: ColorTone, scheme: Scheme): Sources { + const key = `${tone}:${scheme}`; + let sources = sourceCache.get(key); + if (!sources) { + const directory = path.join(fixtureRoot, toneDirectories[tone]); + sources = { + semantic: readDeclarations(path.join(directory, `semantic-${scheme}.css`)), + fallback: readDeclarations(path.join(directory, `interaction-fallback-${scheme}.css`)), + }; + sourceCache.set(key, sources); + } + return sources; +} + +function genericSource(tokenPath: string): string { + const source = mappingEntries.get(tokenPath)?.genericSource; + if (!source) { + throw new Error(`${tokenPath} has no generic source.`); + } + return source; +} + +function read(declarations: Map<string, string>, name: string): string { + const value = declarations.get(name); + if (value === undefined) { + throw new Error(`${name} is not declared.`); + } + return value; +} + +function normalizeColor(value: unknown): string { + if (typeof value !== 'string' || !/^#(?:[0-9a-f]{6}|[0-9a-f]{8})$/i.test(value)) { + return `<not a hex color: ${String(value)}>`; + } + const hex = value.toLowerCase(); + return hex.length === 7 ? `${hex}ff` : hex; +} + +function pixels(value: string): number { + if (value.endsWith('rem')) { + return Number(value.slice(0, -3)) * 16; + } + if (value.endsWith('px')) { + return Number(value.slice(0, -2)); + } + throw new Error(`Expected px or rem: ${value}`); +} + +function functionArguments(value: string, name: string): string[] { + if (!value.startsWith(`${name}(`) || !value.endsWith(')')) { + throw new Error(`Expected ${name}(): ${value}`); + } + return value + .slice(name.length + 1, -1) + .split(',') + .map((part) => part.trim()); +} + +// CSS round(P%, Spx) against the role's font size; ties round up, as Math.round does. +function lineHeight(value: string, fontSize: number): number { + if (value.endsWith('px')) { + return pixels(value); + } + const [percent, step] = functionArguments(value, 'round'); + if (!percent.endsWith('%')) { + throw new Error(`Expected a percentage line height: ${value}`); + } + const interval = pixels(step); + return Math.round((fontSize * Number(percent.slice(0, -1))) / 100 / interval) * interval; +} + +function duration(value: string): number { + if (value.endsWith('ms')) { + return Number(value.slice(0, -2)); + } + if (value.endsWith('s')) { + return Number(value.slice(0, -1)) * 1000; + } + throw new Error(`Expected a duration: ${value}`); +} + +function fontFamily(value: string): unknown { + const generic = value.split(',').at(-1)?.trim(); + if (generic === 'monospace') { + return fontFamilyMonospace; + } + if (generic === 'sans-serif' || generic === 'serif') { + return fontFamilyBase; + } + throw new Error(`Unexpected generic family: ${value}`); +} + +// The fallback stylesheets resolve shadow colors to hex for non-OKLCH engines. +function shadow(value: string): FlexShadow { + return value.split(',').map((layer) => { + const [x, y, blur, color] = layer.trim().split(/\s+/); + return { x: pixels(x), y: pixels(y), blur: pixels(blur), color }; + }); +} + +function expectedValue(group: string, token: string, sources: Sources): unknown { + const source = read(sources.semantic, genericSource(`${group}.${token}`)); + switch (group) { + case 'fontWeight': + return nativeFontWeights[source] ?? `<no native weight for ${source}>`; + case 'fontFamily': + return fontFamily(source); + case 'lineHeight': + return lineHeight(source, pixels(read(sources.semantic, genericSource(`fontSize.${token}`)))); + case 'motion': + return source.startsWith('cubic-bezier(') ? functionArguments(source, 'cubic-bezier').map(Number) : duration(source); + case 'shadow': + return shadow(read(sources.fallback, genericSource(`shadow.${token}`))); + default: + return pixels(source); + } +} + +function appearance(colorTone: ColorTone, colorScheme: Scheme): NormalizedThemeAppearance { + return { colorScheme, contrast: 'standard', interfaceLevel: 'base', colorTone }; +} + +function colorMismatches(tokens: FlexTokens, sources: Sources): string[] { + const mismatches: string[] = []; + for (const [token, color] of Object.entries(tokens.color)) { + const restSource = genericSource(`color.${token}.rest`); + const expectedRest = normalizeColor(read(sources.semantic, restSource)); + if (normalizeColor(color.rest) !== expectedRest) { + mismatches.push(`color.${token}.rest: ${String(color.rest)} != ${expectedRest}`); + } + for (const state of ['hover', 'pressed'] as const) { + if (!isInteractiveColorToken(token)) { + if (color[state] !== color.rest || sources.fallback.has(`${restSource}-${state}`)) { + mismatches.push(`color.${token}.${state}: a non-interactive state must equal rest`); + } + continue; + } + const expected = normalizeColor(read(sources.fallback, genericSource(`color.${token}.${state}`))); + if (normalizeColor(color[state]) !== expected) { + mismatches.push(`color.${token}.${state}: ${String(color[state])} != ${expected}`); + } + } + } + return mismatches; +} + +function explicitStates(description: FlexTokenDescription): [token: string, state: 'hover' | 'pressed'][] { + return Object.entries(description.color).flatMap(([token, color]) => + (['hover', 'pressed'] as const).filter((state) => color[state] !== undefined).map((state) => [token, state] as [string, typeof state]), + ); +} + +describe('x3 Flex defaults', () => { + describe.each(tones)('%s tone', (tone) => { + const description = getDefaultFlexTokenDescription(tone); + + it.each(schemes)('resolves every %s color to the pinned source values', (scheme) => { + const tokens = resolveFlexTokenDescription(description, appearance(tone, scheme)); + + expect(colorMismatches(tokens, readSources(tone, scheme))).toEqual([]); + }); + + it.each(schemes)('resolves every %s non-color value to the pinned source values', (scheme) => { + const tokens = resolveFlexTokenDescription(description, appearance(tone, scheme)); + const sources = readSources(tone, scheme); + + for (const [group, values] of Object.entries(tokens)) { + if (group === 'color') { + continue; + } + for (const [token, value] of Object.entries(values as Record<string, unknown>)) { + expect([`${group}.${token}`, value]).toEqual([`${group}.${token}`, expectedValue(group, token, sources)]); + } + } + }); + + it('authors an interaction state only when the policy cannot reproduce its source', () => { + for (const [token, state] of explicitStates(description)) { + const color = description.color[token as keyof typeof description.color]; + const direction = color.type === 'inverted' ? 'inverted' : 'standard'; + const reproduced = schemes.every((scheme) => { + const resolvedAppearance = appearance(tone, scheme); + const rest = selectColorEntry(color.rest, resolvedAppearance); + const derived = deriveInteractionColor( + rest, + token as Parameters<typeof deriveInteractionColor>[1], + state, + direction, + resolvedAppearance, + ); + return normalizeColor(derived) === normalizeColor(selectColorEntry(color[state] as never, resolvedAppearance)); + }); + + expect([token, state, reproduced]).toEqual([token, state, false]); + } + }); + + it.each(schemes)('maps every %s source variable to a Flex destination', (scheme) => { + const declared = new Set([...mappingEntries.values()].map((entry) => entry.genericSource)); + const { semantic, fallback } = readSources(tone, scheme); + const names = [...semantic.keys(), ...fallback.keys()]; + + expect(names.filter((name) => name.startsWith('--gnrc-') && !declared.has(name))).toEqual([]); + expect([...new Set(names.filter((name) => !name.startsWith('--gnrc-')))].sort()).toEqual(engineParameters); + }); + }); +}); diff --git a/packages/agentic/design/src/flex/flexShadow.test.ts b/packages/agentic/design/src/flex/flexShadow.test.ts new file mode 100644 index 00000000000..78422bce38c --- /dev/null +++ b/packages/agentic/design/src/flex/flexShadow.test.ts @@ -0,0 +1,109 @@ +import { defaultFlexTokenDescription } from './defaults/defaultTokens'; +import { assertShadowEntries, mergeShadowEntries, resolveShadowEntries, selectShadowEntry } from './flexShadow'; +import { mergeFlexTokenDescription } from './flexTokenDescription'; +import type { FlexShadow, FlexShadowEntry, SemanticShadowEntries } from './tokens.types'; + +const contour = { x: 0, y: 0, blur: 2, color: '#0000001a' }; +const key = { x: 0, y: 2, blur: 4, color: '#00000024' }; +const lightShadow: FlexShadow = [contour, key]; +const darkShadow: FlexShadow = [ + { ...contour, color: '#00000033' }, + { ...key, color: '#00000048' }, +]; + +describe('selectShadowEntry', () => { + it('uses one shadow for every scheme', () => { + expect(selectShadowEntry(lightShadow, { colorScheme: 'light' })).toBe(lightShadow); + expect(selectShadowEntry(lightShadow, { colorScheme: 'dark' })).toBe(lightShadow); + }); + + it('selects a light/dark tuple by scheme', () => { + const entry: FlexShadowEntry = [lightShadow, darkShadow]; + + expect(selectShadowEntry(entry, { colorScheme: 'light' })).toBe(lightShadow); + expect(selectShadowEntry(entry, { colorScheme: 'dark' })).toBe(darkShadow); + }); + + it('treats an empty shadow as one shadow with no layers', () => { + expect(selectShadowEntry([], { colorScheme: 'dark' })).toEqual([]); + }); +}); + +describe('resolveShadowEntries', () => { + it('selects every entry for the scheme and freezes the result', () => { + const resolved = resolveShadowEntries(defaultFlexTokenDescription.shadow, { colorScheme: 'dark' }); + + expect(Object.isFrozen(resolved)).toBe(true); + expect(Object.keys(resolved)).toEqual(Object.keys(defaultFlexTokenDescription.shadow)); + for (const [name, entry] of Object.entries(defaultFlexTokenDescription.shadow)) { + expect(resolved[name as keyof typeof resolved]).toBe(selectShadowEntry(entry, { colorScheme: 'dark' })); + } + }); +}); + +describe('assertShadowEntries', () => { + it('accepts layered shadows, tuples, and undefined entries', () => { + expect(() => assertShadowEntries({ low: lightShadow, high: [lightShadow, darkShadow], higher: undefined })).not.toThrow(); + }); + + it.each([ + ['an array', []], + ['null', null], + ['a string', 'low'], + ])('rejects %s as the shadow group', (_label, shadows) => { + expect(() => assertShadowEntries(shadows)).toThrow('Flex shadow overrides must be an object keyed by semantic shadow name.'); + }); + + it.each([ + ['a layer without a color', [{ x: 0, y: 0, blur: 2 }]], + ['a layer with a string offset', [{ x: '0px', y: 0, blur: 2, color: '#000000' }]], + ['a single layer object', contour], + ['a three-shadow tuple', [lightShadow, darkShadow, lightShadow]], + ])('rejects %s', (_label, value) => { + expect(() => assertShadowEntries({ low: value })).toThrow( + 'shadow.low must be an array of { x, y, blur, color } shadow layers or a [light, dark] tuple of them.', + ); + }); + + it('explains how to author a legacy { ambient, key } shadow', () => { + expect(() => assertShadowEntries({ low: { ambient: contour, key } })).toThrow( + 'Author a legacy { ambient, key } shadow as [ambient, key].', + ); + }); +}); + +describe('mergeShadowEntries', () => { + const base = defaultFlexTokenDescription.shadow; + + it('replaces each entry atomically', () => { + const merged = mergeShadowEntries(base, { low: lightShadow }); + + expect(merged.low).toBe(lightShadow); + expect(merged.high).toBe(base.high); + expect(Object.isFrozen(merged)).toBe(true); + }); + + it('keeps the base for undefined and unchanged entries', () => { + expect(mergeShadowEntries(base, { low: undefined, high: base.high })).toBe(base); + }); + + it('validates overrides', () => { + expect(() => mergeShadowEntries(base, { low: { ambient: contour, key } })).toThrow('shadow.low'); + }); +}); + +describe('mergeFlexTokenDescription shadows', () => { + it('replaces a light/dark tuple with one shadow instead of merging layers', () => { + const merged = mergeFlexTokenDescription(defaultFlexTokenDescription, { shadow: { lowest: [contour] } }); + + expect(merged.shadow.lowest).toEqual([contour]); + expect(merged.shadow.lower).toBe(defaultFlexTokenDescription.shadow.lower); + expect(merged.color).toBe(defaultFlexTokenDescription.color); + }); + + it('does not remove a shadow for an undefined override', () => { + const shadow: Partial<SemanticShadowEntries> = { lowest: undefined }; + + expect(mergeFlexTokenDescription(defaultFlexTokenDescription, { shadow })).toBe(defaultFlexTokenDescription); + }); +}); diff --git a/packages/agentic/design/src/flex/flexShadow.ts b/packages/agentic/design/src/flex/flexShadow.ts new file mode 100644 index 00000000000..d57eca61cb6 --- /dev/null +++ b/packages/agentic/design/src/flex/flexShadow.ts @@ -0,0 +1,84 @@ +import type { ColorSchemeSelector } from './colors/flexColor'; +import type { FlexShadow, FlexShadowEntry, SemanticShadowEntries, SemanticShadows } from './tokens.types'; + +function isShadowLayer(value: unknown): boolean { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return false; + } + const { x, y, blur, color } = value as Record<string, unknown>; + return typeof x === 'number' && typeof y === 'number' && typeof blur === 'number' && color !== undefined && color !== null; +} + +function isFlexShadow(value: unknown): value is FlexShadow { + return Array.isArray(value) && value.every(isShadowLayer); +} + +function isShadowTuple(entry: FlexShadowEntry): entry is readonly [light: FlexShadow, dark: FlexShadow] { + return Array.isArray(entry[0]); +} + +/** + * Throw unless a value is a layered shadow or a light/dark tuple of layered + * shadows. + */ +function assertShadowEntry(value: unknown, path: string): asserts value is FlexShadowEntry { + if (isFlexShadow(value) || (Array.isArray(value) && value.length === 2 && isFlexShadow(value[0]) && isFlexShadow(value[1]))) { + return; + } + const legacy = typeof value === 'object' && value !== null && ('ambient' in value || 'key' in value); + throw new TypeError( + `${path} must be an array of { x, y, blur, color } shadow layers or a [light, dark] tuple of them.` + + (legacy ? ' Author a legacy { ambient, key } shadow as [ambient, key].' : ''), + ); +} + +/** + * Validate authored shadow entries. `undefined` entries are not overrides. + * @internal + */ +export function assertShadowEntries(shadows: unknown): asserts shadows is Partial<SemanticShadowEntries> { + if (typeof shadows !== 'object' || shadows === null || Array.isArray(shadows)) { + throw new TypeError('Flex shadow overrides must be an object keyed by semantic shadow name.'); + } + for (const [name, value] of Object.entries(shadows)) { + if (value !== undefined) { + assertShadowEntry(value, `shadow.${name}`); + } + } +} + +/** + * Replace each overridden shadow atomically. `undefined` entries are not + * overrides, so they keep the base shadow. + * @internal + */ +export function mergeShadowEntries(base: SemanticShadowEntries, shadows: unknown): SemanticShadowEntries { + assertShadowEntries(shadows); + let merged: Record<string, FlexShadowEntry> | undefined; + for (const [name, value] of Object.entries(shadows)) { + if (value !== undefined && value !== (base as Record<string, FlexShadowEntry>)[name]) { + merged ??= { ...base }; + merged[name] = value; + } + } + return merged ? (Object.freeze(merged) as SemanticShadowEntries) : base; +} + +/** + * Select the shadow an authored entry uses for an appearance's color scheme. + */ +export function selectShadowEntry(entry: FlexShadowEntry, appearance: ColorSchemeSelector): FlexShadow { + return isShadowTuple(entry) ? entry[appearance.colorScheme === 'dark' ? 1 : 0] : entry; +} + +/** + * Select every authored shadow for an appearance. + * @internal + */ +export function resolveShadowEntries(shadows: SemanticShadowEntries, appearance: ColorSchemeSelector): SemanticShadows { + const resolved: Record<string, FlexShadow> = {}; + for (const name of Object.keys(shadows)) { + resolved[name] = selectShadowEntry((shadows as Record<string, FlexShadowEntry>)[name], appearance); + } + return Object.freeze(resolved) as SemanticShadows; +} diff --git a/packages/agentic/design/src/flex/flexThemeReference.test.ts b/packages/agentic/design/src/flex/flexThemeReference.test.ts new file mode 100644 index 00000000000..e4959c14768 --- /dev/null +++ b/packages/agentic/design/src/flex/flexThemeReference.test.ts @@ -0,0 +1,295 @@ +import { PlatformColor } from 'react-native'; +import type { ColorValue } from 'react-native'; + +import { defaultResolvedThemeAppearance } from '../theming/appearance'; +import { flexColor, selectColorEntry } from './colors/flexColor'; +import { deriveInteractionColor, resolveFlexTokenDescription } from './colors/interactionPolicy'; +import { defaultFlexTokenDescription, defaultFlexTokens, getDefaultFlexTokenDescription } from './defaults/defaultTokens'; +import { FlexThemeReference } from './flexThemeReference'; +import type { FlexThemeDescription } from './themeState.types'; +import type { FlexTokenDescription, PartialFlexTokens } from './tokens.types'; + +const darkAppearance = { + colorScheme: 'dark', + contrast: 'standard', + interfaceLevel: 'base', +} as const; + +describe('FlexThemeReference', () => { + it('resolves one stable token object per appearance', () => { + const reference = new FlexThemeReference({}, (_description, appearance) => ({ + color: { + backgroundBrandHeavy: appearance.colorScheme === 'dark' ? '#111111' : '#eeeeee', + }, + })); + + const light = reference.resolveFlexTokens(defaultResolvedThemeAppearance); + const lightAgain = reference.resolveFlexTokens(defaultResolvedThemeAppearance); + const dark = reference.resolveFlexTokens(darkAppearance); + + expect(lightAgain).toBe(light); + expect(dark).not.toBe(light); + expect(light.color.backgroundBrandHeavy.rest).toBe('#eeeeee'); + expect(dark.color.backgroundBrandHeavy.rest).toBe('#111111'); + }); + + it('replaces all appearance identities after invalidation', () => { + const reference = new FlexThemeReference(); + const before = reference.resolveFlexTokens(defaultResolvedThemeAppearance); + + reference.invalidate(); + + expect(reference.revision).toBe(1); + expect(reference.resolveFlexTokens(defaultResolvedThemeAppearance)).not.toBe(before); + }); + + it('updates recipes and notifies subscribed consumers', () => { + const reference = new FlexThemeReference(); + const listener = jest.fn(); + reference.addOnThemeChanged(listener); + + reference.update({ color: { backgroundBrandHeavy: '#123456' } }); + + expect(listener).toHaveBeenCalledTimes(1); + expect(reference.resolveFlexTokens(defaultResolvedThemeAppearance).color.backgroundBrandHeavy.rest).toBe('#123456'); + }); + + it('inherits source configuration and composes legacy fallbacks from a parent reference', () => { + const appearanceSource = { + getSnapshot: () => defaultResolvedThemeAppearance, + subscribe: () => () => undefined, + }; + const parent = new FlexThemeReference({ + appearance: { colorScheme: 'dark' }, + fallbackAppearance: darkAppearance, + appearanceSource, + legacyFallback: { components: { ParentComponent: { tokens: { parent: true } } } }, + }); + const child = new FlexThemeReference({ + base: parent, + legacyFallback: { components: { ChildComponent: { tokens: { child: true } } } }, + }); + + expect(child.appearanceOptions).toBe(parent.appearanceOptions); + expect(child.fallbackAppearance).toBe(parent.fallbackAppearance); + expect(child.appearanceSource).toBe(appearanceSource); + expect(child.resolveLegacyFallback(darkAppearance)?.components).toEqual({ + ParentComponent: { tokens: { parent: true } }, + ChildComponent: { tokens: { child: true } }, + }); + }); + + it('synchronizes a parent invalidation before exposing its revision', () => { + const parent = new FlexThemeReference(); + const child = new FlexThemeReference({ base: parent }); + const initial = child.resolveFlexTokens(defaultResolvedThemeAppearance); + + parent.invalidate(); + + expect(child.revision).toBe(1); + expect(child.resolveFlexTokens(defaultResolvedThemeAppearance)).not.toBe(initial); + }); +}); + +describe('FlexThemeReference color tone', () => { + const lightAppearance = { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base' } as const; + + it('passes a concrete tone to bases and recipes and keys warm separately', () => { + const tones: string[] = []; + const reference = new FlexThemeReference( + { + base: (appearance) => { + tones.push(`base:${appearance.colorTone}`); + return {}; + }, + }, + (_description, appearance) => { + tones.push(`recipe:${appearance.colorTone}`); + return {}; + }, + ); + const omitted = reference.resolveFlexTokens(lightAppearance); + + expect(reference.resolveFlexTokens({ ...lightAppearance, colorTone: 'cool' })).toBe(omitted); + expect(reference.resolveFlexTokens({ ...lightAppearance, colorTone: 'warm' })).not.toBe(omitted); + expect(tones).toEqual(['base:cool', 'recipe:cool', 'base:warm', 'recipe:warm']); + }); + + it('resolves the default description for each tone and scheme', () => { + const reference = new FlexThemeReference(); + + for (const colorTone of ['cool', 'warm'] as const) { + for (const colorScheme of ['light', 'dark'] as const) { + const appearance = { ...lightAppearance, colorScheme, colorTone }; + const expected = resolveFlexTokenDescription(getDefaultFlexTokenDescription(colorTone), appearance); + expect(reference.resolveFlexTokens(appearance).color).toEqual(expected.color); + } + } + expect(reference.resolveFlexTokens(lightAppearance).color).toEqual(defaultFlexTokens.color); + expect(reference.resolveFlexTokens({ ...lightAppearance, colorTone: 'warm' }).color.surfaceNeutralFarther.rest).toBe('#f0eae5'); + expect(reference.resolveFlexTokens(darkAppearance).color.surfaceNeutralFarther.rest).toBe('#1b1b1b'); + }); + + it('shares the warm default description when nothing is authored', () => { + const descriptions: FlexTokenDescription[] = []; + const reference = new FlexThemeReference({}, (description) => { + descriptions.push(description); + return {}; + }); + reference.resolveFlexTokens({ ...lightAppearance, colorTone: 'warm' }); + + expect(descriptions[0]).toBe(getDefaultFlexTokenDescription('warm')); + }); +}); + +describe('FlexThemeReference theme description base', () => { + const warmTheme: FlexThemeDescription = { tokens: getDefaultFlexTokenDescription('warm'), colorTone: 'warm' }; + + it('replaces the package defaults for every requested tone', () => { + const descriptions: FlexTokenDescription[] = []; + const reference = new FlexThemeReference({ base: warmTheme }, (description) => { + descriptions.push(description); + return {}; + }); + + expect(reference.resolveFlexTokens({ ...defaultResolvedThemeAppearance, colorTone: 'cool' }).color.surfaceNeutralFarther.rest).toBe( + '#f0eae5', + ); + expect(descriptions[0]).toBe(warmTheme.tokens); + }); + + it('uses the description tone unless the appearance option sets one', () => { + expect(new FlexThemeReference({ base: warmTheme, appearance: { colorScheme: 'dark' } }).appearanceOptions).toEqual({ + colorScheme: 'dark', + colorTone: 'warm', + }); + expect(new FlexThemeReference({ base: warmTheme, appearance: { colorTone: 'cool' } }).appearanceOptions).toEqual({ colorTone: 'cool' }); + expect(new FlexThemeReference({ base: { tokens: warmTheme.tokens } }).appearanceOptions).toBeUndefined(); + }); +}); + +describe('FlexThemeReference interaction derivation', () => { + const omitInteraction = (rest: ColorValue): PartialFlexTokens => ({ color: { backgroundNeutralTranslucent: rest } }); + + it('derives omitted states from rest with the appearance tone', () => { + const reference = new FlexThemeReference({}, omitInteraction('#e9e9e980')); + const cool = reference.resolveFlexTokens(defaultResolvedThemeAppearance).color; + const warm = reference.resolveFlexTokens({ ...defaultResolvedThemeAppearance, colorTone: 'warm' }).color; + + expect(cool.backgroundNeutralTranslucent.hover).toBe('#dfdfdf8a'); + expect(cool.backgroundNeutralTranslucent.pressed).toBe('#d5d5d594'); + expect(warm.backgroundNeutralTranslucent.hover).toBe('#dcdcd68a'); + expect(warm.backgroundNeutralTranslucent.pressed).toBe('#d2cfc894'); + }); + + it('keeps authored interaction values', () => { + const reference = new FlexThemeReference( + {}, + { + color: { backgroundNeutralTranslucent: { rest: '#e9e9e980', hover: '#123456' } }, + }, + ); + const colors = reference.resolveFlexTokens(defaultResolvedThemeAppearance).color; + + expect(colors.backgroundNeutralTranslucent.hover).toBe('#123456'); + expect(colors.backgroundNeutralTranslucent.pressed).toBe('#d5d5d594'); + }); + + it('falls back to the same rest value when it cannot be derived', () => { + const rest = PlatformColor('windowBackgroundColor'); + const reference = new FlexThemeReference({}, omitInteraction(rest)); + const colors = reference.resolveFlexTokens({ ...defaultResolvedThemeAppearance, colorTone: 'warm' }).color; + + expect(colors.backgroundNeutralTranslucent.rest).toBe(rest); + expect(colors.backgroundNeutralTranslucent.hover).toBe(rest); + expect(colors.backgroundNeutralTranslucent.pressed).toBe(rest); + }); + + it('uses rest in high contrast', () => { + const reference = new FlexThemeReference({}, omitInteraction('#e9e9e980')); + const colors = reference.resolveFlexTokens({ ...defaultResolvedThemeAppearance, contrast: 'highContrast' }).color; + + expect(colors.backgroundNeutralTranslucent.hover).toBe('#e9e9e980'); + expect(colors.backgroundNeutralTranslucent.pressed).toBe('#e9e9e980'); + }); + + it('replaces a color atomically so earlier explicit states do not leak', () => { + const parent = new FlexThemeReference({ + base: { color: { backgroundBrandHeavy: { rest: '#0f6cbd', hover: '#111111', pressed: '#222222' } } }, + }); + const child = new FlexThemeReference({ base: parent }, { color: { backgroundBrandHeavy: flexColor('#0f6cbd', 'inverted') } }); + const color = child.resolveFlexTokens(defaultResolvedThemeAppearance).color.backgroundBrandHeavy; + + expect(parent.resolveFlexTokens(defaultResolvedThemeAppearance).color.backgroundBrandHeavy.hover).toBe('#111111'); + expect(color.hover).toBe( + deriveInteractionColor('#0f6cbd', 'backgroundBrandHeavy', 'hover', 'inverted', defaultResolvedThemeAppearance), + ); + expect(color.hover).not.toBe('#111111'); + }); + + it('derives a plain override as standard unless flexColor marks it inverted', () => { + const plain = new FlexThemeReference({}, { color: { backgroundBrandHeavy: '#0f6cbd' } }); + const inverted = new FlexThemeReference({}, { color: { backgroundBrandHeavy: flexColor('#0f6cbd', 'inverted') } }); + const appearance = { ...defaultResolvedThemeAppearance, colorTone: 'cool' } as const; + + expect(plain.resolveFlexTokens(appearance).color.backgroundBrandHeavy.hover).toBe( + deriveInteractionColor('#0f6cbd', 'backgroundBrandHeavy', 'hover', 'standard', appearance), + ); + expect(inverted.resolveFlexTokens(appearance).color.backgroundBrandHeavy.hover).toBe( + deriveInteractionColor('#0f6cbd', 'backgroundBrandHeavy', 'hover', 'inverted', appearance), + ); + }); + + it('selects light and dark tuple entries for each scheme', () => { + const reference = new FlexThemeReference({ + base: { color: { surfaceNeutralFarther: { rest: ['#fafafa', '#1f1f1f'], hover: ['#f0f0f0', '#292929'] } } }, + }); + + expect(reference.resolveFlexTokens(defaultResolvedThemeAppearance).color.surfaceNeutralFarther).toMatchObject({ + rest: '#fafafa', + hover: '#f0f0f0', + }); + expect(reference.resolveFlexTokens(darkAppearance).color.surfaceNeutralFarther).toMatchObject({ rest: '#1f1f1f', hover: '#292929' }); + }); +}); + +describe('FlexThemeReference authored descriptions', () => { + it('passes recipes the accumulated authored description', () => { + const descriptions: FlexTokenDescription[] = []; + const reference = new FlexThemeReference( + { base: { color: { surfaceNeutralFarther: ['#fafafa', '#1f1f1f'] } } }, + (description, appearance) => { + descriptions.push(description); + return { color: { foregroundNeutralPrimary: selectColorEntry(description.color.surfaceNeutralFarther.rest, appearance) } }; + }, + ); + + expect(reference.resolveFlexTokens(darkAppearance).color.foregroundNeutralPrimary.rest).toBe('#1f1f1f'); + expect(descriptions[0].color.backgroundBrandHeavy).toBe(defaultFlexTokenDescription.color.backgroundBrandHeavy); + expect(descriptions[0].color.backgroundBrandHeavy.type).toBe('inverted'); + expect(Object.isFrozen(descriptions[0].color.surfaceNeutralFarther)).toBe(true); + }); + + it('shares the default description when nothing is authored', () => { + const descriptions: FlexTokenDescription[] = []; + const reference = new FlexThemeReference({}, (description) => { + descriptions.push(description); + return {}; + }); + reference.resolveFlexTokens(defaultResolvedThemeAppearance); + + expect(descriptions[0]).toBe(defaultFlexTokenDescription); + }); + + it('rejects resolved tokens as authored input', () => { + const reference = new FlexThemeReference({}, defaultFlexTokens as unknown as PartialFlexTokens); + + expect(() => reference.resolveFlexTokens(defaultResolvedThemeAppearance)).toThrow('resolved InteractiveColor'); + }); + + it('rejects the removed color state maps with a migration message', () => { + const reference = new FlexThemeReference({}, { color: { hover: { backgroundBrandHeavy: '#123456' } } } as unknown as PartialFlexTokens); + + expect(() => reference.resolveFlexTokens(defaultResolvedThemeAppearance)).toThrow('color.hover maps are no longer supported'); + }); +}); diff --git a/packages/agentic/design/src/flex/flexThemeReference.ts b/packages/agentic/design/src/flex/flexThemeReference.ts new file mode 100644 index 00000000000..729c3f05764 --- /dev/null +++ b/packages/agentic/design/src/flex/flexThemeReference.ts @@ -0,0 +1,180 @@ +import { immutableMerge } from '@fluentui-react-native/framework-base'; + +import { getDefaultFlexTokenDescription } from './defaults/defaultTokens'; +import { mergeFlexTokenDescription } from './flexTokenDescription'; +import type { FlexThemeDescription } from './themeState.types'; +import type { FlexTokenDescription, FlexTokens, PartialFlexTokens } from './tokens.types'; +import { resolveFlexTokenDescription } from './colors/interactionPolicy'; +import { internResolvedThemeAppearance, themeAppearanceKey } from '../theming/appearance'; +import type { + NormalizedThemeAppearance, + ResolvedThemeAppearance, + ThemeAppearanceOptions, + ThemeAppearanceSource, +} from '../types/appearance.types'; +import type { FlexThemeSource, OnThemeChange } from '../theming/themeSource'; +import type { PartialTheme, Theme } from '../fluent/types/Theme.types'; + +/** + * Authored base tokens layered over the package defaults. Resolved + * `FlexTokens` are appearance-bound outputs and are not accepted. + */ +export type FlexThemeInput = PartialFlexTokens | ((appearance: Readonly<NormalizedThemeAppearance>) => PartialFlexTokens); + +/** + * Authored overrides, or a function of the accumulated authored description + * and the appearance that returns overrides. Use `selectColorEntry` to read an + * appearance-specific authored color. + */ +export type FlexThemeRecipe = + | PartialFlexTokens + | ((description: FlexTokenDescription, appearance: Readonly<NormalizedThemeAppearance>) => PartialFlexTokens); + +export type LegacyThemeFallback = Theme | PartialTheme | ((appearance: Readonly<NormalizedThemeAppearance>) => Theme | PartialTheme); + +// No token group is named `tokens`, so its presence identifies a complete description. +function isFlexThemeDescription(base: FlexThemeReferenceOptions['base']): base is FlexThemeDescription { + return typeof base === 'object' && base !== null && !(base instanceof FlexThemeReference) && 'tokens' in base; +} + +export interface FlexThemeReferenceOptions { + /** + * Authored tokens layered over the package defaults, a complete + * `FlexThemeDescription` that replaces them, or a parent reference. A + * description's `colorTone` fills `appearance.colorTone` when that option + * omits it. + */ + base?: FlexThemeInput | FlexThemeDescription | FlexThemeReference; + appearance?: ThemeAppearanceOptions; + fallbackAppearance?: Partial<ResolvedThemeAppearance>; + appearanceSource?: ThemeAppearanceSource; + legacyFallback?: LegacyThemeFallback; +} + +export class FlexThemeReference implements FlexThemeSource { + public readonly kind = 'flex'; + public readonly appearanceOptions?: ThemeAppearanceOptions; + public readonly fallbackAppearance?: Partial<ResolvedThemeAppearance>; + public readonly appearanceSource?: ThemeAppearanceSource; + + private revisionValue = 0; + private readonly base?: FlexThemeInput | FlexThemeDescription | FlexThemeReference; + private readonly legacyFallback?: LegacyThemeFallback; + private recipes: FlexThemeRecipe[]; + private readonly listeners = new Set<OnThemeChange>(); + private readonly descriptionsByAppearance = new Map<string, FlexTokenDescription>(); + private readonly tokensByAppearance = new Map<string, FlexTokens>(); + private parentListener?: OnThemeChange; + private parentRevision?: number; + + public constructor(options: FlexThemeReferenceOptions = {}, ...recipes: FlexThemeRecipe[]) { + this.base = options.base; + const parent = options.base instanceof FlexThemeReference ? options.base : undefined; + const appearance = options.appearance ?? parent?.appearanceOptions; + const descriptionTone = isFlexThemeDescription(options.base) ? options.base.colorTone : undefined; + this.appearanceOptions = + descriptionTone !== undefined && appearance?.colorTone === undefined ? { ...appearance, colorTone: descriptionTone } : appearance; + this.fallbackAppearance = options.fallbackAppearance ?? parent?.fallbackAppearance; + this.appearanceSource = options.appearanceSource ?? parent?.appearanceSource; + this.legacyFallback = options.legacyFallback; + this.recipes = recipes; + this.parentRevision = parent?.revision; + } + + public get revision(): number { + this.syncParentRevision(); + return this.revisionValue; + } + + /** + * Resolve the tokens for one appearance. A missing tone means cool. Omitted + * interactive hover and pressed values are computed from rest on first read. + */ + public resolveFlexTokens(requestedAppearance: ResolvedThemeAppearance): FlexTokens { + this.syncParentRevision(); + const appearance = internResolvedThemeAppearance(requestedAppearance); + const key = themeAppearanceKey(appearance); + const cached = this.tokensByAppearance.get(key); + if (cached) { + return cached; + } + + const tokens = resolveFlexTokenDescription(this.resolveDescription(appearance, key), appearance); + this.tokensByAppearance.set(key, tokens); + return tokens; + } + + public resolveLegacyFallback(requestedAppearance: ResolvedThemeAppearance): Theme | PartialTheme | undefined { + const appearance = internResolvedThemeAppearance(requestedAppearance); + const parentFallback = this.base instanceof FlexThemeReference ? this.base.resolveLegacyFallback(appearance) : undefined; + const fallback = typeof this.legacyFallback === 'function' ? this.legacyFallback(appearance) : this.legacyFallback; + return parentFallback && fallback ? immutableMerge(parentFallback, fallback) : (fallback ?? parentFallback); + } + + public addOnThemeChanged(listener: OnThemeChange): void { + this.listeners.add(listener); + if (this.listeners.size === 1 && this.base instanceof FlexThemeReference) { + this.parentListener = () => { + this.parentRevision = this.base instanceof FlexThemeReference ? this.base.revision : undefined; + this.invalidate(); + }; + this.base.addOnThemeChanged(this.parentListener); + } + } + + public removeOnThemeChanged(listener: OnThemeChange): void { + this.listeners.delete(listener); + if (this.listeners.size === 0 && this.parentListener && this.base instanceof FlexThemeReference) { + this.base.removeOnThemeChanged(this.parentListener); + this.parentListener = undefined; + } + } + + public invalidate(): void { + this.revisionValue += 1; + this.descriptionsByAppearance.clear(); + this.tokensByAppearance.clear(); + for (const listener of this.listeners) { + listener(); + } + } + + public update(...recipes: FlexThemeRecipe[]): void { + this.recipes = recipes; + this.invalidate(); + } + + // Parents supply authored descriptions, never appearance-bound resolved tokens. + private resolveDescription(appearance: Readonly<NormalizedThemeAppearance>, key: string): FlexTokenDescription { + const cached = this.descriptionsByAppearance.get(key); + if (cached) { + return cached; + } + + let description = this.resolveBaseDescription(appearance, key); + for (const recipe of this.recipes) { + description = mergeFlexTokenDescription(description, typeof recipe === 'function' ? recipe(description, appearance) : recipe); + } + this.descriptionsByAppearance.set(key, description); + return description; + } + + private resolveBaseDescription(appearance: Readonly<NormalizedThemeAppearance>, key: string): FlexTokenDescription { + if (this.base instanceof FlexThemeReference) { + this.base.syncParentRevision(); + return this.base.resolveDescription(appearance, key); + } + if (isFlexThemeDescription(this.base)) { + return this.base.tokens; + } + const base = typeof this.base === 'function' ? this.base(appearance) : this.base; + return mergeFlexTokenDescription(getDefaultFlexTokenDescription(appearance.colorTone), base); + } + + private syncParentRevision(): void { + if (this.base instanceof FlexThemeReference && this.parentRevision !== this.base.revision) { + this.parentRevision = this.base.revision; + this.invalidate(); + } + } +} diff --git a/packages/agentic/design/src/flex/flexTokenDescription.ts b/packages/agentic/design/src/flex/flexTokenDescription.ts new file mode 100644 index 00000000000..28a63deab42 --- /dev/null +++ b/packages/agentic/design/src/flex/flexTokenDescription.ts @@ -0,0 +1,117 @@ +import { immutableMerge } from '@fluentui-react-native/framework-base'; + +import type { + CompleteFlexTokenInput, + FlexColorDescription, + FlexTokenDescription, + FlexTokens, + InteractiveColor, + PartialFlexTokens, + SemanticColorDescriptions, + SemanticColors, +} from './tokens.types'; +import { normalizeFlexColor, resolveExplicitFlexColor } from './colors/flexColor'; +import type { ColorSchemeSelector } from './colors/flexColor'; +import { assertShadowEntries, mergeShadowEntries, resolveShadowEntries } from './flexShadow'; + +/** Resolve one normalized color for an appearance. */ +export type FlexColorResolver<TAppearance extends ColorSchemeSelector> = ( + token: string, + description: FlexColorDescription, + appearance: TAppearance, +) => InteractiveColor; + +const emptyColors = Object.freeze({}) as SemanticColorDescriptions; + +function mergeColors(base: SemanticColorDescriptions, colors: unknown): SemanticColorDescriptions { + if (typeof colors !== 'object' || colors === null || Array.isArray(colors)) { + throw new TypeError('Flex color overrides must be an object keyed by semantic color name.'); + } + + let merged: Record<string, FlexColorDescription> | undefined; + for (const name of Object.keys(colors)) { + const value = (colors as Record<string, unknown>)[name]; + if (value === undefined) { + continue; + } + if (name === 'hover' || name === 'pressed') { + throw new TypeError(`color.${name} maps are no longer supported. Author { rest, ${name} } on each color instead.`); + } + const description = normalizeFlexColor(value as never, 'standard', `color.${name}`); + if (description !== (base as Record<string, FlexColorDescription>)[name]) { + merged ??= { ...base }; + merged[name] = description; + } + } + return merged ? (Object.freeze(merged) as SemanticColorDescriptions) : base; +} + +/** + * Merge authored overrides into a description. Each color and shadow replaces + * the previous value atomically, so omitted states never inherit stale + * explicit values. `undefined` colors and shadows are not overrides. Other + * non-color groups keep deep-merge semantics. + * @internal + */ +export function mergeFlexTokenDescription(base: FlexTokenDescription, overrides: PartialFlexTokens | undefined): FlexTokenDescription { + if (overrides === undefined) { + return base; + } + if (typeof overrides !== 'object' || overrides === null || Array.isArray(overrides)) { + throw new TypeError('Flex token overrides must be an object.'); + } + + const { color, shadow, ...groups } = overrides; + const mergedColors = color === undefined ? base.color : mergeColors(base.color, color); + const mergedShadows = shadow === undefined ? base.shadow : mergeShadowEntries(base.shadow, shadow); + const hasGroups = Object.keys(groups).length > 0; + if (mergedColors === base.color && mergedShadows === base.shadow && !hasGroups) { + return base; + } + + const { color: _baseColor, shadow: _baseShadow, ...baseGroups } = base; + const mergedGroups = hasGroups ? immutableMerge(baseGroups as object, groups as object) : baseGroups; + return Object.freeze({ color: mergedColors, shadow: mergedShadows, ...mergedGroups }) as FlexTokenDescription; +} + +/** + * Normalize a complete authored token set. + * @internal + */ +export function createFlexTokenDescription(tokens: CompleteFlexTokenInput): FlexTokenDescription { + const { color, ...groups } = tokens; + assertShadowEntries(groups.shadow); + return Object.freeze({ color: mergeColors(emptyColors, color), ...groups }) as FlexTokenDescription; +} + +/** + * Resolve every color in a description with a color policy and select each + * shadow for the scheme. Other non-color groups are shared with the + * description. + * @internal + */ +export function resolveFlexTokenDescriptionWith<TAppearance extends ColorSchemeSelector>( + description: FlexTokenDescription, + appearance: TAppearance, + resolveColor: FlexColorResolver<TAppearance>, +): FlexTokens { + const color: Record<string, InteractiveColor> = {}; + for (const name of Object.keys(description.color)) { + color[name] = resolveColor(name, (description.color as Record<string, FlexColorDescription>)[name], appearance); + } + const { color: _descriptionColor, shadow, ...groups } = description; + return Object.freeze({ + color: Object.freeze(color) as SemanticColors, + shadow: resolveShadowEntries(shadow, appearance), + ...groups, + }) as FlexTokens; +} + +/** + * Resolve a description without interaction algorithms; omitted states equal + * rest. + * @internal + */ +export function resolveExplicitFlexTokenDescription(description: FlexTokenDescription, appearance: ColorSchemeSelector): FlexTokens { + return resolveFlexTokenDescriptionWith(description, appearance, (_token, color, selected) => resolveExplicitFlexColor(color, selected)); +} diff --git a/packages/agentic/design/src/styling/colorStyles.test.ts b/packages/agentic/design/src/flex/styling/colorStyles.test.ts similarity index 72% rename from packages/agentic/design/src/styling/colorStyles.test.ts rename to packages/agentic/design/src/flex/styling/colorStyles.test.ts index 21f2b5f7109..2815f3459d5 100644 --- a/packages/agentic/design/src/styling/colorStyles.test.ts +++ b/packages/agentic/design/src/flex/styling/colorStyles.test.ts @@ -1,7 +1,8 @@ -import type { FlexTokens } from '../tokens/flex.types'; -import { defaultFlexTokens } from '../tokens/defaultTokens'; -import { defaultResolvedThemeAppearance } from '../theming/appearance'; -import type { ThemeState } from '../useThemeState'; +import { createInteractiveColor } from '../colors/interactiveColor'; +import type { FlexTokens } from '../tokens.types'; +import { defaultFlexTokens } from '../defaults/defaultTokens'; +import { defaultResolvedThemeAppearance } from '../../theming/appearance'; +import type { ThemeState } from '../themeState.types'; import { colorStyleDef, getThemedColorStyleFactory } from './colorStyles'; import type { ColorStyleDefinition, ViewColorStyle } from './colorStyles'; @@ -40,14 +41,14 @@ describe('colorStyles', () => { const tokens = defaultFlexTokens; const styles = colorStyleDef(definition, stateLevels)(tokens); - expect(styles.backgroundColor).toBe(tokens.color.backgroundNeutralSubtle); - expect(styles.borderColor).toBe(tokens.color.strokeNeutralTransparent); + expect(styles.backgroundColor).toBe(tokens.color.backgroundNeutralSubtle.rest); + expect(styles.borderColor).toBe(tokens.color.strokeNeutralTransparent.rest); expect(styles.selected).toMatchObject({ - backgroundColor: tokens.color.backgroundNeutralHeavy, + backgroundColor: tokens.color.backgroundNeutralHeavy.rest, }); expect(styles.disabled).toEqual({ - backgroundColor: tokens.color.backgroundNeutralSubtleDisabled, - borderColor: tokens.color.strokeNeutralDisabled, + backgroundColor: tokens.color.backgroundNeutralSubtleDisabled.rest, + borderColor: tokens.color.strokeNeutralDisabled.rest, }); }); @@ -56,24 +57,24 @@ describe('colorStyles', () => { const styles = colorStyleDef(definition, stateLevels)(tokens); expect(styles.hovered).toEqual({ - backgroundColor: tokens.color.hover.backgroundNeutralSubtle, - borderColor: tokens.color.hover.strokeNeutralTransparent, + backgroundColor: tokens.color.backgroundNeutralSubtle.hover, + borderColor: tokens.color.strokeNeutralTransparent.hover, }); expect(styles.pressed).toEqual({ - backgroundColor: tokens.color.pressed.backgroundNeutralSubtle, - borderColor: tokens.color.pressed.strokeNeutralTransparent, + backgroundColor: tokens.color.backgroundNeutralSubtle.pressed, + borderColor: tokens.color.strokeNeutralTransparent.pressed, }); expect(styles.selected?.hovered).toEqual({ - backgroundColor: tokens.color.hover.backgroundNeutralHeavy, - borderColor: tokens.color.hover.strokeNeutralHeavy, + backgroundColor: tokens.color.backgroundNeutralHeavy.hover, + borderColor: tokens.color.strokeNeutralHeavy.hover, }); expect(styles.selected?.pressed).toEqual({ - backgroundColor: tokens.color.pressed.backgroundNeutralHeavy, - borderColor: tokens.color.pressed.strokeNeutralTransparent, + backgroundColor: tokens.color.backgroundNeutralHeavy.pressed, + borderColor: tokens.color.strokeNeutralTransparent.pressed, }); }); - it('falls back to rest colors when an interaction map does not override a semantic key', () => { + it('uses the rest value in hovered nodes for colors without interaction states', () => { const tokens = defaultFlexTokens; const levels = [['hovered']] as const; const styles = colorStyleDef<ViewColorStyle, typeof levels>( @@ -86,7 +87,7 @@ describe('colorStyles', () => { levels, )(tokens); - expect(styles.hovered?.backgroundColor).toBe(tokens.color.backgroundNeutralHeavyDisabled); + expect(styles.hovered?.backgroundColor).toBe(tokens.color.backgroundNeutralHeavyDisabled.rest); }); it('preserves valid falsy color values', () => { @@ -95,7 +96,7 @@ describe('colorStyles', () => { ...tokens, color: { ...tokens.color, - backgroundBrandHeavy: '', + backgroundBrandHeavy: createInteractiveColor('', '', ''), }, } satisfies FlexTokens; const levels = [['disabled']] as const; @@ -127,8 +128,8 @@ describe('colorStyles', () => { const styles = colorStyleDef(threeLevelDefinition, levels)(tokens); expect(styles.selected?.pressed?.highContrast).toEqual({ - backgroundColor: tokens.color.pressed.backgroundNeutralHeavy, - borderColor: tokens.color.pressed.strokeNeutralHeavy, + backgroundColor: tokens.color.backgroundNeutralHeavy.pressed, + borderColor: tokens.color.strokeNeutralHeavy.pressed, }); }); @@ -138,14 +139,14 @@ describe('colorStyles', () => { const getStyle = getThemedColorStyleFactory('test.colors', definition, stateLevels); expect(getStyle(themeState, { selected: true, hovered: true })).toEqual({ - backgroundColor: colors.hover.backgroundNeutralHeavy, - borderColor: colors.hover.strokeNeutralHeavy, + backgroundColor: colors.backgroundNeutralHeavy.hover, + borderColor: colors.strokeNeutralHeavy.hover, }); const cachedEntries = Reflect.ownKeys(themeState.themeStyles).length; expect(getStyle(themeState, { selected: true, disabled: true })).toEqual({ - backgroundColor: colors.backgroundNeutralHeavyDisabled, - borderColor: colors.strokeNeutralDisabled, + backgroundColor: colors.backgroundNeutralHeavyDisabled.rest, + borderColor: colors.strokeNeutralDisabled.rest, }); expect(Reflect.ownKeys(themeState.themeStyles)).toHaveLength(cachedEntries); }); diff --git a/packages/agentic/design/src/styling/colorStyles.ts b/packages/agentic/design/src/flex/styling/colorStyles.ts similarity index 82% rename from packages/agentic/design/src/styling/colorStyles.ts rename to packages/agentic/design/src/flex/styling/colorStyles.ts index 568398454e5..0717b8de1b0 100644 --- a/packages/agentic/design/src/styling/colorStyles.ts +++ b/packages/agentic/design/src/flex/styling/colorStyles.ts @@ -1,10 +1,10 @@ -import type { ColorValue, TextStyle, ViewStyle } from 'react-native'; +import type { TextStyle, ViewStyle } from 'react-native'; -import type { FlexTokens, SemanticColors } from '../tokens/flex.types'; -import type { ThemeState } from '../useThemeState'; +import type { FlexTokens, InteractiveColor, SemanticColorName, SemanticColors } from '../tokens.types'; +import type { ThemeState } from '../themeState.types'; -import { createStateLevelMap, getThemedStateStyleFactory } from './branchedStyle'; -import type { StateLevels, StateNames, StateSource, StyleDefinition, StyleDefFromTokens } from './branchedStyle'; +import { createStateLevelMap, getThemedStateStyleFactory } from '../../styling/branchedStyle'; +import type { StateLevels, StateNames, StateSource, StyleDefinition, StyleDefFromTokens } from '../../styling/branchedStyle'; export type ViewColorStyle = Pick<ViewStyle, 'backgroundColor' | 'borderColor'>; export type TextColorStyle = Pick<TextStyle, 'color'>; @@ -15,7 +15,7 @@ const colorStyleKeys: readonly ColorStyleKeys[] = ['backgroundColor', 'borderCol /** * A semantic color key available in the Flex tokens. */ -export type ColorKey = keyof Omit<SemanticColors, 'hover' | 'pressed'>; +export type ColorKey = SemanticColorName; type AnyColorStyle = ViewColorStyle | TextColorStyle; type ColorKeysForStyle<StyleType extends AnyColorStyle> = { [K in keyof StyleType]: ColorKey }; @@ -39,7 +39,7 @@ interface RawColorDef { } type InheritedColorKeys = Partial<Record<ColorStyleKeys, ColorKey>>; type RawStyleDef = Record<string, unknown>; -type InteractionColors = Partial<Record<ColorKey, ColorValue>>; +type ColorState = Exclude<keyof InteractiveColor, 'rest'>; function getColorKey(definition: RawColorDef, key: ColorStyleKeys): ColorKey | undefined { const value = definition[key]; @@ -51,19 +51,21 @@ function getStateDefinition(definition: RawColorDef, key: string): RawColorDef | return typeof value === 'object' && value !== null ? value : undefined; } -function getInteractionColors(colors: SemanticColors, state: string | undefined): InteractionColors | undefined { +function getColorState(state: string | undefined): ColorState | undefined { if (state === 'hovered') { - return colors.hover; + return 'hover'; } if (state === 'pressed') { - return colors.pressed; + return 'pressed'; } return undefined; } /** * Converts semantic color keys into resolved style values while synthesizing - * hovered and pressed nodes wherever those states are declared. + * hovered and pressed nodes wherever those states are declared. Hovered and + * pressed nodes read each color's matching state, so a derived state is + * computed when the style is first built for a theme state. */ function convertToStyleDef( name: string | undefined, @@ -72,18 +74,17 @@ function convertToStyleDef( rawColorDef: RawColorDef, stateLevels: StateLevels, nextLevel: number, - activeInteractionState?: string, + activeInteractionState?: ColorState, ): RawStyleDef { const result: RawStyleDef = {}; const inheritedKeys: InheritedColorKeys = { ...parent }; - const interactionState = getInteractionColors(colors, name) ? name : activeInteractionState; - const interactionColors = getInteractionColors(colors, interactionState); + const interactionState = getColorState(name) ?? activeInteractionState; for (const styleKey of colorStyleKeys) { - const colorKey = getColorKey(rawColorDef, styleKey) ?? (interactionColors ? parent?.[styleKey] : undefined); + const colorKey = getColorKey(rawColorDef, styleKey) ?? (interactionState ? parent?.[styleKey] : undefined); if (colorKey !== undefined) { inheritedKeys[styleKey] = colorKey; - const colorValue = interactionColors?.[colorKey] ?? colors[colorKey]; + const colorValue = colors[colorKey]?.[interactionState ?? 'rest']; if (colorValue !== undefined) { result[styleKey] = colorValue; } diff --git a/packages/agentic/design/src/flex/themeState.ts b/packages/agentic/design/src/flex/themeState.ts new file mode 100644 index 00000000000..156c197f60e --- /dev/null +++ b/packages/agentic/design/src/flex/themeState.ts @@ -0,0 +1,47 @@ +import { defaultFlexTokens } from './defaults/defaultTokens'; +import { flexTokensFromTheme } from './adapters/flexTokensFromTheme'; +import type { FlexTokens } from './tokens.types'; +import { defaultResolvedThemeAppearance } from '../theming/appearance'; +import { getFlexSourceTokens, getThemeAppearanceCache } from '../theming/themeRuntime'; +import type { ThemeSource } from '../theming/themeSource'; +import type { NormalizedThemeAppearance } from '../types/appearance.types'; +import type { ThemeState } from './themeState.types'; + +export const defaultThemeState: ThemeState = { + tokens: defaultFlexTokens, + appearance: defaultResolvedThemeAppearance, + highContrast: false, + themeStyles: {}, +}; + +/** + * Resolve Flex tokens for any source. Legacy sources use the forward adapter. + */ +export function getFlexTokens(source: ThemeSource, appearance: Readonly<NormalizedThemeAppearance>): FlexTokens { + if (source.kind === 'flex') { + return getFlexSourceTokens(source, appearance); + } + + const cache = getThemeAppearanceCache(source, appearance); + if (!cache.flexTokens) { + cache.flexTokens = flexTokensFromTheme(source.resolveTheme(appearance), appearance); + } + return cache.flexTokens; +} + +/** + * Return the shared theme state for one source revision and resolved + * appearance. Every new state owns a fresh style registry. + */ +export function getThemeState(source: ThemeSource, appearance: Readonly<NormalizedThemeAppearance>): ThemeState { + const cache = getThemeAppearanceCache(source, appearance); + if (!cache.themeState) { + cache.themeState = { + tokens: getFlexTokens(source, appearance), + appearance, + highContrast: appearance.contrast === 'highContrast', + themeStyles: {}, + }; + } + return cache.themeState; +} diff --git a/packages/agentic/design/src/flex/themeState.types.ts b/packages/agentic/design/src/flex/themeState.types.ts new file mode 100644 index 00000000000..c7a12cd71f2 --- /dev/null +++ b/packages/agentic/design/src/flex/themeState.types.ts @@ -0,0 +1,49 @@ +import type { ColorTone, NormalizedThemeAppearance } from '../types/appearance.types'; +import type { FlexTokenDescription, FlexTokens } from './tokens.types'; + +/** + * A complete Flex theme: a token description that replaces the package + * defaults, and the palette tone it was authored for. + */ +export type FlexThemeDescription = { + /** + * The complete authored token description, covering light and dark. + */ + readonly tokens: FlexTokenDescription; + /** + * The palette tone of these tokens. A `FlexThemeReference` built on this + * description uses it as its default requested tone, which also selects the + * interaction-color algorithm. Omitted means no default, so the tone + * resolves as for any other source. + */ + readonly colorTone?: ColorTone; +}; + +/** + * Style sheets cached for one theme state, keyed by a module-scoped symbol per component. + */ +export type ThemeStyleRegistry = Record<symbol, unknown>; + +export type ThemeState = { + /** + * The set of flex tokens + */ + readonly tokens: FlexTokens; + /** + * Structured appearance values used to resolve this theme state. + */ + readonly appearance: Readonly<NormalizedThemeAppearance>; + /** + * @deprecated Use appearance.contrast. + */ + readonly highContrast: boolean; + /** + * Style sheets shared by every component instance using this theme state. + * + * Components should use a module-scoped symbol as their key and lazily store + * one immutable StyleSheet.create result whose values depend only on this + * ThemeState. Component props, interaction state, and user styles must be + * applied separately. + */ + readonly themeStyles: ThemeStyleRegistry; +}; diff --git a/packages/agentic/design/src/flex/tokens.test.ts b/packages/agentic/design/src/flex/tokens.test.ts new file mode 100644 index 00000000000..5e9a73f17bf --- /dev/null +++ b/packages/agentic/design/src/flex/tokens.test.ts @@ -0,0 +1,81 @@ +import { INTERACTIVE_COLOR_TOKENS, isInverseInteractionToken } from './colors/interactiveTokens'; +import { defaultFlexTokenDescription, defaultFlexTokens, getDefaultFlexTokenDescription } from './defaults/defaultTokens'; +import type { FlexTokenDescription, FlexTokens } from './tokens.types'; + +const flexTokens: FlexTokens = defaultFlexTokens; + +function explicitStates(description: FlexTokenDescription): string[] { + return Object.entries(description.color) + .flatMap(([name, color]) => + (['hover', 'pressed'] as const).filter((state) => color[state] !== undefined).map((state) => `${name}.${state}`), + ) + .sort(); +} + +describe('FlexTokens', () => { + it('groups tokens and removes category prefixes from their names', () => { + expect(flexTokens.color.surfaceNeutralFarther).toEqual({ rest: '#ebebeb', hover: '#e1e1e1', pressed: '#d7d7d7' }); + expect(flexTokens.shadow.lowest).toEqual([ + { x: 0, y: 0, blur: 2, color: '#0000001a' }, + { x: 0, y: 1, blur: 2, color: '#0000000d' }, + ]); + expect(flexTokens.fontWeight.functionalRegular).toBe('400'); + expect(flexTokens.fontFamily.functional).toBeTruthy(); + expect(flexTokens.fontSize.functionalBodyMedium).toBe(14); + expect(flexTokens.lineHeight.functionalBodyMedium).toBe(20); + expect(flexTokens.borderRadius.base100).toBe(4); + expect(flexTokens.spacing.componentBase800).toBe(32); + expect(flexTokens.strokeWidth.thin).toBe(1); + expect(flexTokens.motion.durationBase200).toBe(200); + expect(flexTokens.motion.easingFunctionalEnter).toEqual([0, 0, 0, 1]); + expect(flexTokens.color.backgroundBrandHeavy.rest).toBe('#242424'); + }); + + it('does not expose the previous flat token names or state maps', () => { + expect('colorSurfaceNeutralFarther' in flexTokens).toBe(false); + expect('shadowLowest' in flexTokens).toBe(false); + expect('fontWeightFunctionalRegular' in flexTokens).toBe(false); + expect('hover' in flexTokens.color).toBe(false); + expect('pressed' in flexTokens.color).toBe(false); + }); + + it('resolves every default color with all three states', () => { + for (const [name, color] of Object.entries(defaultFlexTokens.color)) { + expect([name, Object.keys(color)]).toEqual([name, ['rest', 'hover', 'pressed']]); + } + expect(defaultFlexTokens.color.fixedBlack.hover).toBe(defaultFlexTokens.color.fixedBlack.rest); + expect(Object.isFrozen(defaultFlexTokens.color)).toBe(true); + }); + + it('authors inverse interaction metadata on every inverse interactive default', () => { + for (const tone of ['cool', 'warm'] as const) { + const colors = getDefaultFlexTokenDescription(tone).color; + const inverted = Object.keys(colors).filter((name) => colors[name as keyof typeof colors].type === 'inverted'); + + expect([tone, inverted.sort()]).toEqual([tone, INTERACTIVE_COLOR_TOKENS.filter(isInverseInteractionToken).sort()]); + } + }); + + it('authors only the interaction states the policy cannot reproduce', () => { + expect(explicitStates(defaultFlexTokenDescription)).toEqual([ + 'backgroundNeutralTranslucent.hover', + 'backgroundNeutralTranslucent.pressed', + 'strokeBrandSoft.hover', + 'strokeBrandSoft.pressed', + 'strokeBrandSubtle.pressed', + 'strokeNeutralSoft.hover', + 'strokeNeutralSoft.pressed', + 'strokeNeutralSubtle.pressed', + ]); + expect(explicitStates(getDefaultFlexTokenDescription('warm'))).toEqual([]); + }); + + it('selects the default description by color tone', () => { + const warm = getDefaultFlexTokenDescription('warm'); + + expect(getDefaultFlexTokenDescription('cool')).toBe(defaultFlexTokenDescription); + expect(getDefaultFlexTokenDescription('warm')).toBe(warm); + expect(warm.color.surfaceNeutralFarther.rest).toEqual(['#f0eae5', '#1e1916']); + expect(warm.shadow).toBe(defaultFlexTokenDescription.shadow); + }); +}); diff --git a/packages/agentic/design/src/flex/tokens.types.ts b/packages/agentic/design/src/flex/tokens.types.ts new file mode 100644 index 00000000000..f7c76a1a53a --- /dev/null +++ b/packages/agentic/design/src/flex/tokens.types.ts @@ -0,0 +1,516 @@ +import type { ColorValue, TextStyle, ViewStyle, DimensionValue } from 'react-native'; + +type FontWeight = TextStyle['fontWeight']; +type FontSize = TextStyle['fontSize']; +type BorderRadius = ViewStyle['borderRadius']; +type StrokeWidth = ViewStyle['borderWidth']; + +/** A color that selects light at index zero and dark at index one. */ +export type ColorTuple = readonly [light: ColorValue, dark: ColorValue]; + +/** One authored color for every scheme, or a light/dark tuple. */ +export type ColorEntry = ColorValue | ColorTuple; + +/** + * How omitted interaction states derive from rest. Standard and inverted use + * opposite scheme-dependent lightness directions. Fixed requires explicit + * states for derivable literal colors. + */ +export type InteractiveColorType = 'standard' | 'inverted' | 'fixed'; + +/** An authored color with optional explicit interaction states. */ +export type InteractiveColorOptions = { + rest: ColorEntry; + hover?: ColorEntry; + pressed?: ColorEntry; + type?: InteractiveColorType; +}; + +/** Any authored Flex color. */ +export type FlexColorInput = ColorEntry | InteractiveColorOptions; + +/** + * A normalized, frozen authored color. Omitted states stay omitted until the + * color resolves for an appearance. + */ +export type FlexColorDescription = { + readonly rest: ColorEntry; + readonly hover?: ColorEntry; + readonly pressed?: ColorEntry; + readonly type: InteractiveColorType; +}; + +/** + * A resolved Flex color for one appearance. Omitted states are computed on + * first read and memoized. + */ +export type InteractiveColor = { + readonly rest: ColorValue; + readonly hover: ColorValue; + readonly pressed: ColorValue; +}; + +/** + * Every semantic color token, resolved for one appearance. + */ +export type SemanticColors = { + // surface / neutral + surfaceNeutralFarther: InteractiveColor; + surfaceNeutralFar: InteractiveColor; + surfaceNeutralNear: InteractiveColor; + surfaceNeutralNearer: InteractiveColor; + surfaceNeutralTranslucent: InteractiveColor; + + // background / neutral + backgroundNeutralHeavy: InteractiveColor; + backgroundNeutralLoud: InteractiveColor; + backgroundNeutralSoft: InteractiveColor; + backgroundNeutralSubtle: InteractiveColor; + backgroundNeutralTransparent: InteractiveColor; + backgroundNeutralTranslucent: InteractiveColor; + + // background / brand + backgroundBrandHeavy: InteractiveColor; + backgroundBrandLoud: InteractiveColor; + backgroundBrandSoft: InteractiveColor; + backgroundBrandSubtle: InteractiveColor; + backgroundBrandTransparent: InteractiveColor; + + // background / danger + backgroundDangerLoud: InteractiveColor; + backgroundDangerSoft: InteractiveColor; + backgroundDangerSubtle: InteractiveColor; + + // background / warning + backgroundWarningLoud: InteractiveColor; + backgroundWarningSoft: InteractiveColor; + backgroundWarningSubtle: InteractiveColor; + + // background / success + backgroundSuccessLoud: InteractiveColor; + backgroundSuccessSoft: InteractiveColor; + backgroundSuccessSubtle: InteractiveColor; + + // stroke / neutral + strokeNeutralHeavy: InteractiveColor; + strokeNeutralLoud: InteractiveColor; + strokeNeutralSoft: InteractiveColor; + strokeNeutralSubtle: InteractiveColor; + strokeNeutralTransparent: InteractiveColor; + strokeNeutralOnloud: InteractiveColor; + + // stroke / brand + strokeBrandLoud: InteractiveColor; + strokeBrandSoft: InteractiveColor; + strokeBrandSubtle: InteractiveColor; + strokeBrandOnloud: InteractiveColor; + + // stroke / danger + strokeDangerLoud: InteractiveColor; + strokeDangerSoft: InteractiveColor; + strokeDangerSubtle: InteractiveColor; + strokeDangerOnloud: InteractiveColor; + + // stroke / warning + strokeWarningLoud: InteractiveColor; + strokeWarningSoft: InteractiveColor; + strokeWarningSubtle: InteractiveColor; + strokeWarningOnloud: InteractiveColor; + + // stroke / success + strokeSuccessLoud: InteractiveColor; + strokeSuccessSoft: InteractiveColor; + strokeSuccessSubtle: InteractiveColor; + strokeSuccessOnloud: InteractiveColor; + + // foreground / neutral + foregroundNeutralPrimary: InteractiveColor; + foregroundNeutralSecondary: InteractiveColor; + foregroundNeutralTertiary: InteractiveColor; + foregroundNeutralOnloud: InteractiveColor; + + // foreground / brand + foregroundBrandPrimary: InteractiveColor; + foregroundBrandOnloud: InteractiveColor; + + // foreground / danger + foregroundDangerPrimary: InteractiveColor; + foregroundDangerOnloud: InteractiveColor; + + // foreground / warning + foregroundWarningPrimary: InteractiveColor; + foregroundWarningOnloud: InteractiveColor; + + // foreground / success + foregroundSuccessPrimary: InteractiveColor; + foregroundSuccessOnloud: InteractiveColor; + + // fixed + fixedWhite: InteractiveColor; + fixedBlack: InteractiveColor; + + // expression / accent + expressionAccentHeavy: InteractiveColor; + expressionAccentLoud: InteractiveColor; + expressionAccentSoft: InteractiveColor; + expressionAccentSubtle: InteractiveColor; + + // expression / achromatic + expressionAchromaticHeavy: InteractiveColor; + expressionAchromaticSubtle: InteractiveColor; + + // expression / gray + expressionGrayHeavy: InteractiveColor; + expressionGrayLoud: InteractiveColor; + expressionGraySoft: InteractiveColor; + expressionGraySubtle: InteractiveColor; + + // expression / navy + expressionNavyHeavy: InteractiveColor; + expressionNavyLoud: InteractiveColor; + expressionNavySoft: InteractiveColor; + expressionNavySubtle: InteractiveColor; + + // expression / blue + expressionBlueHeavy: InteractiveColor; + expressionBlueLoud: InteractiveColor; + expressionBlueSoft: InteractiveColor; + expressionBlueSubtle: InteractiveColor; + + // expression / green + expressionGreenHeavy: InteractiveColor; + expressionGreenLoud: InteractiveColor; + expressionGreenSoft: InteractiveColor; + expressionGreenSubtle: InteractiveColor; + + // expression / lime + expressionLimeHeavy: InteractiveColor; + expressionLimeLoud: InteractiveColor; + expressionLimeSoft: InteractiveColor; + expressionLimeSubtle: InteractiveColor; + + // expression / yellow + expressionYellowHeavy: InteractiveColor; + expressionYellowLoud: InteractiveColor; + expressionYellowSoft: InteractiveColor; + expressionYellowSubtle: InteractiveColor; + + // expression / pumpkin + expressionPumpkinHeavy: InteractiveColor; + expressionPumpkinLoud: InteractiveColor; + expressionPumpkinSoft: InteractiveColor; + expressionPumpkinSubtle: InteractiveColor; + + // expression / red + expressionRedHeavy: InteractiveColor; + expressionRedLoud: InteractiveColor; + expressionRedSoft: InteractiveColor; + expressionRedSubtle: InteractiveColor; + + // expression / pink + expressionPinkHeavy: InteractiveColor; + expressionPinkLoud: InteractiveColor; + expressionPinkSoft: InteractiveColor; + expressionPinkSubtle: InteractiveColor; + + // expression / purple + expressionPurpleHeavy: InteractiveColor; + expressionPurpleLoud: InteractiveColor; + expressionPurpleSoft: InteractiveColor; + expressionPurpleSubtle: InteractiveColor; + + // overlay + overlayNeutralTranslucent: InteractiveColor; + + // material / background + materialBackgroundThick: InteractiveColor; + materialBackgroundRegular: InteractiveColor; + materialBackgroundThin: InteractiveColor; + + // disabled + backgroundNeutralDisabled: InteractiveColor; + backgroundNeutralHeavyDisabled: InteractiveColor; + backgroundNeutralSubtleDisabled: InteractiveColor; + strokeNeutralDisabled: InteractiveColor; + foregroundNeutralDisabled: InteractiveColor; + + // focus strokes + strokeFocusInner: InteractiveColor; + strokeFocusOuter: InteractiveColor; + + // shadow + shadow: InteractiveColor; +}; + +/** A semantic color token name. */ +export type SemanticColorName = keyof SemanticColors; + +/** One selected color value for each semantic color token. */ +export type SemanticColorTokenValues = { [Name in SemanticColorName]: ColorValue }; + +/** Authored semantic colors. `undefined` means no override. */ +export type PartialSemanticColors = { [Name in SemanticColorName]?: FlexColorInput }; + +/** Normalized authored semantic colors. */ +export type SemanticColorDescriptions = { readonly [Name in SemanticColorName]: FlexColorDescription }; + +/** One shadow layer. Offsets and blur are density-independent pixels. */ +export type FlexShadowLayer = { + readonly x: number; + readonly y: number; + readonly blur: number; + readonly color: ColorValue; +}; + +/** + * A layered shadow, ordered like CSS `box-shadow`: the first layer is the + * contour and the last is the key shadow. + */ +export type FlexShadow = readonly FlexShadowLayer[]; + +/** One authored shadow for every scheme, or a light/dark tuple of shadows. */ +export type FlexShadowEntry = FlexShadow | readonly [light: FlexShadow, dark: FlexShadow]; + +/** + * The semantic shadow token set, resolved for one appearance. + */ +export type SemanticShadows = { + lowest: FlexShadow; + lower: FlexShadow; + low: FlexShadow; + high: FlexShadow; + higher: FlexShadow; + highest: FlexShadow; +}; + +/** Authored semantic shadows. Each entry may select a shadow per scheme. */ +export type SemanticShadowEntries = { [Name in keyof SemanticShadows]: FlexShadowEntry }; + +/** + * Semantic font weight tokens. + * + * Source of truth: `dev/web/flex-themes/css/semantic.css`. + */ +export type SemanticFontWeights = { + functionalRegular: FontWeight; + functionalMedium: FontWeight; + functionalSemibold: FontWeight; + functionalBold: FontWeight; + contentRegular: FontWeight; + contentMedium: FontWeight; + contentSemibold: FontWeight; + contentBold: FontWeight; + contentEditorialRegular: FontWeight; + contentEditorialMedium: FontWeight; + contentEditorialSemibold: FontWeight; + contentEditorialBold: FontWeight; +}; + +export type SemanticFontFamilies = { + functional: string; + content: string; + contentEditorial: string; + contentCode: string; +}; + +export type SemanticFontSizes = { + functionalDisplay: FontSize; + functionalPagetitle: FontSize; + functionalTitleLarge: FontSize; + functionalTitleMedium: FontSize; + functionalTitleSmall: FontSize; + functionalSubtitle: FontSize; + functionalBodyLarge: FontSize; + functionalBodyMedium: FontSize; + functionalBodySmall: FontSize; + functionalCaption: FontSize; + contentStatement: FontSize; + contentExpressiveLarge: FontSize; + contentExpressiveMedium: FontSize; + contentExpressiveSmall: FontSize; + contentH1: FontSize; + contentH2: FontSize; + contentH3: FontSize; + contentH4: FontSize; + contentH5: FontSize; + contentSubheadline: FontSize; + contentParagraphLarge: FontSize; + contentParagraphMedium: FontSize; + contentParagraphSmall: FontSize; + contentSubtext: FontSize; + contentTable: FontSize; + contentCode: FontSize; +}; + +export type SemanticLineHeights = { + functionalDisplay: number; + functionalPagetitle: number; + functionalTitleLarge: number; + functionalTitleMedium: number; + functionalTitleSmall: number; + functionalSubtitle: number; + functionalBodyLarge: number; + functionalBodyMedium: number; + functionalBodySmall: number; + functionalCaption: number; + contentStatement: number; + contentExpressiveLarge: number; + contentExpressiveMedium: number; + contentExpressiveSmall: number; + contentH1: number; + contentH2: number; + contentH3: number; + contentH4: number; + contentH5: number; + contentSubheadline: number; + contentParagraphLarge: number; + contentParagraphMedium: number; + contentParagraphSmall: number; + contentSubtext: number; + contentTable: number; + contentCode: number; +}; + +export type SemanticBorderRadii = { + base100: BorderRadius; + base200: BorderRadius; + base300: BorderRadius; + base400: BorderRadius; + base600: BorderRadius; + base700: BorderRadius; + circular: BorderRadius; +}; + +export type SemanticSpacing = { + componentBase50: DimensionValue; + componentBase100: DimensionValue; + componentBase150: DimensionValue; + componentBase200: DimensionValue; + componentBase250: DimensionValue; + componentBase300: DimensionValue; + componentBase400: DimensionValue; + componentBase500: DimensionValue; + componentBase600: DimensionValue; + componentBase700: DimensionValue; + componentBase800: DimensionValue; + layoutBase100: DimensionValue; + layoutBase200: DimensionValue; + layoutBase300: DimensionValue; + layoutBase400: DimensionValue; + layoutBase450: DimensionValue; + layoutBase500: DimensionValue; + layoutBase600: DimensionValue; + layoutBase700: DimensionValue; + layoutBase800: DimensionValue; + layoutBase1000: DimensionValue; + layoutBase1200: DimensionValue; +}; + +export type SemanticStrokeWidths = { + thin: StrokeWidth; + thick: StrokeWidth; + thicker: StrokeWidth; + thickest: StrokeWidth; +}; + +/** A cubic Bézier easing curve as `[x1, y1, x2, y2]`, the arguments of `Easing.bezier`. */ +export type FlexEasing = readonly [x1: number, y1: number, x2: number, y2: number]; + +/** + * Semantic motion tokens. Durations are milliseconds. + */ +export type SemanticMotion = { + durationBase50: number; + durationBase100: number; + durationBase200: number; + durationBase300: number; + durationBase500: number; + durationBase1000: number; + easingFunctionalEnter: FlexEasing; + easingFunctionalExit: FlexEasing; + easingFunctionalTransition: FlexEasing; + easingFunctionalLinear: FlexEasing; + easingExpressiveEnter: FlexEasing; + easingExpressiveExit: FlexEasing; + easingExpressiveTransition: FlexEasing; +}; + +/** + * The complete, grouped Flex token set. Category prefixes are represented by + * sub-objects and removed from the token names inside each category. + */ +export type FlexTokens = { + color: SemanticColors; + shadow: SemanticShadows; + fontWeight: SemanticFontWeights; + fontFamily: SemanticFontFamilies; + fontSize: SemanticFontSizes; + lineHeight: SemanticLineHeights; + borderRadius: SemanticBorderRadii; + spacing: SemanticSpacing; + strokeWidth: SemanticStrokeWidths; + motion: SemanticMotion; +}; + +export type SemanticTokens = FlexTokens; + +type NonColorFlexTokenGroup = Exclude<keyof FlexTokens, 'color'>; + +/** Authored non-color groups. Shadows may select a value per scheme. */ +type AuthoredFlexTokenGroups = Omit<FlexTokens, 'color' | 'shadow'> & { shadow: SemanticShadowEntries }; + +/** + * Authored Flex token overrides. Each color and shadow is an atomic + * replacement; other non-color groups deep merge. + */ +export type PartialFlexTokens = { color?: PartialSemanticColors } & { + [Group in NonColorFlexTokenGroup]?: Partial<AuthoredFlexTokenGroups[Group]>; +}; + +/** A complete authored Flex token set. */ +export type CompleteFlexTokenInput = { color: { [Name in SemanticColorName]: FlexColorInput } } & Pick< + AuthoredFlexTokenGroups, + NonColorFlexTokenGroup +>; + +/** + * A complete, normalized authored token set before appearance resolution. + * Recipes receive this form. + */ +export type FlexTokenDescription = { readonly color: SemanticColorDescriptions } & { + readonly [Group in NonColorFlexTokenGroup]: AuthoredFlexTokenGroups[Group]; +}; + +/** + * These are flex tokens from web that are not supported on native. + */ +export type UnsupportedFlexTokens = { + letterSpacing: { + functionalDisplay: string; + functionalPagetitle: string; + functionalTitleLarge: string; + functionalTitleMedium: string; + functionalTitleSmall: string; + functionalSubtitle: string; + functionalBodyLarge: string; + functionalBodyMedium: string; + functionalBodySmall: string; + functionalCaption: string; + contentStatement: string; + contentExpressiveLarge: string; + contentExpressiveMedium: string; + contentExpressiveSmall: string; + contentH1: string; + contentH2: string; + contentH3: string; + contentH4: string; + contentH5: string; + contentSubheadline: string; + contentParagraphLarge: string; + contentParagraphMedium: string; + contentParagraphSmall: string; + contentSubtext: string; + contentTable: string; + contentCode: string; + }; +}; diff --git a/packages/agentic/design/src/useThemeState.test.ts b/packages/agentic/design/src/flex/useThemeState.test.ts similarity index 79% rename from packages/agentic/design/src/useThemeState.test.ts rename to packages/agentic/design/src/flex/useThemeState.test.ts index a5345e49d99..ce3980b6fa5 100644 --- a/packages/agentic/design/src/useThemeState.test.ts +++ b/packages/agentic/design/src/flex/useThemeState.test.ts @@ -4,15 +4,15 @@ import { StyleSheet } from 'react-native'; import { act, create } from 'react-test-renderer'; import type { ReactTestRenderer } from 'react-test-renderer'; -import { defaultResolvedThemeAppearance } from './theming/appearance'; -import type { ThemeAppearanceSource, ThemeAppearanceSourceSnapshot } from './theming/appearance.types'; -import { ThemeContext } from './theming/context'; -import { FlexThemeReference } from './theming/flexThemeReference'; -import { ThemeProvider } from './theming/ThemeProvider'; -import type { Theme } from './theming/types/Theme.types'; -import { mockTheme } from './testing/mockTheme'; +import { defaultResolvedThemeAppearance } from '../theming/appearance'; +import type { ThemeAppearanceSource, ThemeAppearanceSourceSnapshot } from '../types/appearance.types'; +import { ThemeContext } from '../theming/context'; +import { FlexThemeReference } from './flexThemeReference'; +import { ThemeProvider } from '../theming/ThemeProvider'; +import type { Theme } from '../fluent/types/Theme.types'; +import { mockTheme } from '../test/fixtures/mockTheme'; import { themedStyleSheetFactory, useThemeAppearance, useThemeState } from './useThemeState'; -import type { ThemeState } from './useThemeState'; +import type { ThemeState } from './themeState.types'; function ThemeStateProbe({ states }: { states: ThemeState[] }) { states.push(useThemeState()); @@ -89,7 +89,7 @@ describe('useThemeState', () => { createCount += 1; return StyleSheet.create({ root: { - backgroundColor: tokens.color.backgroundNeutralSubtle, + backgroundColor: tokens.color.backgroundNeutralSubtle.rest, }, }); }); @@ -114,7 +114,7 @@ describe('useThemeState', () => { createCount += 1; return StyleSheet.create({ root: { - backgroundColor: tokens.color.backgroundNeutralSubtle, + backgroundColor: tokens.color.backgroundNeutralSubtle.rest, }, }); }); @@ -123,7 +123,7 @@ describe('useThemeState', () => { const second = getStyles(states[0]); expect(first).toBe(second); - expect(first.root.backgroundColor).toBe(states[0].tokens.color.backgroundNeutralSubtle); + expect(first.root.backgroundColor).toBe(states[0].tokens.color.backgroundNeutralSubtle.rest); expect(createCount).toBe(1); act(() => component!.unmount()); }); @@ -151,9 +151,10 @@ describe('useThemeState', () => { expect(states).toHaveLength(2); expect(states[0]).toBe(states[1]); - expect(states[0].tokens.color.backgroundNeutralSubtle).toBe('#123456'); + expect(states[0].tokens.color.backgroundNeutralSubtle.rest).toBe('#123456'); expect(states[0].highContrast).toBe(true); expect(states[0].appearance.contrast).toBe('highContrast'); + expect(states[0].appearance.colorTone).toBe('cool'); expect(Object.getOwnPropertySymbols(theme)).toEqual(initialSymbols); @@ -184,7 +185,7 @@ describe('useThemeState', () => { }); expect(states[1]).not.toBe(states[0]); - expect(states[1].tokens.color.backgroundNeutralSubtle).toBe('#222222'); + expect(states[1].tokens.color.backgroundNeutralSubtle.rest).toBe('#222222'); act(() => component!.unmount()); }); @@ -216,7 +217,7 @@ describe('useThemeState', () => { }); expect(resolver).toHaveBeenCalledTimes(1); - expect(states[0].tokens.color.backgroundBrandHeavy).toBe('#123456'); + expect(states[0].tokens.color.backgroundBrandHeavy.rest).toBe('#123456'); expect(states[0].appearance).toBe(defaultResolvedThemeAppearance); act(() => component!.unmount()); }); @@ -280,6 +281,42 @@ describe('useThemeState', () => { act(() => component!.unmount()); }); + it('keys ThemeState and theme styles by color tone', () => { + const reference = new FlexThemeReference(); + const states: ThemeState[] = []; + const render = (colorTone: 'cool' | 'warm') => + React.createElement( + ThemeProvider, + { theme: reference, appearanceSource: lightAppearanceSource, appearance: { colorTone } }, + React.createElement(ThemeStateProbe, { states }), + ); + let createCount = 0; + const getStyles = themedStyleSheetFactory('test.tone', ({ appearance }) => { + createCount += 1; + return { root: { opacity: appearance.colorTone === 'warm' ? 0.5 : 1 } }; + }); + let component: ReactTestRenderer; + + act(() => { + component = create(render('cool')); + }); + const coolState = states.at(-1)!; + act(() => component!.update(render('warm'))); + const warmState = states.at(-1)!; + + expect(warmState).not.toBe(coolState); + expect(warmState.appearance).toMatchObject({ colorScheme: 'light', colorTone: 'warm' }); + expect(warmState.themeStyles).not.toBe(coolState.themeStyles); + expect(getStyles(coolState).root.opacity).toBe(1); + expect(getStyles(warmState).root.opacity).toBe(0.5); + + act(() => component!.update(render('cool'))); + expect(states.at(-1)).toBe(coolState); + expect(getStyles(coolState).root.opacity).toBe(1); + expect(createCount).toBe(2); + act(() => component!.unmount()); + }); + it('replaces ThemeState after source invalidation', () => { const reference = new FlexThemeReference(); const states: ThemeState[] = []; diff --git a/packages/agentic/design/src/useThemeState.ts b/packages/agentic/design/src/flex/useThemeState.ts similarity index 67% rename from packages/agentic/design/src/useThemeState.ts rename to packages/agentic/design/src/flex/useThemeState.ts index 5fb9a522157..71db5db091c 100644 --- a/packages/agentic/design/src/useThemeState.ts +++ b/packages/agentic/design/src/flex/useThemeState.ts @@ -1,37 +1,13 @@ import type { ImageStyle, TextStyle, ViewStyle } from 'react-native'; -import { defaultThemeAppearanceState } from './theming/appearance'; -import type { ResolvedThemeAppearance, ThemeAppearanceState } from './theming/appearance.types'; -import { useThemeBoundary } from './theming/context'; -import { defaultThemeState, getThemeState } from './theming/themeRuntime'; -import type { FlexTokens } from './tokens/flex.types'; +import { defaultThemeAppearanceState } from '../theming/appearance'; +import { useThemeBoundary } from '../theming/context'; +import { defaultThemeState, getThemeState } from './themeState'; +import type { ThemeAppearanceState } from '../types/appearance.types'; +import type { ThemeState } from './themeState.types'; export type ThemeStyleSheet = Record<string, ViewStyle | TextStyle | ImageStyle>; -export type ThemeState = { - /** - * The set of flex tokens - */ - readonly tokens: FlexTokens; - /** - * Structured appearance values used to resolve this theme state. - */ - readonly appearance: Readonly<ResolvedThemeAppearance>; - /** - * @deprecated Use appearance.contrast. - */ - readonly highContrast: boolean; - /** - * Style sheets shared by every component instance using this theme state. - * - * Components should use a module-scoped symbol as their key and lazily store - * one immutable StyleSheet.create result whose values depend only on this - * ThemeState. Component props, interaction state, and user styles must be - * applied separately. - */ - readonly themeStyles: Record<symbol, unknown>; -}; - /** * Theme state should be consistent on object identity until a theme change or system appearance change occurs. Each new * theme state must own a new themeStyles registry so cached style sheets cannot leak across themes. diff --git a/packages/agentic/design/src/theming/__tests__/themeReference.test.ts b/packages/agentic/design/src/fluent/__tests__/themeReference.test.ts similarity index 85% rename from packages/agentic/design/src/theming/__tests__/themeReference.test.ts rename to packages/agentic/design/src/fluent/__tests__/themeReference.test.ts index 2e8c25b7439..6fd484ba7f0 100644 --- a/packages/agentic/design/src/theming/__tests__/themeReference.test.ts +++ b/packages/agentic/design/src/fluent/__tests__/themeReference.test.ts @@ -1,7 +1,7 @@ -import { mockTheme } from '../../testing'; -import type { Theme, Spacing, PartialTheme } from '../index'; +import { mockTheme } from '../../test'; +import type { Theme, Spacing, PartialTheme } from '../../theming/index'; -import { defaultResolvedThemeAppearance } from '../appearance'; +import { defaultResolvedThemeAppearance } from '../../theming/appearance'; import { ThemeReference } from '../themeReference'; const themeBase = mockTheme; @@ -42,6 +42,23 @@ describe('ThemeReference tests', () => { expect(themeRef.resolveTheme(defaultResolvedThemeAppearance)).not.toBe(before); }); + it('passes a concrete color tone to transforms and keys warm separately', () => { + const tones: unknown[] = []; + const themeRef = new ThemeReference(themeBase, (_theme, appearance) => { + tones.push(appearance?.colorTone); + return { colors: { white: appearance?.colorTone === 'warm' ? 'peach' : 'white' } }; + }); + const threeField = { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base' } as const; + const omitted = themeRef.resolveTheme(threeField); + + expect(themeRef.resolveTheme({ ...threeField, colorTone: 'cool' })).toBe(omitted); + const warm = themeRef.resolveTheme({ ...threeField, colorTone: 'warm' }); + expect(warm).not.toBe(omitted); + expect(warm.colors.white).toBe('peach'); + expect(omitted.colors.white).toBe('white'); + expect(tones).toEqual(['cool', 'warm']); + }); + it('performs a simple merge', () => { const themeRef = new ThemeReference(themeBase, { colors: { diff --git a/packages/agentic/design/src/fluent/__tests__/theming-utils.test.ts b/packages/agentic/design/src/fluent/__tests__/theming-utils.test.ts new file mode 100644 index 00000000000..10f542aa4c9 --- /dev/null +++ b/packages/agentic/design/src/fluent/__tests__/theming-utils.test.ts @@ -0,0 +1,31 @@ +import { getCurrentAppearance } from '../../theming'; + +const fallBackAppearance = 'light'; + +beforeAll(() => { + jest.mock('react-native/Libraries/Utilities/Appearance', () => ({ + getColorScheme: () => 'dark', + })); +}); + +describe('getCurrentAppearanceTable test', () => { + it('light', () => { + expect(getCurrentAppearance('light', fallBackAppearance)).toBe('light'); + }); + + it('dark', () => { + expect(getCurrentAppearance('dark', fallBackAppearance)).toBe('dark'); + }); + + it('highContrast', () => { + expect(getCurrentAppearance('highContrast', fallBackAppearance)).toBe('highContrast'); + }); + + it('dynamic', () => { + expect(getCurrentAppearance('dynamic', fallBackAppearance)).toBe('dark'); + }); + + it('undefined', () => { + expect(getCurrentAppearance(undefined, fallBackAppearance)).toBe(fallBackAppearance); + }); +}); diff --git a/packages/agentic/design/src/fluent/compat/index.ts b/packages/agentic/design/src/fluent/compat/index.ts new file mode 100644 index 00000000000..d730c0c4db0 --- /dev/null +++ b/packages/agentic/design/src/fluent/compat/index.ts @@ -0,0 +1,2 @@ +export { themeFromFlexTokens } from './themeFromFlexTokens'; +export type { FlatFlexTokens, ThemeFromFlexTokensOptions } from './themeFromFlexTokens'; diff --git a/packages/agentic/design/src/fluent/compat/themeFromFlexTokens.test.ts b/packages/agentic/design/src/fluent/compat/themeFromFlexTokens.test.ts new file mode 100644 index 00000000000..b73e2c2083a --- /dev/null +++ b/packages/agentic/design/src/fluent/compat/themeFromFlexTokens.test.ts @@ -0,0 +1,216 @@ +import { createInteractiveColor } from '../../flex/colors/interactiveColor'; +import { defaultFlexTokens } from '../../flex/defaults/defaultTokens'; +import type { FlexTokens, SemanticColorTokenValues } from '../../flex/tokens.types'; +import { restColorValues } from '../../test/fixtures/interactionColors'; +import { fluentDarkTheme } from '../../themes/fluent/fluentDarkTheme'; +import { fluentHcDarkTheme } from '../../themes/fluent/fluentHcDarkTheme'; +import { fluentHcLightTheme } from '../../themes/fluent/fluentHcLightTheme'; +import { fluentLightTheme } from '../../themes/fluent/fluentLightTheme'; +import reverseProjection from '../../tokens/mappings/theme-from-flex.json' with { type: 'json' }; +import type { ResolvedThemeAppearance } from '../../types/appearance.types'; +import type { PartialTheme, Theme } from '../types/Theme.types'; + +import { themeFromFlexTokens } from './themeFromFlexTokens'; +import type { FlatFlexTokens } from './themeFromFlexTokens'; + +const light = { + colorScheme: 'light', + contrast: 'standard', + interfaceLevel: 'base', +} as const; +const dark = { ...light, colorScheme: 'dark' } as const; + +function solid(value: string) { + return createInteractiveColor(value, value, value); +} + +function createTokens(): FlexTokens { + return { + ...defaultFlexTokens, + color: { + ...defaultFlexTokens.color, + backgroundBrandSoft: solid('#111111'), + backgroundBrandSubtle: solid('#222222'), + backgroundNeutralSubtle: solid('#333333'), + surfaceNeutralNear: createInteractiveColor('#444444', '#454545', '#464646'), + fixedBlack: solid('#050505'), + expressionAchromaticHeavy: solid('#060606'), + }, + borderRadius: { + ...defaultFlexTokens.borderRadius, + base200: 12, + base300: 24, + }, + fontWeight: { + ...defaultFlexTokens.fontWeight, + functionalSemibold: '700', + contentBold: '900', + }, + }; +} + +describe('themeFromFlexTokens', () => { + it.each([ + [light, fluentLightTheme], + [dark, fluentDarkTheme], + [{ ...dark, interfaceLevel: 'elevated' }, fluentDarkTheme], + [{ ...light, contrast: 'highContrast' }, fluentHcLightTheme], + [{ ...dark, contrast: 'highContrast' }, fluentHcDarkTheme], + ] as [ResolvedThemeAppearance, Theme][])('fills values Flex cannot represent from the Fluent theme for %o', (appearance, base) => { + const baseline = JSON.stringify(base); + const projectedPaths = new Set(Object.keys(reverseProjection)); + const unmappedColors = Object.keys(base.colors).filter((name) => !projectedPaths.has(`colors.${name}`)); + + const theme = themeFromFlexTokens(createTokens(), appearance, { + fallback: { colors: { customLegacyColor: '#abcdef' } } as PartialTheme, + }); + + expect(unmappedColors.length).toBeGreaterThan(0); + for (const name of unmappedColors) { + expect([name, theme.colors[name]]).toEqual([name, base.colors[name]]); + } + expect(theme.typography.variants).toEqual(base.typography.variants); + expect(theme.spacing).toEqual(base.spacing); + expect(theme).not.toBe(base); + expect(JSON.stringify(base)).toBe(baseline); + }); + + it('merges the base, legacy fallback, mapped Flex values, and final appearance in order', () => { + const fallback = { + name: 'Host theme', + colors: { + brandBackground2: '#777777', + customLegacyColor: '#abcdef', + }, + components: { + Button: { + tokens: { + borderRadius: 2, + legacyOnlyMetric: 42, + }, + }, + }, + host: { + appearance: 'dynamic', + palette: { + Bkg: '#101010', + }, + colors: { + AppPrimary: '#202020', + }, + }, + } as PartialTheme; + + const theme = themeFromFlexTokens(createTokens(), light, { fallback }); + + expect(theme.name).toBe('Host theme'); + expect(theme.colors.customLegacyColor).toBe('#abcdef'); + expect(theme.colors.brandBackground2).toBe('#111111'); + expect(theme.colors.neutralBackground2).toBe('#444444'); + expect(theme.colors.neutralBackground2Hover).toBe('#454545'); + expect(theme.colors.neutralBackground2Pressed).toBe('#464646'); + expect(theme.colors.black).toBe('#050505'); + expect(theme.components.Button.tokens).toMatchObject({ + borderRadius: 12, + legacyOnlyMetric: 42, + }); + expect(theme.host.palette?.Bkg).toBe('#101010'); + expect(theme.host.colors?.AppPrimary).toBe('#202020'); + expect(theme.host.appearance).toBe('light'); + expect(theme.typography.weights.semiBold).toBe('700'); + }); + + it('uses declared canonical sources when several Flex roles share one legacy path', () => { + const theme = themeFromFlexTokens(createTokens(), light); + + expect(theme.colors.brandBackground2).toBe('#111111'); + expect(theme.colors.neutralBackground2).toBe('#444444'); + expect(theme.colors.black).toBe('#050505'); + expect(theme.components.Button).toMatchObject({ + tokens: { + borderRadius: 12, + }, + }); + expect(theme.typography.weights.semiBold).toBe('700'); + }); + + it('does not mutate frozen author inputs and returns a fresh legacy root', () => { + const tokens = Object.freeze(createTokens()); + const fallback = Object.freeze({ + colors: Object.freeze({ + customLegacyColor: '#abcdef', + }), + }) as PartialTheme; + + const first = themeFromFlexTokens(tokens, light, { fallback }); + const second = themeFromFlexTokens(tokens, light, { fallback }); + + expect(first).not.toBe(second); + expect(first.colors.customLegacyColor).toBe('#abcdef'); + expect(tokens.color.surfaceNeutralNear.rest).toBe('#444444'); + }); + + it('accepts the deprecated flat representation with optional state maps', () => { + const color: FlatFlexTokens['color'] = { + ...restColorValues(defaultFlexTokens.color), + surfaceNeutralNear: '#444444', + backgroundBrandHeavy: '#0f6cbd', + hover: { backgroundBrandHeavy: '#115ea3' } satisfies Partial<SemanticColorTokenValues>, + }; + const flat: FlatFlexTokens = { ...defaultFlexTokens, color }; + + const theme = themeFromFlexTokens(flat, light); + + expect(theme.colors.neutralBackground2).toBe('#444444'); + expect(theme.colors.neutralBackground2Hover).toBe('#444444'); + expect(theme.colors.brandBackground).toBe('#0f6cbd'); + expect(theme.colors.brandBackgroundHover).toBe('#115ea3'); + expect(theme.colors.brandBackgroundPressed).toBe('#0f6cbd'); + }); + + it('projects layered shadows lossily to legacy { ambient, key } shadows', () => { + const contour = { x: 0, y: 0, blur: 2, color: '#0000001a' }; + const middle = { x: 0, y: 1, blur: 2, color: '#0000000d' }; + const keyLayer = { x: 0, y: 4, blur: 8, color: '#00000014' }; + const tokens: FlexTokens = { + ...createTokens(), + shadow: { ...defaultFlexTokens.shadow, lowest: [contour, middle, keyLayer], lower: [keyLayer], low: [] }, + }; + + const theme = themeFromFlexTokens(tokens, light); + + expect(theme.shadows.shadow2).toEqual({ ambient: contour, key: keyLayer }); + expect(theme.shadows.shadow4).toEqual({ ambient: keyLayer, key: keyLayer }); + expect(theme.shadows.shadow8).toEqual(fluentLightTheme.shadows.shadow8); + expect(theme.shadows.shadow16).toEqual({ ambient: defaultFlexTokens.shadow.high[0], key: defaultFlexTokens.shadow.high.at(-1) }); + }); + + it('accepts the pre-interactive flat representation, including legacy { ambient, key } shadows', () => { + const legacy = { ambient: { x: 0, y: 0, blur: 2, color: 'black' }, key: { x: 0, y: 2, blur: 4, color: 'red' } }; + const { motion: _motion, spacing, ...groups } = defaultFlexTokens; + const { componentBase800: _componentBase800, ...previousSpacing } = spacing; + const flat: FlatFlexTokens = { + ...groups, + color: restColorValues(defaultFlexTokens.color), + shadow: { ...defaultFlexTokens.shadow, lowest: legacy }, + spacing: previousSpacing, + }; + + expect(themeFromFlexTokens(flat, light).shadows.shadow2).toEqual(legacy); + }); + + it('projects the same legacy theme from resolved and equivalent flat tokens', () => { + const resolved = themeFromFlexTokens(defaultFlexTokens, light); + const values = restColorValues(defaultFlexTokens.color); + const flat: FlatFlexTokens = { + ...defaultFlexTokens, + color: { + ...values, + hover: Object.fromEntries(Object.entries(defaultFlexTokens.color).map(([name, entry]) => [name, entry.hover])), + pressed: Object.fromEntries(Object.entries(defaultFlexTokens.color).map(([name, entry]) => [name, entry.pressed])), + }, + }; + + expect(themeFromFlexTokens(flat, light)).toEqual(resolved); + }); +}); diff --git a/packages/agentic/design/src/fluent/compat/themeFromFlexTokens.ts b/packages/agentic/design/src/fluent/compat/themeFromFlexTokens.ts new file mode 100644 index 00000000000..f79b5fdc15c --- /dev/null +++ b/packages/agentic/design/src/fluent/compat/themeFromFlexTokens.ts @@ -0,0 +1,147 @@ +import type { FlexTokens, SemanticColorTokenValues, SemanticMotion, SemanticShadows, SemanticSpacing } from '../../flex/tokens.types'; +import { selectFluentTheme } from '../../themes/fluent/selectFluentTheme'; +import reverseProjection from '../../tokens/mappings/theme-from-flex.json' with { type: 'json' }; +import { appearanceOptionFromResolved } from '../../theming/appearance'; +import type { ResolvedThemeAppearance } from '../../types/appearance.types'; +import { ensureParentRecord, getValueAtSegments, isRecord, splitObjectPath } from '../../utilities/objects'; +import { mergeTheme } from '../mergeTheme'; +import type { ShadowToken } from '../types/Shadow.types'; +import type { PartialTheme, Theme } from '../types/Theme.types'; + +type ReverseTransform = 'numberToPx' | 'shadowLayersToToken'; + +type ReverseProjectionEntry = { + source: string; + fallback?: string; + transform?: ReverseTransform; +}; + +export interface ThemeFromFlexTokensOptions { + fallback?: Theme | PartialTheme; +} + +/** + * Flex tokens in the representation used before interactive colors: each color + * is its rest value, optional `color.hover` and `color.pressed` maps hold + * explicit states, a shadow may be a legacy `{ ambient, key }` token, and the + * later `motion` group and `spacing.componentBase800` may be absent. + * + * @deprecated Pass resolved {@link FlexTokens}, whose colors carry + * `rest`, `hover`, and `pressed`. + */ +export type FlatFlexTokens = Omit<FlexTokens, 'color' | 'shadow' | 'spacing' | 'motion'> & { + color: SemanticColorTokenValues & { + hover?: Partial<SemanticColorTokenValues>; + pressed?: Partial<SemanticColorTokenValues>; + }; + shadow: { [Name in keyof SemanticShadows]: SemanticShadows[Name] | ShadowToken }; + spacing: Omit<SemanticSpacing, 'componentBase800'> & Partial<Pick<SemanticSpacing, 'componentBase800'>>; + motion?: SemanticMotion; +}; + +const colorStatePathPattern = /^color\.([^.]+)\.(rest|hover|pressed)$/; + +function getOwnValue(source: unknown, key: string): unknown { + return isRecord(source) && Object.prototype.hasOwnProperty.call(source, key) ? source[key] : undefined; +} + +/** + * Read a color state from resolved tokens, or from the flat representation + * where the color is its rest value and states live in `color.<state>` maps. + */ +function getColorState(tokens: FlexTokens | FlatFlexTokens, name: string, state: string): unknown { + const colors = getOwnValue(tokens, 'color'); + const entry = getOwnValue(colors, name); + if (isRecord(entry) && Object.prototype.hasOwnProperty.call(entry, 'rest')) { + return entry[state]; + } + return state === 'rest' ? entry : getOwnValue(getOwnValue(colors, state), name); +} + +function getPathSegments(path: string): string[] { + return splitObjectPath(path, () => new Error(`Invalid generated theme projection path "${path}".`)); +} + +function getValueAtPath(source: FlexTokens | FlatFlexTokens, path: string): unknown { + const colorState = colorStatePathPattern.exec(path); + if (colorState) { + return getColorState(source, colorState[1], colorState[2]); + } + return getValueAtSegments(source, getPathSegments(path)); +} + +// Later projection entries overwrite earlier leaves; conflicting parents are generator errors. +function setValueAtPath(destination: Record<string, unknown>, path: string, value: unknown): void { + const segments = getPathSegments(path); + const target = ensureParentRecord(destination, segments, () => new Error(`Cannot create generated theme projection path "${path}".`)); + target[segments[segments.length - 1]] = value; +} + +function shadowLayersToToken(value: unknown): unknown { + if (!Array.isArray(value)) { + // Pass through a legacy { ambient, key } shadow. + return value; + } + if (value.length === 0) { + return undefined; + } + return { ambient: value[0], key: value[value.length - 1] }; +} + +function applyTransform(value: unknown, transform?: ReverseTransform): unknown { + if (!transform) { + return value; + } + if (transform === 'numberToPx') { + return typeof value === 'number' ? `${value}px` : value; + } + if (transform === 'shadowLayersToToken') { + return shadowLayersToToken(value); + } + return value; +} + +function projectThemeValues(tokens: FlexTokens | FlatFlexTokens): PartialTheme { + const projected: Record<string, unknown> = {}; + for (const [themePath, descriptor] of Object.entries(reverseProjection as Record<string, ReverseProjectionEntry>)) { + let value = getValueAtPath(tokens, descriptor.source); + if (value === undefined && descriptor.fallback) { + value = getValueAtPath(tokens, descriptor.fallback); + } + if (value !== undefined) { + value = applyTransform(value, descriptor.transform); + } + if (value !== undefined) { + setValueAtPath(projected, themePath, value); + } + } + return projected as PartialTheme; +} + +/** + * Project Flex tokens into a complete legacy Theme. + * + * The Fluent theme for the appearance fills values that Flex cannot represent, + * the optional fallback adds author or host metadata, mapped Flex values remain + * authoritative, and the final host appearance reflects the resolved + * structured appearance. Reading a derived interaction state computes it. + * Layered Flex shadows project lossily to legacy { ambient, key } shadows: the + * first layer is ambient, the last is key, and middle layers are dropped. An + * empty shadow keeps the Fluent theme's shadow. + */ +export function themeFromFlexTokens( + tokens: FlexTokens | FlatFlexTokens, + appearance: ResolvedThemeAppearance, + options?: { fallback?: Theme | PartialTheme }, +): Theme { + let theme = selectFluentTheme(appearance); + if (options?.fallback) { + theme = mergeTheme(theme, options.fallback as PartialTheme); + } + theme = mergeTheme(theme, projectThemeValues(tokens)); + return mergeTheme(theme, { + host: { + appearance: appearanceOptionFromResolved(appearance), + }, + }); +} diff --git a/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.android.ts b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.android.ts new file mode 100644 index 00000000000..79896570831 --- /dev/null +++ b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.android.ts @@ -0,0 +1,523 @@ +/** + * WARNING: This file is auto-generated by scripts/fluent-tokens.cts. Do not edit it manually. + * Complete Fluent tokens: native values, same-platform equivalents, then same-scheme portable defaults. + * An appearance without token data inherits elevated from standard, and high contrast from the other + * high-contrast appearance, else from standard. Shared values are emitted once. + */ +import type { AliasColorTokens } from '../types/Color.types'; +import type { BaseShadowAliasTokens } from '../types/Shadow.types'; +import type { Variants } from '../types/Typography.types'; + +const Roboto = 'Roboto'; +const fontWeight400 = '400'; +const fontWeight500 = '500'; +const rgb000000 = '#000000'; +const rgb00000000 = '#00000000'; +const rgb0000001f = '#0000001f'; +const rgb00000024 = '#00000024'; +const rgb00000040 = '#00000040'; +const rgb0000004d = '#0000004d'; +const rgb0c3b5e = '#0c3b5e'; +const rgb0e4775 = '#0e4775'; +const rgb0e700e = '#0e700e'; +const rgb0f548c = '#0f548c'; +const rgb0f6cbd = '#0f6cbd'; +const rgb107c10 = '#107c10'; +const rgb1f1f1f = '#1f1f1f'; +const rgb242424 = '#242424'; +const rgb2886de = '#2886de'; +const rgb292929 = '#292929'; +const rgb2e2e2e = '#2e2e2e'; +const rgb333333 = '#333333'; +const rgb359b35 = '#359b35'; +const rgb3d3d3d = '#3d3d3d'; +const rgb3f1011 = '#3f1011'; +const rgb424242 = '#424242'; +const rgb479ef5 = '#479ef5'; +const rgb4d4d4d = '#4d4d4d'; +const rgb54b054 = '#54b054'; +const rgb575757 = '#575757'; +const rgb5c5c5c = '#5c5c5c'; +const rgb616161 = '#616161'; +const rgb6d2064 = '#6d2064'; +const rgb77b7f7 = '#77b7f7'; +const rgb808080 = '#808080'; +const rgb817400 = '#817400'; +const rgb96c6fa = '#96c6fa'; +const rgb9e9e9e = '#9e9e9e'; +const rgb9fd89f = '#9fd89f'; +const rgbadadad = '#adadad'; +const rgbb4d6fa = '#b4d6fa'; +const rgbbc2f32 = '#bc2f32'; +const rgbbdbdbd = '#bdbdbd'; +const rgbc0ad00 = '#c0ad00'; +const rgbc239b3 = '#c239b3'; +const rgbc43501 = '#c43501'; +const rgbd13438 = '#d13438'; +const rgbd161c4 = '#d161c4'; +const rgbd1d1d1 = '#d1d1d1'; +const rgbd6d6d6 = '#d6d6d6'; +const rgbda3b01 = '#da3b01'; +const rgbda7ed0 = '#da7ed0'; +const rgbdbdbdb = '#dbdbdb'; +const rgbdc5e62 = '#dc5e62'; +const rgbde501c = '#de501c'; +const rgbe0e0e0 = '#e0e0e0'; +const rgbe36537 = '#e36537'; +const rgbe37d80 = '#e37d80'; +const rgbe6e6e6 = '#e6e6e6'; +const rgbe9835e = '#e9835e'; +const rgbebebeb = '#ebebeb'; +const rgbedbbe7 = '#edbbe7'; +const rgbf0f0f0 = '#f0f0f0'; +const rgbf5f5f5 = '#f5f5f5'; +const rgbfafafa = '#fafafa'; +const rgbfde300 = '#fde300'; +const rgbfdea3d = '#fdea3d'; +const rgbfdf6f6 = '#fdf6f6'; +const rgbfeee66 = '#feee66'; +const rgbffffff = '#ffffff'; + +const body1 = { face: Roboto, size: 16, weight: fontWeight400, lineHeight: 24, letterSpacing: 0 } as const; +const body1Strong = { face: Roboto, size: 16, weight: fontWeight500, lineHeight: 24, letterSpacing: 0 } as const; +const body2 = { face: Roboto, size: 14, weight: fontWeight400, lineHeight: 18, letterSpacing: 0 } as const; +const body2Strong = { face: Roboto, size: 14, weight: fontWeight500, lineHeight: 18, letterSpacing: 0 } as const; +const caption1 = { face: Roboto, size: 13, weight: fontWeight400, lineHeight: 16, letterSpacing: 0 } as const; +const display = { face: Roboto, size: 60, weight: fontWeight400, lineHeight: 72, letterSpacing: -0.5 } as const; +const largeTitle = { face: Roboto, size: 34, weight: fontWeight400, lineHeight: 48, letterSpacing: -0.25 } as const; +const shadowLayer1 = { color: rgb0000001f, x: 0, y: 0, blur: 2 } as const; +const shadowLayer2 = { color: rgb0000001f, x: 0, y: 0, blur: 8 } as const; +const shadowLayer3 = { color: rgb0000004d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer4 = { color: rgb0000004d, x: 0, y: 0, blur: 8 } as const; +const subtitle1Strong = { face: Roboto, size: 20, weight: '600', lineHeight: 24, letterSpacing: 0 } as const; +const subtitle2Strong = { face: Roboto, size: 18, weight: '600', lineHeight: 24, letterSpacing: 0 } as const; +const title1 = { face: Roboto, size: 24, weight: fontWeight400, lineHeight: 32, letterSpacing: 0 } as const; +const title1Strong = { face: Roboto, size: 24, weight: '600', lineHeight: 32, letterSpacing: 0 } as const; +const title2 = { face: Roboto, size: 20, weight: fontWeight500, lineHeight: 24, letterSpacing: 0 } as const; +const title3 = { face: Roboto, size: 18, weight: fontWeight500, lineHeight: 24, letterSpacing: 0 } as const; + +const sharedAliasColors = { + neutralForegroundInverted: rgbffffff, + neutralForegroundInvertedLink: rgbffffff, + brandForeground1Disabled: rgb2886de, + brandForegroundDisabled1: rgb2886de, + brandBackgroundInverted: rgbffffff, + dangerStroke1: rgbdc5e62, + successStroke1: rgb359b35, + dangerBorder1: rgbdc5e62, + successBorder1: rgb359b35, + presenceAway: '#eaa300', + redBackground3: rgbd13438, + redBorder1: rgbdc5e62, + neutralForegroundOnBrandHover: rgbffffff, + neutralForegroundOnBrandPressed: rgbffffff, + neutralForegroundOnBrandSelected: rgbffffff, + subtleBackground: rgb00000000, + transparentBackground: rgb00000000, + transparentBackgroundHover: rgb00000000, + transparentBackgroundPressed: rgb00000000, + transparentBackgroundSelected: rgb00000000, + transparentStroke: rgb00000000, + transparentStrokeInteractive: rgb00000000, + transparentStrokeDisabled: rgb00000000, + dangerBackground3: rgbd13438, + successBackground3: rgb107c10, + warningBackground3: rgbfde300, + severeBackground3: rgbda3b01, + outofofficeBackground3: rgbc239b3, + neutralBackgroundLightStatic: rgbffffff, + neutralForegroundDarkStatic: rgb000000, + neutralForegroundLightStatic: rgbffffff, +} as const; + +export const lightShadows: BaseShadowAliasTokens = { + shadow2: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer2, key: { color: rgb00000024, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer2, key: { color: rgb00000024, x: 0, y: 32, blur: 64 } }, + shadow2brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 1, blur: 2 } }, + shadow4brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 2, blur: 4 } }, + shadow8brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 4, blur: 8 } }, + shadow16brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 8, blur: 16 } }, + shadow28brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 14, blur: 28 } }, + shadow64brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 32, blur: 64 } }, +}; + +export const darkShadows: BaseShadowAliasTokens = lightShadows; +export const lightElevatedShadows: BaseShadowAliasTokens = lightShadows; +export const darkElevatedShadows: BaseShadowAliasTokens = lightShadows; +export const hcLightShadows: BaseShadowAliasTokens = lightShadows; +export const hcDarkShadows: BaseShadowAliasTokens = lightShadows; + +export const lightAliasColors: Required<AliasColorTokens> = { + ...sharedAliasColors, + neutralForeground4: rgb808080, + neutralForegroundDisabled: rgbbdbdbd, + neutralForegroundDisabled1: rgbbdbdbd, + neutralForegroundDisabled2: rgbffffff, + neutralForegroundOnBrand: rgbffffff, + neutralForegroundOnColor: rgbffffff, + brandForegroundLink: rgb0f6cbd, + compoundBrandForeground1: rgb0f6cbd, + brandForeground2: rgb0f6cbd, + brandForegroundTint: rgb0f548c, + brandForegroundDisabled2: rgbb4d6fa, + neutralBackgroundCanvas: rgbf5f5f5, + neutralBackgroundLightStaticDisabled: rgbffffff, + brandBackground2: '#115ea3', + brandBackground3: rgb0f548c, + brandBackgroundTint: '#cfe4fa', + brandBackgroundInvertedDisabled: rgbffffff, + brandBackgroundDisabled: rgbb4d6fa, + compoundBrandBackground1: rgb0f6cbd, + brandBackgroundStatic: rgb0f6cbd, + neutralStroke3: rgbe0e0e0, + neutralStrokeFocus1: rgbffffff, + neutralStrokeFocus2: rgb000000, + strokeFocus1: rgbffffff, + strokeFocus2: rgb000000, + brandStroke2: rgb2886de, + brandStrokeTint: rgb2886de, + compoundBrandStroke1: rgb0f6cbd, + warningStroke1: rgb817400, + severeStroke1: rgbde501c, + warningBorder1: rgb817400, + severeBorder1: rgbde501c, + presenceDnd: rgbd13438, + presenceAvailable: '#13a10e', + presenceOof: rgbc239b3, + redBackground1: rgbfdf6f6, + redBackground2: rgbd13438, + redForeground1: rgbbc2f32, + redForeground2: rgbd13438, + redForeground3: rgbd13438, + redBorderActive: rgbd13438, + redBorder2: rgbd13438, + neutralForeground1: rgb242424, + neutralForeground1Hover: rgb242424, + neutralForeground1Pressed: rgb242424, + neutralForeground1Selected: rgb242424, + neutralForeground2: rgb616161, + neutralForeground2Hover: rgb616161, + neutralForeground2Pressed: rgb616161, + neutralForeground2Selected: rgb616161, + neutralForeground2BrandHover: rgb616161, + neutralForeground2BrandPressed: rgb616161, + neutralForeground2BrandSelected: rgb616161, + neutralForeground3: rgb808080, + neutralForeground3Hover: rgb808080, + neutralForeground3Pressed: rgb808080, + neutralForeground3Selected: rgb808080, + neutralForeground3BrandHover: rgb808080, + neutralForeground3BrandPressed: rgb808080, + neutralForeground3BrandSelected: rgb808080, + brandForegroundLinkHover: rgb0f6cbd, + brandForegroundLinkPressed: rgb0e4775, + brandForegroundLinkSelected: rgb0f548c, + compoundBrandForeground1Hover: rgb0f6cbd, + compoundBrandForeground1Pressed: rgb0e4775, + brandForeground1: rgb0f6cbd, + neutralForegroundInvertedLinkHover: rgbffffff, + neutralForegroundInvertedLinkPressed: rgbffffff, + neutralForegroundInvertedLinkSelected: rgbffffff, + neutralBackground1: rgbffffff, + neutralBackground1Hover: rgbffffff, + neutralBackground1Pressed: rgbe0e0e0, + neutralBackground1Selected: rgbebebeb, + neutralBackground2: rgbffffff, + neutralBackground2Hover: rgbffffff, + neutralBackground2Pressed: rgbe0e0e0, + neutralBackground2Selected: rgbebebeb, + neutralBackground3: rgbffffff, + neutralBackground3Hover: rgbffffff, + neutralBackground3Pressed: rgbe0e0e0, + neutralBackground3Selected: rgbebebeb, + neutralBackground4: rgbfafafa, + neutralBackground4Hover: rgbfafafa, + neutralBackground4Pressed: rgbdbdbdb, + neutralBackground4Selected: rgbe6e6e6, + neutralBackground5: rgbf0f0f0, + neutralBackground5Hover: rgbf0f0f0, + neutralBackground5Pressed: rgbd1d1d1, + neutralBackground5Selected: rgbdbdbdb, + neutralBackground6: rgbd1d1d1, + neutralBackgroundInverted: '#757575', + subtleBackgroundHover: rgbf5f5f5, + subtleBackgroundPressed: rgbe0e0e0, + subtleBackgroundSelected: rgbebebeb, + neutralBackgroundDisabled: rgbe0e0e0, + neutralStencil1: rgbe6e6e6, + neutralStencil2: rgbfafafa, + brandBackground: rgb0f6cbd, + brandBackgroundHover: rgb0f6cbd, + brandBackgroundPressed: rgb0e4775, + brandBackgroundSelected: rgb0f548c, + compoundBrandBackground1Hover: rgb0f6cbd, + compoundBrandBackground1Pressed: rgb0e4775, + neutralStrokeAccessible: rgb616161, + neutralStrokeAccessibleHover: rgb616161, + neutralStrokeAccessiblePressed: rgb616161, + neutralStrokeAccessibleSelected: rgb616161, + neutralStroke1: rgbd1d1d1, + neutralStroke1Hover: rgbd1d1d1, + neutralStroke1Pressed: rgbd1d1d1, + neutralStroke1Selected: rgbd1d1d1, + neutralStroke2: rgbe0e0e0, + brandStroke1: rgb0f6cbd, + compoundBrandStroke1Hover: rgb0f6cbd, + compoundBrandStroke1Pressed: rgb0e4775, + neutralStrokeDisabled: rgbe0e0e0, + dangerBackground1: rgbfdf6f6, + dangerBackground2: rgbd13438, + dangerForeground1: rgbbc2f32, + dangerForeground2: rgbd13438, + dangerForeground3: rgbd13438, + dangerForegroundInverted: rgbdc5e62, + dangerBorderActive: rgbd13438, + dangerBorder2: rgbd13438, + successBackground1: '#f1faf1', + successBackground2: rgb107c10, + successForeground1: rgb0e700e, + successForeground2: rgb107c10, + successForeground3: rgb107c10, + successForegroundInverted: rgb359b35, + successBorderActive: rgb107c10, + successBorder2: rgb107c10, + warningBackground1: '#fffef5', + warningBackground2: rgbfde300, + warningForeground1: rgb817400, + warningForeground2: rgb817400, + warningForeground3: rgbfde300, + warningForegroundInverted: '#fef7b2', + warningBorderActive: rgbfde300, + warningBorder2: rgbfde300, + severeBackground1: '#fdf6f3', + severeBackground2: rgbda3b01, + severeForeground1: rgbc43501, + severeForeground2: rgbc43501, + severeForeground3: rgbda3b01, + severeBorderActive: rgbda3b01, + severeBorder2: rgbda3b01, + outofofficeBackground1: '#fdf5fc', + outofofficeBackground2: rgbedbbe7, + outofofficeForeground1: '#af33a1', + outofofficeForeground2: rgb6d2064, + outofofficeForeground3: rgbc239b3, + outofofficeBorderActive: rgbc239b3, + outofofficeBorder1: rgbedbbe7, + outofofficeBorder2: rgbc239b3, + brandForeground1Pressed: rgb0e4775, + neutralBackgroundDarkStatic: rgb242424, + brandBackground2Pressed: rgb0c3b5e, + brandBackground2Selected: rgb0e4775, + brandForeground1Selected: rgb0f548c, + brandStroke1Pressed: rgb0e4775, + brandStroke1Selected: rgb0f548c, +}; + +export const darkAliasColors: Required<AliasColorTokens> = { + ...sharedAliasColors, + neutralForeground4: rgbadadad, + neutralForegroundDisabled: rgb5c5c5c, + neutralForegroundDisabled1: rgb5c5c5c, + neutralForegroundDisabled2: rgb2e2e2e, + neutralForegroundOnBrand: rgb000000, + neutralForegroundOnColor: rgb000000, + brandForegroundLink: rgb479ef5, + compoundBrandForeground1: rgb479ef5, + brandForeground2: rgb479ef5, + brandForegroundTint: rgb96c6fa, + brandForegroundDisabled2: rgb0c3b5e, + neutralBackgroundCanvas: '#141414', + neutralBackgroundLightStaticDisabled: rgbadadad, + brandBackground2: rgb479ef5, + brandBackground3: rgb479ef5, + brandBackgroundTint: rgb0c3b5e, + brandBackgroundInvertedDisabled: rgbadadad, + brandBackgroundDisabled: rgb0c3b5e, + compoundBrandBackground1: rgb479ef5, + brandBackgroundStatic: rgb479ef5, + neutralStroke3: rgb3d3d3d, + neutralStrokeFocus1: rgb000000, + neutralStrokeFocus2: rgbffffff, + strokeFocus1: rgb000000, + strokeFocus2: rgbffffff, + brandStroke2: rgb479ef5, + brandStrokeTint: rgb479ef5, + compoundBrandStroke1: rgb479ef5, + warningStroke1: rgbc0ad00, + severeStroke1: rgbe36537, + warningBorder1: rgbc0ad00, + severeBorder1: rgbe36537, + presenceDnd: '#d7494c', + presenceAvailable: '#3db838', + presenceOof: rgbd161c4, + redBackground1: rgb3f1011, + redBackground2: rgbbc2f32, + redForeground1: rgbe37d80, + redForeground2: rgbe37d80, + redForeground3: rgbe37d80, + redBorderActive: rgbe37d80, + redBorder2: rgbdc5e62, + neutralForeground1: rgbffffff, + neutralForeground1Hover: rgbffffff, + neutralForeground1Pressed: rgbffffff, + neutralForeground1Selected: rgbffffff, + neutralForeground2: rgbd6d6d6, + neutralForeground2Hover: rgbd6d6d6, + neutralForeground2Pressed: rgbd6d6d6, + neutralForeground2Selected: rgbd6d6d6, + neutralForeground2BrandHover: rgbd6d6d6, + neutralForeground2BrandPressed: rgbd6d6d6, + neutralForeground2BrandSelected: rgbd6d6d6, + neutralForeground3: rgbadadad, + neutralForeground3Hover: rgbadadad, + neutralForeground3Pressed: rgbadadad, + neutralForeground3Selected: rgbadadad, + neutralForeground3BrandHover: rgbadadad, + neutralForeground3BrandPressed: rgbadadad, + neutralForeground3BrandSelected: rgbadadad, + brandForegroundLinkHover: rgb479ef5, + brandForegroundLinkPressed: rgb96c6fa, + brandForegroundLinkSelected: rgb77b7f7, + compoundBrandForeground1Hover: rgb479ef5, + compoundBrandForeground1Pressed: rgb96c6fa, + brandForeground1: rgb479ef5, + neutralForegroundInvertedLinkHover: rgb000000, + neutralForegroundInvertedLinkPressed: rgb000000, + neutralForegroundInvertedLinkSelected: rgb000000, + neutralBackground1: rgb000000, + neutralBackground1Hover: rgb000000, + neutralBackground1Pressed: rgb2e2e2e, + neutralBackground1Selected: rgb242424, + neutralBackground2: rgb1f1f1f, + neutralBackground2Hover: rgb1f1f1f, + neutralBackground2Pressed: rgb4d4d4d, + neutralBackground2Selected: rgb424242, + neutralBackground3: rgb292929, + neutralBackground3Hover: rgb292929, + neutralBackground3Pressed: rgb575757, + neutralBackground3Selected: rgb4d4d4d, + neutralBackground4: rgb333333, + neutralBackground4Hover: rgb333333, + neutralBackground4Pressed: rgb616161, + neutralBackground4Selected: rgb575757, + neutralBackground5: rgb3d3d3d, + neutralBackground5Hover: rgb3d3d3d, + neutralBackground5Pressed: '#6b6b6b', + neutralBackground5Selected: rgb616161, + neutralBackground6: rgb5c5c5c, + neutralBackgroundInverted: '#b8b8b8', + subtleBackgroundHover: rgb3d3d3d, + subtleBackgroundPressed: rgb1f1f1f, + subtleBackgroundSelected: '#383838', + neutralBackgroundDisabled: '#525252', + neutralStencil1: rgb575757, + neutralStencil2: rgb333333, + brandBackground: rgb479ef5, + brandBackgroundHover: rgb479ef5, + brandBackgroundPressed: rgb96c6fa, + brandBackgroundSelected: rgb77b7f7, + compoundBrandBackground1Hover: rgb479ef5, + compoundBrandBackground1Pressed: rgb96c6fa, + neutralStrokeAccessible: rgb9e9e9e, + neutralStrokeAccessibleHover: rgb9e9e9e, + neutralStrokeAccessiblePressed: rgb9e9e9e, + neutralStrokeAccessibleSelected: rgb9e9e9e, + neutralStroke1: rgb4d4d4d, + neutralStroke1Hover: rgb4d4d4d, + neutralStroke1Pressed: rgb4d4d4d, + neutralStroke1Selected: rgb4d4d4d, + neutralStroke2: rgb3d3d3d, + brandStroke1: rgb479ef5, + compoundBrandStroke1Hover: rgb479ef5, + compoundBrandStroke1Pressed: rgb96c6fa, + neutralStrokeDisabled: rgb424242, + dangerBackground1: rgb3f1011, + dangerBackground2: rgbbc2f32, + dangerForeground1: rgbe37d80, + dangerForeground2: rgbe37d80, + dangerForeground3: rgbe37d80, + dangerForegroundInverted: rgbd13438, + dangerBorderActive: rgbe37d80, + dangerBorder2: rgbdc5e62, + successBackground1: '#052505', + successBackground2: rgb0e700e, + successForeground1: rgb54b054, + successForeground2: rgb54b054, + successForeground3: rgb9fd89f, + successForegroundInverted: rgb107c10, + successBorderActive: rgb54b054, + successBorder2: rgb9fd89f, + warningBackground1: '#4c4400', + warningBackground2: '#e4cc00', + warningForeground1: rgbfeee66, + warningForeground2: rgbfeee66, + warningForeground3: rgbfdea3d, + warningForegroundInverted: rgb817400, + warningBorderActive: rgbfeee66, + warningBorder2: rgbfdea3d, + severeBackground1: '#411200', + severeBackground2: rgbc43501, + severeForeground1: rgbe9835e, + severeForeground2: rgbe9835e, + severeForeground3: rgbe9835e, + severeBorderActive: rgbe9835e, + severeBorder2: rgbe9835e, + outofofficeBackground1: '#3a1136', + outofofficeBackground2: rgb6d2064, + outofofficeForeground1: rgbda7ed0, + outofofficeForeground2: rgbedbbe7, + outofofficeForeground3: rgbd161c4, + outofofficeBorderActive: rgbda7ed0, + outofofficeBorder1: rgbc239b3, + outofofficeBorder2: rgbd161c4, + brandForeground1Pressed: rgb96c6fa, + neutralBackgroundDarkStatic: rgb3d3d3d, + brandBackground2Pressed: rgb96c6fa, + brandBackground2Selected: rgb77b7f7, + brandForeground1Selected: rgb77b7f7, + brandStroke1Pressed: rgb96c6fa, + brandStroke1Selected: rgb77b7f7, +}; + +export const lightElevatedAliasColors: Required<AliasColorTokens> = lightAliasColors; +export const darkElevatedAliasColors: Required<AliasColorTokens> = darkAliasColors; +export const hcLightAliasColors: Required<AliasColorTokens> = lightAliasColors; +export const hcDarkAliasColors: Required<AliasColorTokens> = darkAliasColors; + +/** Font aliases from the light appearance, completed with native equivalents and the platform global ramp. */ +export const fontAliasTokens: Required<Variants> = { + caption1, + caption2: { face: Roboto, size: 12, weight: fontWeight400, lineHeight: 16, letterSpacing: 0 }, + caption1Strong: { face: Roboto, size: 13, weight: fontWeight500, lineHeight: 16, letterSpacing: 0 }, + body1, + body1Strong, + body2, + body2Strong, + title1, + title2, + title3, + largeTitle, + display, + subtitle1: title2, + subtitle1Strong, + subtitle2: title3, + subtitle2Strong, + title1Strong, + captionStandard: caption1, + secondaryStandard: body1, + secondarySemibold: body1Strong, + bodyStandard: body2, + bodySemibold: body2Strong, + subheaderStandard: title3, + subheaderSemibold: subtitle2Strong, + headerStandard: title2, + headerSemibold: subtitle1Strong, + heroStandard: title1, + heroSemibold: title1Strong, + heroLargeStandard: largeTitle, + heroLargeSemibold: display, +}; diff --git a/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.ios.ts b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.ios.ts new file mode 100644 index 00000000000..0d0b90e1248 --- /dev/null +++ b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.ios.ts @@ -0,0 +1,632 @@ +/** + * WARNING: This file is auto-generated by scripts/fluent-tokens.cts. Do not edit it manually. + * Complete Fluent tokens: native values, same-platform equivalents, then same-scheme portable defaults. + * An appearance without token data inherits elevated from standard, and high contrast from the other + * high-contrast appearance, else from standard. Shared values are emitted once. + */ +import type { AliasColorTokens } from '../types/Color.types'; +import type { BaseShadowAliasTokens } from '../types/Shadow.types'; +import type { Variants } from '../types/Typography.types'; + +const System = 'System'; +const fontWeight400 = '400'; +const fontWeight600 = '600'; +const footnote = 'footnote'; +const largeTitle1 = 'largeTitle'; +const rgb000000 = '#000000'; +const rgb00000000 = '#00000000'; +const rgb00000024 = '#00000024'; +const rgb0000003d = '#0000003d'; +const rgb00000040 = '#00000040'; +const rgb00000047 = '#00000047'; +const rgb0000004d = '#0000004d'; +const rgb0000007a = '#0000007a'; +const rgb0c3b5e = '#0c3b5e'; +const rgb0e4775 = '#0e4775'; +const rgb0e700e = '#0e700e'; +const rgb0f548c = '#0f548c'; +const rgb0f6cbd = '#0f6cbd'; +const rgb107c10 = '#107c10'; +const rgb1f1f1f = '#1f1f1f'; +const rgb242424 = '#242424'; +const rgb2886de = '#2886de'; +const rgb292929 = '#292929'; +const rgb2e2e2e = '#2e2e2e'; +const rgb333333 = '#333333'; +const rgb359b35 = '#359b35'; +const rgb383838 = '#383838'; +const rgb3d3d3d = '#3d3d3d'; +const rgb3f1011 = '#3f1011'; +const rgb424242 = '#424242'; +const rgb479ef5 = '#479ef5'; +const rgb4d4d4d = '#4d4d4d'; +const rgb525252 = '#525252'; +const rgb54b054 = '#54b054'; +const rgb575757 = '#575757'; +const rgb5c5c5c = '#5c5c5c'; +const rgb616161 = '#616161'; +const rgb6b6b6b = '#6b6b6b'; +const rgb6d2064 = '#6d2064'; +const rgb757575 = '#757575'; +const rgb77b7f7 = '#77b7f7'; +const rgb808080 = '#808080'; +const rgb817400 = '#817400'; +const rgb96c6fa = '#96c6fa'; +const rgb9e9e9e = '#9e9e9e'; +const rgb9fd89f = '#9fd89f'; +const rgbadadad = '#adadad'; +const rgbb4d6fa = '#b4d6fa'; +const rgbb8b8b8 = '#b8b8b8'; +const rgbbc2f32 = '#bc2f32'; +const rgbbdbdbd = '#bdbdbd'; +const rgbc0ad00 = '#c0ad00'; +const rgbc239b3 = '#c239b3'; +const rgbc43501 = '#c43501'; +const rgbc7c7c7 = '#c7c7c7'; +const rgbd13438 = '#d13438'; +const rgbd161c4 = '#d161c4'; +const rgbd1d1d1 = '#d1d1d1'; +const rgbd6d6d6 = '#d6d6d6'; +const rgbda3b01 = '#da3b01'; +const rgbda7ed0 = '#da7ed0'; +const rgbdbdbdb = '#dbdbdb'; +const rgbdc5e62 = '#dc5e62'; +const rgbde501c = '#de501c'; +const rgbe0e0e0 = '#e0e0e0'; +const rgbe36537 = '#e36537'; +const rgbe37d80 = '#e37d80'; +const rgbe6e6e6 = '#e6e6e6'; +const rgbe9835e = '#e9835e'; +const rgbebebeb = '#ebebeb'; +const rgbedbbe7 = '#edbbe7'; +const rgbf0f0f0 = '#f0f0f0'; +const rgbf5f5f5 = '#f5f5f5'; +const rgbfafafa = '#fafafa'; +const rgbfde300 = '#fde300'; +const rgbfdea3d = '#fdea3d'; +const rgbfdf6f6 = '#fdf6f6'; +const rgbfeee66 = '#feee66'; +const rgbffffff = '#ffffff'; +const subheadline = 'subheadline'; + +const body1 = { face: System, size: 17, weight: fontWeight400, lineHeight: 22, letterSpacing: -0.43, dynamicTypeRamp: 'body' } as const; + +const body1Strong = { + face: System, + size: 17, + weight: fontWeight600, + lineHeight: 22, + letterSpacing: -0.43, + dynamicTypeRamp: 'body', +} as const; + +const body2 = { + face: System, + size: 15, + weight: fontWeight400, + lineHeight: 20, + letterSpacing: -0.23, + dynamicTypeRamp: subheadline, +} as const; + +const body2Strong = { + face: System, + size: 15, + weight: fontWeight600, + lineHeight: 20, + letterSpacing: -0.23, + dynamicTypeRamp: subheadline, +} as const; + +const caption1 = { + face: System, + size: 13, + weight: fontWeight400, + lineHeight: 18, + letterSpacing: -0.08, + dynamicTypeRamp: footnote, +} as const; + +const display = { face: System, size: 60, weight: '700', lineHeight: 70, letterSpacing: 0.26, dynamicTypeRamp: largeTitle1 } as const; +const largeTitle2 = { face: System, size: 34, weight: '700', lineHeight: 41, letterSpacing: 0.4, dynamicTypeRamp: largeTitle1 } as const; +const shadowLayer1 = { color: '#0000001f', x: 0, y: 0, blur: 2 } as const; +const shadowLayer2 = { color: '#00000033', x: 0, y: 0, blur: 8 } as const; +const shadowLayer3 = { color: rgb0000004d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer4 = { color: rgb0000004d, x: 0, y: 0, blur: 8 } as const; +const shadowLayer5 = { color: rgb0000003d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer6 = { color: '#00000066', x: 0, y: 0, blur: 8 } as const; +const title1 = { face: System, size: 28, weight: '700', lineHeight: 34, letterSpacing: 0.38, dynamicTypeRamp: 'title1' } as const; + +const title1Strong = { + face: System, + size: 28, + weight: fontWeight600, + lineHeight: 34, + letterSpacing: 0.38, + dynamicTypeRamp: 'title1', +} as const; + +const title2 = { face: System, size: 22, weight: fontWeight600, lineHeight: 28, letterSpacing: -0.26, dynamicTypeRamp: 'title2' } as const; +const title3 = { face: System, size: 20, weight: fontWeight600, lineHeight: 25, letterSpacing: -0.45, dynamicTypeRamp: 'title3' } as const; + +const sharedAliasColors = { + brandForeground1Disabled: rgb2886de, + brandForegroundDisabled1: rgb2886de, + dangerStroke1: rgbdc5e62, + successStroke1: rgb359b35, + dangerBorder1: rgbdc5e62, + successBorder1: rgb359b35, + presenceAway: '#eaa300', + redBackground3: rgbd13438, + redBorder1: rgbdc5e62, + neutralForegroundOnBrandHover: rgbffffff, + neutralForegroundOnBrandPressed: rgbffffff, + neutralForegroundOnBrandSelected: rgbffffff, + subtleBackground: rgb00000000, + transparentBackground: rgb00000000, + transparentBackgroundHover: rgb00000000, + transparentBackgroundPressed: rgb00000000, + transparentBackgroundSelected: rgb00000000, + transparentStroke: rgb00000000, + transparentStrokeInteractive: rgb00000000, + transparentStrokeDisabled: rgb00000000, + dangerBackground3: rgbd13438, + successBackground3: rgb107c10, + warningBackground3: rgbfde300, + severeBackground3: rgbda3b01, + outofofficeBackground3: rgbc239b3, + neutralBackgroundLightStatic: rgbffffff, + neutralForegroundDarkStatic: rgb000000, + neutralForegroundLightStatic: rgbffffff, +} as const; + +const darkDarkElevatedHcDarkAliasColors = { + ...sharedAliasColors, + neutralForeground4: rgbadadad, + neutralForegroundDisabled: rgb5c5c5c, + neutralForegroundDisabled1: rgb5c5c5c, + neutralForegroundDisabled2: rgb2e2e2e, + neutralForegroundOnBrand: rgb000000, + neutralForegroundOnColor: rgb000000, + neutralForegroundInverted: rgb000000, + neutralForegroundInvertedLink: rgb000000, + brandForegroundLink: rgb479ef5, + compoundBrandForeground1: rgb479ef5, + brandForeground2: rgb479ef5, + brandForegroundTint: rgb96c6fa, + brandForegroundDisabled2: rgb0c3b5e, + brandBackground2: rgb479ef5, + brandBackground3: rgb479ef5, + brandBackgroundTint: rgb0c3b5e, + brandBackgroundDisabled: rgb0c3b5e, + compoundBrandBackground1: rgb479ef5, + brandBackgroundStatic: rgb479ef5, + neutralStrokeFocus1: rgb000000, + neutralStrokeFocus2: rgbffffff, + strokeFocus1: rgb000000, + strokeFocus2: rgbffffff, + brandStroke2: rgb479ef5, + brandStrokeTint: rgb479ef5, + compoundBrandStroke1: rgb479ef5, + warningStroke1: rgbc0ad00, + severeStroke1: rgbe36537, + warningBorder1: rgbc0ad00, + severeBorder1: rgbe36537, + presenceDnd: '#d7494c', + presenceAvailable: '#3db838', + presenceOof: rgbd161c4, + redBackground1: rgb3f1011, + redBackground2: rgbbc2f32, + redForeground1: rgbe37d80, + redForeground2: rgbe37d80, + redForeground3: rgbe37d80, + redBorderActive: rgbe37d80, + redBorder2: rgbdc5e62, + neutralForeground1: rgbffffff, + neutralForeground1Hover: rgbffffff, + neutralForeground1Pressed: rgbffffff, + neutralForeground1Selected: rgbffffff, + neutralForeground2: rgbd6d6d6, + neutralForeground2Hover: rgbd6d6d6, + neutralForeground2Pressed: rgbd6d6d6, + neutralForeground2Selected: rgbd6d6d6, + neutralForeground2BrandHover: rgbd6d6d6, + neutralForeground2BrandPressed: rgbd6d6d6, + neutralForeground2BrandSelected: rgbd6d6d6, + neutralForeground3: rgbadadad, + neutralForeground3Hover: rgbadadad, + neutralForeground3Pressed: rgbadadad, + neutralForeground3Selected: rgbadadad, + neutralForeground3BrandHover: rgbadadad, + neutralForeground3BrandPressed: rgbadadad, + neutralForeground3BrandSelected: rgbadadad, + brandForegroundLinkHover: rgb479ef5, + brandForegroundLinkPressed: rgb96c6fa, + brandForegroundLinkSelected: rgb77b7f7, + compoundBrandForeground1Hover: rgb479ef5, + compoundBrandForeground1Pressed: rgb96c6fa, + brandForeground1: rgb479ef5, + neutralForegroundInvertedLinkHover: rgb000000, + neutralForegroundInvertedLinkPressed: rgb000000, + neutralForegroundInvertedLinkSelected: rgb000000, + neutralBackground2Pressed: rgb4d4d4d, + neutralBackground2Selected: rgb424242, + neutralBackground3Pressed: rgb575757, + neutralBackground3Selected: rgb4d4d4d, + neutralBackground4Pressed: rgb616161, + neutralBackground4Selected: rgb575757, + neutralBackground5Pressed: rgb6b6b6b, + neutralBackground5Selected: rgb616161, + subtleBackgroundHover: rgb3d3d3d, + subtleBackgroundPressed: rgb1f1f1f, + subtleBackgroundSelected: rgb383838, + brandBackground: rgb479ef5, + brandBackgroundHover: rgb479ef5, + brandBackgroundPressed: rgb96c6fa, + brandBackgroundSelected: rgb77b7f7, + compoundBrandBackground1Hover: rgb479ef5, + compoundBrandBackground1Pressed: rgb96c6fa, + brandStroke1: rgb479ef5, + compoundBrandStroke1Hover: rgb479ef5, + compoundBrandStroke1Pressed: rgb96c6fa, + dangerBackground1: rgb3f1011, + dangerBackground2: rgbbc2f32, + dangerForeground1: rgbe37d80, + dangerForeground2: rgbe37d80, + dangerForeground3: rgbe37d80, + dangerForegroundInverted: rgbd13438, + dangerBorderActive: rgbe37d80, + dangerBorder2: rgbdc5e62, + successBackground1: '#052505', + successBackground2: rgb0e700e, + successForeground1: rgb54b054, + successForeground2: rgb54b054, + successForeground3: rgb9fd89f, + successForegroundInverted: rgb107c10, + successBorderActive: rgb54b054, + successBorder2: rgb9fd89f, + warningBackground1: '#4c4400', + warningBackground2: '#e4cc00', + warningForeground1: rgbfeee66, + warningForeground2: rgbfeee66, + warningForeground3: rgbfdea3d, + warningForegroundInverted: rgb817400, + warningBorderActive: rgbfeee66, + warningBorder2: rgbfdea3d, + severeBackground1: '#411200', + severeBackground2: rgbc43501, + severeForeground1: rgbe9835e, + severeForeground2: rgbe9835e, + severeForeground3: rgbe9835e, + severeBorderActive: rgbe9835e, + severeBorder2: rgbe9835e, + outofofficeBackground1: '#3a1136', + outofofficeBackground2: rgb6d2064, + outofofficeForeground1: rgbda7ed0, + outofofficeForeground2: rgbedbbe7, + outofofficeForeground3: rgbd161c4, + outofofficeBorderActive: rgbda7ed0, + outofofficeBorder1: rgbc239b3, + outofofficeBorder2: rgbd161c4, + brandForeground1Pressed: rgb96c6fa, + brandBackground2Pressed: rgb96c6fa, + brandBackground2Selected: rgb77b7f7, + brandForeground1Selected: rgb77b7f7, + brandStroke1Pressed: rgb96c6fa, + brandStroke1Selected: rgb77b7f7, +} as const; + +const sharedShadows = { + shadow2brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 1, blur: 2 } }, + shadow4brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 2, blur: 4 } }, + shadow8brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 4, blur: 8 } }, + shadow16brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 8, blur: 16 } }, + shadow28brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 14, blur: 28 } }, + shadow64brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 32, blur: 64 } }, +} as const; + +export const lightShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 32, blur: 64 } }, +}; + +export const darkShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 32, blur: 64 } }, +}; + +export const darkElevatedShadows: BaseShadowAliasTokens = darkShadows; +export const hcLightShadows: BaseShadowAliasTokens = darkShadows; +export const hcDarkShadows: BaseShadowAliasTokens = darkShadows; +export const lightElevatedShadows: BaseShadowAliasTokens = lightShadows; + +export const lightAliasColors: Required<AliasColorTokens> = { + ...sharedAliasColors, + neutralForeground4: rgb808080, + neutralForegroundDisabled: rgbbdbdbd, + neutralForegroundDisabled1: rgbbdbdbd, + neutralForegroundDisabled2: rgbffffff, + neutralForegroundOnBrand: rgbffffff, + neutralForegroundOnColor: rgbffffff, + neutralForegroundInverted: rgbffffff, + neutralForegroundInvertedLink: rgbffffff, + brandForegroundLink: rgb0f6cbd, + compoundBrandForeground1: rgb0f6cbd, + brandForeground2: rgb0f6cbd, + brandForegroundTint: rgb0f548c, + brandForegroundDisabled2: rgbb4d6fa, + neutralBackgroundCanvas: rgbf5f5f5, + neutralBackgroundLightStaticDisabled: rgbffffff, + brandBackground2: '#115ea3', + brandBackground3: rgb0f548c, + brandBackgroundTint: '#cfe4fa', + brandBackgroundInverted: rgb757575, + brandBackgroundInvertedDisabled: rgbe0e0e0, + brandBackgroundDisabled: rgbb4d6fa, + compoundBrandBackground1: rgb0f6cbd, + brandBackgroundStatic: rgb0f6cbd, + neutralStroke3: rgbe0e0e0, + neutralStrokeFocus1: rgbffffff, + neutralStrokeFocus2: rgb000000, + strokeFocus1: rgbffffff, + strokeFocus2: rgb000000, + brandStroke2: rgb2886de, + brandStrokeTint: rgb2886de, + compoundBrandStroke1: rgb0f6cbd, + warningStroke1: rgb817400, + severeStroke1: rgbde501c, + warningBorder1: rgb817400, + severeBorder1: rgbde501c, + presenceDnd: rgbd13438, + presenceAvailable: '#13a10e', + presenceOof: rgbc239b3, + redBackground1: rgbfdf6f6, + redBackground2: rgbd13438, + redForeground1: rgbbc2f32, + redForeground2: rgbd13438, + redForeground3: rgbd13438, + redBorderActive: rgbd13438, + redBorder2: rgbd13438, + neutralForeground1: rgb242424, + neutralForeground1Hover: rgb242424, + neutralForeground1Pressed: rgb242424, + neutralForeground1Selected: rgb242424, + neutralForeground2: rgb616161, + neutralForeground2Hover: rgb616161, + neutralForeground2Pressed: rgb616161, + neutralForeground2Selected: rgb616161, + neutralForeground2BrandHover: rgb616161, + neutralForeground2BrandPressed: rgb616161, + neutralForeground2BrandSelected: rgb616161, + neutralForeground3: rgb808080, + neutralForeground3Hover: rgb808080, + neutralForeground3Pressed: rgb808080, + neutralForeground3Selected: rgb808080, + neutralForeground3BrandHover: rgb808080, + neutralForeground3BrandPressed: rgb808080, + neutralForeground3BrandSelected: rgb808080, + brandForegroundLinkHover: rgb0f6cbd, + brandForegroundLinkPressed: rgb0e4775, + brandForegroundLinkSelected: rgb0f548c, + compoundBrandForeground1Hover: rgb0f6cbd, + compoundBrandForeground1Pressed: rgb0e4775, + brandForeground1: rgb0f6cbd, + neutralForegroundInvertedLinkHover: rgbffffff, + neutralForegroundInvertedLinkPressed: rgbffffff, + neutralForegroundInvertedLinkSelected: rgbffffff, + neutralBackground1: rgbffffff, + neutralBackground1Hover: rgbffffff, + neutralBackground1Pressed: rgbe0e0e0, + neutralBackground1Selected: rgbebebeb, + neutralBackground2: rgbffffff, + neutralBackground2Hover: rgbffffff, + neutralBackground2Pressed: rgbe0e0e0, + neutralBackground2Selected: rgbebebeb, + neutralBackground3: rgbffffff, + neutralBackground3Hover: rgbffffff, + neutralBackground3Pressed: rgbe0e0e0, + neutralBackground3Selected: rgbebebeb, + neutralBackground4: rgbfafafa, + neutralBackground4Hover: rgbfafafa, + neutralBackground4Pressed: rgbdbdbdb, + neutralBackground4Selected: rgbe6e6e6, + neutralBackground5: rgbf0f0f0, + neutralBackground5Hover: rgbf0f0f0, + neutralBackground5Pressed: rgbd1d1d1, + neutralBackground5Selected: rgbdbdbdb, + neutralBackground6: rgbd1d1d1, + neutralBackgroundInverted: rgb757575, + subtleBackgroundHover: rgbf5f5f5, + subtleBackgroundPressed: rgbe0e0e0, + subtleBackgroundSelected: rgbebebeb, + neutralBackgroundDisabled: rgbe0e0e0, + neutralStencil1: rgbe6e6e6, + neutralStencil2: rgbfafafa, + brandBackground: rgb0f6cbd, + brandBackgroundHover: rgb0f6cbd, + brandBackgroundPressed: rgb0e4775, + brandBackgroundSelected: rgb0f548c, + compoundBrandBackground1Hover: rgb0f6cbd, + compoundBrandBackground1Pressed: rgb0e4775, + neutralStrokeAccessible: rgb616161, + neutralStrokeAccessibleHover: rgb616161, + neutralStrokeAccessiblePressed: rgb616161, + neutralStrokeAccessibleSelected: rgb616161, + neutralStroke1: rgbd1d1d1, + neutralStroke1Hover: rgbd1d1d1, + neutralStroke1Pressed: rgbd1d1d1, + neutralStroke1Selected: rgbd1d1d1, + neutralStroke2: rgbe0e0e0, + brandStroke1: rgb0f6cbd, + compoundBrandStroke1Hover: rgb0f6cbd, + compoundBrandStroke1Pressed: rgb0e4775, + neutralStrokeDisabled: rgbe0e0e0, + dangerBackground1: rgbfdf6f6, + dangerBackground2: rgbd13438, + dangerForeground1: rgbbc2f32, + dangerForeground2: rgbd13438, + dangerForeground3: rgbd13438, + dangerForegroundInverted: rgbdc5e62, + dangerBorderActive: rgbd13438, + dangerBorder2: rgbd13438, + successBackground1: '#f1faf1', + successBackground2: rgb107c10, + successForeground1: rgb0e700e, + successForeground2: rgb107c10, + successForeground3: rgb107c10, + successForegroundInverted: rgb359b35, + successBorderActive: rgb107c10, + successBorder2: rgb107c10, + warningBackground1: '#fffef5', + warningBackground2: rgbfde300, + warningForeground1: rgb817400, + warningForeground2: rgb817400, + warningForeground3: rgbfde300, + warningForegroundInverted: '#fef7b2', + warningBorderActive: rgbfde300, + warningBorder2: rgbfde300, + severeBackground1: '#fdf6f3', + severeBackground2: rgbda3b01, + severeForeground1: rgbc43501, + severeForeground2: '#a62d01', + severeForeground3: rgbda3b01, + severeBorderActive: rgbda3b01, + severeBorder2: rgbda3b01, + outofofficeBackground1: '#fdf5fc', + outofofficeBackground2: rgbedbbe7, + outofofficeForeground1: '#af33a1', + outofofficeForeground2: rgb6d2064, + outofofficeForeground3: rgbc239b3, + outofofficeBorderActive: rgbc239b3, + outofofficeBorder1: rgbedbbe7, + outofofficeBorder2: rgbc239b3, + brandForeground1Pressed: rgb0e4775, + neutralBackgroundDarkStatic: rgb242424, + brandBackground2Pressed: rgb0c3b5e, + brandBackground2Selected: rgb0e4775, + brandForeground1Selected: rgb0f548c, + brandStroke1Pressed: rgb0e4775, + brandStroke1Selected: rgb0f548c, +}; + +export const darkAliasColors: Required<AliasColorTokens> = { + ...darkDarkElevatedHcDarkAliasColors, + neutralBackgroundCanvas: '#141414', + neutralBackgroundLightStaticDisabled: rgbadadad, + brandBackgroundInverted: rgbb8b8b8, + brandBackgroundInvertedDisabled: rgb525252, + neutralStroke3: rgb3d3d3d, + neutralBackground1: rgb000000, + neutralBackground1Hover: rgb000000, + neutralBackground1Pressed: rgb2e2e2e, + neutralBackground1Selected: rgb242424, + neutralBackground2: rgb1f1f1f, + neutralBackground2Hover: rgb1f1f1f, + neutralBackground3: rgb292929, + neutralBackground3Hover: rgb292929, + neutralBackground4: rgb333333, + neutralBackground4Hover: rgb333333, + neutralBackground5: rgb3d3d3d, + neutralBackground5Hover: rgb3d3d3d, + neutralBackground6: rgb5c5c5c, + neutralBackgroundInverted: rgbb8b8b8, + neutralBackgroundDisabled: rgb525252, + neutralStencil1: rgb575757, + neutralStencil2: rgb333333, + neutralStrokeAccessible: rgb9e9e9e, + neutralStrokeAccessibleHover: rgb9e9e9e, + neutralStrokeAccessiblePressed: rgb9e9e9e, + neutralStrokeAccessibleSelected: rgb9e9e9e, + neutralStroke1: rgb4d4d4d, + neutralStroke1Hover: rgb4d4d4d, + neutralStroke1Pressed: rgb4d4d4d, + neutralStroke1Selected: rgb4d4d4d, + neutralStroke2: rgb3d3d3d, + neutralStrokeDisabled: rgb424242, + neutralBackgroundDarkStatic: rgb3d3d3d, +}; + +export const darkElevatedAliasColors: Required<AliasColorTokens> = { + ...darkDarkElevatedHcDarkAliasColors, + neutralBackgroundCanvas: rgb242424, + neutralBackgroundLightStaticDisabled: rgb6b6b6b, + brandBackgroundInverted: rgbc7c7c7, + brandBackgroundInvertedDisabled: rgb616161, + neutralStroke3: rgb4d4d4d, + neutralBackground1: rgb1f1f1f, + neutralBackground1Hover: rgb1f1f1f, + neutralBackground1Pressed: rgb4d4d4d, + neutralBackground1Selected: rgb424242, + neutralBackground2: rgb2e2e2e, + neutralBackground2Hover: rgb2e2e2e, + neutralBackground3: rgb383838, + neutralBackground3Hover: rgb383838, + neutralBackground4: rgb424242, + neutralBackground4Hover: rgb424242, + neutralBackground5: rgb4d4d4d, + neutralBackground5Hover: rgb4d4d4d, + neutralBackground6: rgb6b6b6b, + neutralBackgroundInverted: rgbc7c7c7, + neutralBackgroundDisabled: rgb616161, + neutralStencil1: '#666666', + neutralStencil2: rgb424242, + neutralStrokeAccessible: rgbadadad, + neutralStrokeAccessibleHover: rgbadadad, + neutralStrokeAccessiblePressed: rgbadadad, + neutralStrokeAccessibleSelected: rgbadadad, + neutralStroke1: rgb5c5c5c, + neutralStroke1Hover: rgb5c5c5c, + neutralStroke1Pressed: rgb5c5c5c, + neutralStroke1Selected: rgb5c5c5c, + neutralStroke2: rgb4d4d4d, + neutralStrokeDisabled: rgb525252, + neutralBackgroundDarkStatic: rgb4d4d4d, +}; + +export const hcLightAliasColors: Required<AliasColorTokens> = lightAliasColors; +export const hcDarkAliasColors: Required<AliasColorTokens> = darkAliasColors; +export const lightElevatedAliasColors: Required<AliasColorTokens> = lightAliasColors; + +/** Font aliases from the light appearance, completed with native equivalents and the platform global ramp. */ +export const fontAliasTokens: Required<Variants> = { + caption2: { face: System, size: 12, weight: fontWeight400, lineHeight: 16, letterSpacing: 0, dynamicTypeRamp: 'caption1' }, + caption1, + caption1Strong: { face: System, size: 13, weight: fontWeight600, lineHeight: 18, letterSpacing: -0.08, dynamicTypeRamp: footnote }, + body2, + body2Strong, + body1, + body1Strong, + title3, + title2, + title1, + largeTitle: largeTitle2, + display, + subtitle1: title2, + subtitle1Strong: title2, + subtitle2: title3, + subtitle2Strong: title3, + title1Strong, + captionStandard: caption1, + secondaryStandard: body1, + secondarySemibold: body1Strong, + bodyStandard: body2, + bodySemibold: body2Strong, + subheaderStandard: title3, + subheaderSemibold: title3, + headerStandard: title2, + headerSemibold: title2, + heroStandard: title1, + heroSemibold: title1Strong, + heroLargeStandard: largeTitle2, + heroLargeSemibold: display, +}; diff --git a/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.macos.ts b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.macos.ts new file mode 100644 index 00000000000..eb75459b312 --- /dev/null +++ b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.macos.ts @@ -0,0 +1,598 @@ +/** + * WARNING: This file is auto-generated by scripts/fluent-tokens.cts. Do not edit it manually. + * Complete Fluent tokens: native values, same-platform equivalents, then same-scheme portable defaults. + * An appearance without token data inherits elevated from standard, and high contrast from the other + * high-contrast appearance, else from standard. Shared values are emitted once. + */ +import type { AliasColorTokens } from '../types/Color.types'; +import type { BaseShadowAliasTokens } from '../types/Shadow.types'; +import type { Variants } from '../types/Typography.types'; + +const fontWeight400 = '400'; +const fontWeight600 = '600'; +const primary = 'primary'; +const rgb000000 = '#000000'; +const rgb00000000 = '#00000000'; +const rgb00000024 = '#00000024'; +const rgb0000003d = '#0000003d'; +const rgb00000040 = '#00000040'; +const rgb00000047 = '#00000047'; +const rgb0000004d = '#0000004d'; +const rgb0000007a = '#0000007a'; +const rgb004578 = '#004578'; +const rgb004c87 = '#004c87'; +const rgb005a9e = '#005a9e'; +const rgb0078d4 = '#0078d4'; +const rgb0086f0 = '#0086f0'; +const rgb043862 = '#043862'; +const rgb092c47 = '#092c47'; +const rgb094509 = '#094509'; +const rgb0e700e = '#0e700e'; +const rgb106ebe = '#106ebe'; +const rgb107c10 = '#107c10'; +const rgb1890f1 = '#1890f1'; +const rgb1f1f1f = '#1f1f1f'; +const rgb242424 = '#242424'; +const rgb292929 = '#292929'; +const rgb333333 = '#333333'; +const rgb383838 = '#383838'; +const rgb3aa0f3 = '#3aa0f3'; +const rgb3d3d3d = '#3d3d3d'; +const rgb3f1011 = '#3f1011'; +const rgb424242 = '#424242'; +const rgb54b054 = '#54b054'; +const rgb575757 = '#575757'; +const rgb5c5c5c = '#5c5c5c'; +const rgb616161 = '#616161'; +const rgb666666 = '#666666'; +const rgb6cb8f6 = '#6cb8f6'; +const rgb6d2064 = '#6d2064'; +const rgb707070 = '#707070'; +const rgb751d1f = '#751d1f'; +const rgb757575 = '#757575'; +const rgb7a2101 = '#7a2101'; +const rgb817400 = '#817400'; +const rgb9fd89f = '#9fd89f'; +const rgba8a8a8 = '#a8a8a8'; +const rgbadadad = '#adadad'; +const rgbaf33a1 = '#af33a1'; +const rgbb3b3b3 = '#b3b3b3'; +const rgbb8b8b8 = '#b8b8b8'; +const rgbbc2f32 = '#bc2f32'; +const rgbbdbdbd = '#bdbdbd'; +const rgbc239b3 = '#c239b3'; +const rgbc2c2c2 = '#c2c2c2'; +const rgbc7e0f4 = '#c7e0f4'; +const rgbd13438 = '#d13438'; +const rgbd161c4 = '#d161c4'; +const rgbd6d6d6 = '#d6d6d6'; +const rgbda3b01 = '#da3b01'; +const rgbda7ed0 = '#da7ed0'; +const rgbdc5e62 = '#dc5e62'; +const rgbe0e0e0 = '#e0e0e0'; +const rgbe37d80 = '#e37d80'; +const rgbe6e6e6 = '#e6e6e6'; +const rgbe9835e = '#e9835e'; +const rgbebebeb = '#ebebeb'; +const rgbedbbe7 = '#edbbe7'; +const rgbeff6fc = '#eff6fc'; +const rgbf0f0f0 = '#f0f0f0'; +const rgbf1bbbc = '#f1bbbc'; +const rgbf4bfab = '#f4bfab'; +const rgbf5f5f5 = '#f5f5f5'; +const rgbfafafa = '#fafafa'; +const rgbfde300 = '#fde300'; +const rgbfdea3d = '#fdea3d'; +const rgbfdf6f6 = '#fdf6f6'; +const rgbfeee66 = '#feee66'; +const rgbfef7b2 = '#fef7b2'; +const rgbffffff = '#ffffff'; + +const body1 = { face: primary, size: 12, weight: fontWeight400 } as const; +const body1Strong = { face: primary, size: 12, weight: fontWeight600 } as const; +const body2 = { face: primary, size: 14, weight: fontWeight400 } as const; +const body2Strong = { face: primary, size: 14, weight: fontWeight600 } as const; +const caption1 = { face: primary, size: 10, weight: fontWeight400 } as const; +const display = { face: primary, size: 40, weight: fontWeight600 } as const; +const largeTitle = { face: primary, size: 40, weight: fontWeight400 } as const; +const shadowLayer1 = { color: '#0000001f', x: 0, y: 0, blur: 2 } as const; +const shadowLayer2 = { color: '#00000033', x: 0, y: 0, blur: 8 } as const; +const shadowLayer3 = { color: rgb0000004d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer4 = { color: rgb0000004d, x: 0, y: 0, blur: 8 } as const; +const shadowLayer5 = { color: rgb0000003d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer6 = { color: '#00000066', x: 0, y: 0, blur: 8 } as const; +const subtitle1 = { face: primary, size: 20, weight: fontWeight400 } as const; +const subtitle1Strong = { face: primary, size: 20, weight: fontWeight600 } as const; +const subtitle2 = { face: primary, size: 16, weight: fontWeight400 } as const; +const subtitle2Strong = { face: primary, size: 16, weight: fontWeight600 } as const; +const title1 = { face: primary, size: 28, weight: fontWeight400 } as const; +const title1Strong = { face: primary, size: 28, weight: fontWeight600 } as const; + +const sharedAliasColors = { + neutralForegroundOnBrand: rgbffffff, + neutralForegroundOnColor: rgbffffff, + neutralForegroundInverted: rgbffffff, + redBackground3: rgbd13438, + neutralForegroundOnBrandHover: rgbffffff, + neutralForegroundOnBrandPressed: rgbffffff, + neutralForegroundOnBrandSelected: rgbffffff, + subtleBackground: rgb00000000, + transparentBackground: rgb00000000, + transparentBackgroundHover: rgb00000000, + transparentBackgroundPressed: rgb00000000, + transparentBackgroundSelected: rgb00000000, + dangerBackground3: rgbd13438, + successBackground3: rgb107c10, + warningBackground3: rgbfde300, + severeBackground3: rgbda3b01, + outofofficeBackground3: rgbc239b3, + neutralBackgroundLightStatic: rgbffffff, + neutralForegroundDarkStatic: rgb000000, + neutralForegroundLightStatic: rgbffffff, +} as const; + +const lightHcLightLightElevatedAliasColors = { + ...sharedAliasColors, + neutralForegroundDisabled: rgb757575, + neutralForegroundDisabled1: rgb757575, + neutralForegroundDisabled2: rgb757575, + neutralForegroundInvertedLink: rgbffffff, + brandForegroundLink: rgb0078d4, + compoundBrandForeground1: rgb0078d4, + brandForeground2: rgb106ebe, + brandForegroundTint: rgb106ebe, + brandForeground1Disabled: rgb757575, + brandForegroundDisabled1: rgb757575, + brandForegroundDisabled2: rgb757575, + neutralBackgroundCanvas: rgbffffff, + neutralBackgroundLightStaticDisabled: rgbf0f0f0, + brandBackground2: rgbeff6fc, + brandBackground3: rgbeff6fc, + brandBackgroundTint: rgbeff6fc, + brandBackgroundInverted: rgb616161, + brandBackgroundInvertedDisabled: rgbf0f0f0, + brandBackgroundDisabled: '#d1d1d1', + compoundBrandBackground1: rgb0078d4, + brandBackgroundStatic: rgb0078d4, + neutralStrokeFocus1: rgbffffff, + neutralStrokeFocus2: rgb000000, + strokeFocus1: rgbffffff, + strokeFocus2: rgb000000, + brandStroke2: rgbc7e0f4, + brandStrokeTint: rgbc7e0f4, + compoundBrandStroke1: rgb0078d4, + dangerStroke1: rgbf1bbbc, + successStroke1: rgb9fd89f, + warningStroke1: rgbfef7b2, + severeStroke1: rgbf4bfab, + dangerBorder1: rgbf1bbbc, + successBorder1: rgb9fd89f, + warningBorder1: rgbfef7b2, + severeBorder1: rgbf4bfab, + presenceAway: rgb817400, + presenceDnd: rgbbc2f32, + presenceAvailable: rgb0e700e, + presenceOof: rgbaf33a1, + redBackground1: rgbfdf6f6, + redBackground2: rgbf1bbbc, + redForeground1: rgbbc2f32, + redForeground2: rgb751d1f, + redForeground3: rgbd13438, + redBorderActive: rgbd13438, + redBorder1: rgbf1bbbc, + redBorder2: rgbd13438, + neutralForeground2: rgb000000, + neutralForeground2Hover: rgb242424, + neutralForeground2Pressed: rgb242424, + neutralForeground2Selected: rgb242424, + neutralForeground2BrandHover: rgb106ebe, + neutralForeground2BrandPressed: rgb004578, + neutralForeground2BrandSelected: rgb005a9e, + neutralForeground3Hover: rgb424242, + neutralForeground3Pressed: rgb424242, + neutralForeground3Selected: rgb424242, + neutralForeground3BrandHover: rgb106ebe, + neutralForeground3BrandPressed: rgb004578, + neutralForeground3BrandSelected: rgb005a9e, + brandForegroundLinkHover: rgb106ebe, + brandForegroundLinkPressed: rgb004578, + brandForegroundLinkSelected: rgb005a9e, + compoundBrandForeground1Hover: rgb106ebe, + compoundBrandForeground1Pressed: rgb004578, + brandForeground1: rgb0078d4, + neutralForegroundInvertedLinkHover: rgbffffff, + neutralForegroundInvertedLinkPressed: rgbffffff, + neutralForegroundInvertedLinkSelected: rgbffffff, + neutralBackground1: rgbffffff, + neutralBackground1Hover: rgbf5f5f5, + neutralBackground1Pressed: rgbebebeb, + neutralBackground1Selected: rgbebebeb, + neutralBackground2: rgbffffff, + neutralBackground2Hover: rgbf0f0f0, + neutralBackground2Pressed: rgbebebeb, + neutralBackground2Selected: rgbe6e6e6, + neutralBackground3: rgbf5f5f5, + neutralBackground3Hover: rgbebebeb, + neutralBackground3Pressed: rgbd6d6d6, + neutralBackground3Selected: rgbe0e0e0, + neutralBackground4: rgbf0f0f0, + neutralBackground4Hover: rgbfafafa, + neutralBackground4Pressed: rgbf5f5f5, + neutralBackground4Selected: rgbffffff, + neutralBackground5: rgbebebeb, + neutralBackground5Hover: rgbf5f5f5, + neutralBackground5Pressed: rgbf0f0f0, + neutralBackground5Selected: rgbfafafa, + neutralBackground6: rgbe6e6e6, + neutralBackgroundInverted: rgb616161, + subtleBackgroundHover: rgbf5f5f5, + subtleBackgroundPressed: rgbe0e0e0, + subtleBackgroundSelected: rgbebebeb, + neutralBackgroundDisabled: rgbf0f0f0, + neutralStencil1: rgbe6e6e6, + neutralStencil2: rgbfafafa, + brandBackground: rgb0078d4, + brandBackgroundHover: rgb106ebe, + brandBackgroundPressed: rgb106ebe, + brandBackgroundSelected: rgb005a9e, + compoundBrandBackground1Hover: rgb106ebe, + compoundBrandBackground1Pressed: rgb004578, + neutralStrokeAccessibleHover: rgb575757, + neutralStrokeAccessiblePressed: '#4d4d4d', + neutralStrokeAccessibleSelected: rgb0078d4, + neutralStroke1Hover: '#c7c7c7', + neutralStroke1Pressed: rgbb3b3b3, + neutralStroke1Selected: rgbbdbdbd, + brandStroke1: rgb0078d4, + compoundBrandStroke1Hover: rgb106ebe, + compoundBrandStroke1Pressed: rgb004578, + neutralStrokeDisabled: rgbe0e0e0, + dangerBackground1: rgbfdf6f6, + dangerBackground2: rgbf1bbbc, + dangerForeground1: rgbbc2f32, + dangerForeground2: rgb751d1f, + dangerForeground3: rgbd13438, + dangerForegroundInverted: rgbdc5e62, + dangerBorderActive: rgbd13438, + dangerBorder2: rgbd13438, + successBackground1: '#f1faf1', + successBackground2: rgb9fd89f, + successForeground1: rgb0e700e, + successForeground2: rgb094509, + successForeground3: rgb107c10, + successForegroundInverted: '#359b35', + successBorderActive: rgb107c10, + successBorder2: rgb107c10, + warningBackground1: '#fffef5', + warningBackground2: rgbfef7b2, + warningForeground1: rgb817400, + warningForeground2: rgb817400, + warningForeground3: rgbfde300, + warningForegroundInverted: rgbfef7b2, + warningBorderActive: rgbfde300, + warningBorder2: rgbfde300, + severeBackground1: '#fdf6f3', + severeBackground2: rgbf4bfab, + severeForeground1: '#c43501', + severeForeground2: rgb7a2101, + severeForeground3: rgbda3b01, + severeBorderActive: rgbda3b01, + severeBorder2: rgbda3b01, + outofofficeBackground1: '#fdf5fc', + outofofficeBackground2: rgbedbbe7, + outofofficeForeground1: rgbaf33a1, + outofofficeForeground2: rgb6d2064, + outofofficeForeground3: rgbc239b3, + outofofficeBorderActive: rgbc239b3, + outofofficeBorder1: rgbedbbe7, + outofofficeBorder2: rgbc239b3, + brandForeground1Pressed: rgb004578, + neutralBackgroundDarkStatic: rgb242424, + brandBackground2Pressed: rgb106ebe, + brandBackground2Selected: rgb005a9e, + brandForeground1Selected: rgb005a9e, + brandStroke1Pressed: rgb004578, + brandStroke1Selected: rgb005a9e, +} as const; + +const darkHcDarkDarkElevatedAliasColors = { + ...sharedAliasColors, + neutralForegroundDisabled: rgbb8b8b8, + neutralForegroundDisabled1: rgbb8b8b8, + neutralForegroundDisabled2: rgbb8b8b8, + neutralForegroundInvertedLink: rgb292929, + brandForegroundLink: rgb043862, + compoundBrandForeground1: rgb043862, + brandForeground2: rgb092c47, + brandForegroundTint: rgb092c47, + brandForeground1Disabled: rgbc2c2c2, + brandForegroundDisabled1: rgbc2c2c2, + brandForegroundDisabled2: rgbc2c2c2, + neutralBackgroundCanvas: rgb000000, + neutralBackgroundLightStaticDisabled: rgb575757, + brandBackground2: rgb092c47, + brandBackground3: rgb092c47, + brandBackgroundTint: rgb092c47, + brandBackgroundInverted: rgbffffff, + brandBackgroundInvertedDisabled: rgb575757, + brandBackgroundDisabled: rgb575757, + compoundBrandBackground1: rgb0086f0, + brandBackgroundStatic: rgb0086f0, + neutralStrokeFocus1: rgb000000, + neutralStrokeFocus2: rgbffffff, + strokeFocus1: rgb000000, + strokeFocus2: rgbffffff, + brandStroke2: rgb004c87, + brandStrokeTint: rgb004c87, + compoundBrandStroke1: rgb0086f0, + dangerStroke1: rgbd13438, + successStroke1: rgb107c10, + warningStroke1: rgbfde300, + severeStroke1: rgbda3b01, + dangerBorder1: rgbd13438, + successBorder1: rgb107c10, + warningBorder1: rgbfde300, + severeBorder1: rgbda3b01, + presenceAway: rgbfeee66, + presenceDnd: rgbe37d80, + presenceAvailable: rgb54b054, + presenceOof: rgbda7ed0, + redBackground1: rgb3f1011, + redBackground2: rgb751d1f, + redForeground1: rgbe37d80, + redForeground2: rgbf1bbbc, + redForeground3: rgbe37d80, + redBorderActive: rgbe37d80, + redBorder1: rgbd13438, + redBorder2: rgbdc5e62, + neutralForeground1: rgbffffff, + neutralForeground1Hover: rgbffffff, + neutralForeground1Pressed: rgbffffff, + neutralForeground1Selected: rgbffffff, + neutralForeground2: rgbffffff, + neutralForeground2Hover: rgbffffff, + neutralForeground2Pressed: rgbffffff, + neutralForeground2Selected: rgbffffff, + neutralForeground2BrandHover: rgb092c47, + neutralForeground2BrandPressed: rgb0078d4, + neutralForeground2BrandSelected: rgb092c47, + neutralForeground3Hover: rgbd6d6d6, + neutralForeground3Pressed: rgbd6d6d6, + neutralForeground3Selected: rgbd6d6d6, + neutralForeground3BrandHover: rgb092c47, + neutralForeground3BrandPressed: rgb0078d4, + neutralForeground3BrandSelected: rgb092c47, + brandForegroundLinkHover: rgb092c47, + brandForegroundLinkPressed: rgb0078d4, + brandForegroundLinkSelected: rgb092c47, + compoundBrandForeground1Hover: rgb092c47, + compoundBrandForeground1Pressed: rgb0078d4, + brandForeground1: rgb0086f0, + neutralForegroundInvertedLinkHover: rgb292929, + neutralForegroundInvertedLinkPressed: rgb292929, + neutralForegroundInvertedLinkSelected: rgb292929, + neutralBackground1: rgb000000, + neutralBackground1Hover: rgb3d3d3d, + neutralBackground1Pressed: rgb5c5c5c, + neutralBackground1Selected: rgb383838, + neutralBackground2: rgb575757, + neutralBackground2Hover: rgb333333, + neutralBackground2Pressed: rgb707070, + neutralBackground2Selected: '#2e2e2e', + neutralBackground3: rgb575757, + neutralBackground3Hover: rgb292929, + neutralBackground3Pressed: '#0a0a0a', + neutralBackground3Selected: rgb242424, + neutralBackground4: rgb1f1f1f, + neutralBackground4Hover: rgb1f1f1f, + neutralBackground4Pressed: rgb000000, + neutralBackground4Selected: '#1a1a1a', + neutralBackground5: rgb5c5c5c, + neutralBackground5Hover: '#141414', + neutralBackground5Pressed: '#050505', + neutralBackground5Selected: '#0f0f0f', + neutralBackground6: rgb333333, + neutralBackgroundInverted: rgbffffff, + subtleBackgroundHover: rgb3d3d3d, + subtleBackgroundPressed: rgb1f1f1f, + subtleBackgroundSelected: rgb383838, + neutralBackgroundDisabled: rgb575757, + neutralStencil1: rgb333333, + neutralStencil2: rgb575757, + brandBackground: rgb0086f0, + brandBackgroundHover: rgb1890f1, + brandBackgroundPressed: rgb1890f1, + brandBackgroundSelected: rgb3aa0f3, + compoundBrandBackground1Hover: rgb1890f1, + compoundBrandBackground1Pressed: rgb6cb8f6, + neutralStrokeAccessibleHover: rgbbdbdbd, + neutralStrokeAccessiblePressed: rgbb3b3b3, + neutralStrokeAccessibleSelected: rgb0086f0, + neutralStroke1Hover: rgb757575, + neutralStroke1Pressed: '#6b6b6b', + neutralStroke1Selected: rgb707070, + brandStroke1: rgb0086f0, + compoundBrandStroke1Hover: rgb1890f1, + compoundBrandStroke1Pressed: rgb6cb8f6, + neutralStrokeDisabled: '#525252', + dangerBackground1: rgb3f1011, + dangerBackground2: rgb751d1f, + dangerForeground1: rgbe37d80, + dangerForeground2: rgbf1bbbc, + dangerForeground3: rgbe37d80, + dangerForegroundInverted: rgbd13438, + dangerBorderActive: rgbe37d80, + dangerBorder2: rgbdc5e62, + successBackground1: '#052505', + successBackground2: rgb094509, + successForeground1: rgb54b054, + successForeground2: rgb9fd89f, + successForeground3: rgb9fd89f, + successForegroundInverted: rgb107c10, + successBorderActive: rgb54b054, + successBorder2: rgb9fd89f, + warningBackground1: '#4c4400', + warningBackground2: rgb817400, + warningForeground1: rgbfeee66, + warningForeground2: rgbfef7b2, + warningForeground3: rgbfdea3d, + warningForegroundInverted: rgb817400, + warningBorderActive: rgbfeee66, + warningBorder2: rgbfdea3d, + severeBackground1: '#411200', + severeBackground2: rgb7a2101, + severeForeground1: rgbe9835e, + severeForeground2: rgbf4bfab, + severeForeground3: rgbe9835e, + severeBorderActive: rgbe9835e, + severeBorder2: rgbe9835e, + outofofficeBackground1: '#3a1136', + outofofficeBackground2: rgb6d2064, + outofofficeForeground1: rgbda7ed0, + outofofficeForeground2: rgbedbbe7, + outofofficeForeground3: rgbd161c4, + outofofficeBorderActive: rgbda7ed0, + outofofficeBorder1: rgbc239b3, + outofofficeBorder2: rgbd161c4, + brandForeground1Pressed: rgb6cb8f6, + neutralBackgroundDarkStatic: rgb3d3d3d, + brandBackground2Pressed: rgb1890f1, + brandBackground2Selected: rgb3aa0f3, + brandForeground1Selected: rgb3aa0f3, + brandStroke1Pressed: rgb6cb8f6, + brandStroke1Selected: rgb3aa0f3, +} as const; + +const lightDarkLightElevatedDarkElevatedAliasColors = { + ...sharedAliasColors, + transparentStroke: rgb00000000, + transparentStrokeInteractive: rgb00000000, + transparentStrokeDisabled: rgb00000000, +} as const; + +const sharedShadows = { + shadow2brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 1, blur: 2 } }, + shadow4brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 2, blur: 4 } }, + shadow8brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 4, blur: 8 } }, + shadow16brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 8, blur: 16 } }, + shadow28brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 14, blur: 28 } }, + shadow64brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 32, blur: 64 } }, +} as const; + +export const lightShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 32, blur: 64 } }, +}; + +export const darkShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 32, blur: 64 } }, +}; + +export const hcLightShadows: BaseShadowAliasTokens = darkShadows; +export const hcDarkShadows: BaseShadowAliasTokens = darkShadows; +export const lightElevatedShadows: BaseShadowAliasTokens = lightShadows; +export const darkElevatedShadows: BaseShadowAliasTokens = darkShadows; + +export const lightAliasColors: Required<AliasColorTokens> = { + ...lightHcLightLightElevatedAliasColors, + ...lightDarkLightElevatedDarkElevatedAliasColors, + neutralForeground4: '#808080', + neutralStroke3: rgbf0f0f0, + neutralForeground1: rgb242424, + neutralForeground1Hover: rgb242424, + neutralForeground1Pressed: rgb242424, + neutralForeground1Selected: rgb242424, + neutralForeground3: rgb616161, + neutralStrokeAccessible: rgb616161, + neutralStroke1: rgbf0f0f0, + neutralStroke2: rgbd6d6d6, +}; + +export const darkAliasColors: Required<AliasColorTokens> = { + ...darkHcDarkDarkElevatedAliasColors, + ...lightDarkLightElevatedDarkElevatedAliasColors, + neutralForeground4: '#858585', + neutralStroke3: rgb666666, + neutralForeground3: rgbadadad, + neutralStrokeAccessible: rgbadadad, + neutralStroke1: rgb3d3d3d, + neutralStroke2: rgb575757, +}; + +export const hcLightAliasColors: Required<AliasColorTokens> = { + ...lightHcLightLightElevatedAliasColors, + neutralForeground4: rgb424242, + neutralStroke3: rgb616161, + neutralForeground1: rgb000000, + neutralForeground1Hover: rgb000000, + neutralForeground1Pressed: rgb000000, + neutralForeground1Selected: rgb000000, + neutralForeground3: rgb000000, + neutralStrokeAccessible: rgb242424, + neutralStroke1: rgb616161, + neutralStroke2: rgb000000, + transparentStroke: rgb000000, + transparentStrokeInteractive: rgb666666, + transparentStrokeDisabled: rgbbdbdbd, +}; + +export const hcDarkAliasColors: Required<AliasColorTokens> = { + ...darkHcDarkDarkElevatedAliasColors, + neutralForeground4: rgbd6d6d6, + neutralStroke3: rgbadadad, + neutralForeground3: rgbd6d6d6, + neutralStrokeAccessible: rgbd6d6d6, + neutralStroke1: rgbadadad, + neutralStroke2: rgba8a8a8, + transparentStroke: rgb3aa0f3, + transparentStrokeInteractive: rgba8a8a8, + transparentStrokeDisabled: rgbd6d6d6, +}; + +export const lightElevatedAliasColors: Required<AliasColorTokens> = lightAliasColors; +export const darkElevatedAliasColors: Required<AliasColorTokens> = darkAliasColors; + +/** Font aliases from the light appearance, completed with native equivalents and the platform global ramp. */ +export const fontAliasTokens: Required<Variants> = { + caption1, + body1, + body1Strong, + body2, + body2Strong, + subtitle1, + subtitle1Strong, + subtitle2, + subtitle2Strong, + title1, + title1Strong, + largeTitle, + display, + caption1Strong: { face: primary, size: 10, weight: fontWeight600 }, + caption2: caption1, + title2: subtitle1, + title3: subtitle2, + captionStandard: caption1, + secondaryStandard: body1, + secondarySemibold: body1Strong, + bodyStandard: body2, + bodySemibold: body2Strong, + subheaderStandard: subtitle2, + subheaderSemibold: subtitle2Strong, + headerStandard: subtitle1, + headerSemibold: subtitle1Strong, + heroStandard: title1, + heroSemibold: title1Strong, + heroLargeStandard: largeTitle, + heroLargeSemibold: display, +}; diff --git a/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.ts b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.ts new file mode 100644 index 00000000000..c8148ac3da8 --- /dev/null +++ b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.ts @@ -0,0 +1,806 @@ +/** + * WARNING: This file is auto-generated by scripts/fluent-tokens.cts. Do not edit it manually. + * Complete Fluent tokens: native values, same-platform equivalents, then same-scheme portable defaults. + * An appearance without token data inherits elevated from standard, and high contrast from the other + * high-contrast appearance, else from standard. Shared values are emitted once. + */ +import { PlatformColor } from 'react-native'; + +import type { AliasColorTokens } from '../types/Color.types'; +import type { BaseShadowAliasTokens } from '../types/Shadow.types'; +import type { Variants } from '../types/Typography.types'; + +const platformColorButtonFace = /* @__PURE__ */ PlatformColor('ButtonFace'); +const platformColorButtonText = /* @__PURE__ */ PlatformColor('ButtonText'); +const platformColorGrayText = /* @__PURE__ */ PlatformColor('GrayText'); +const platformColorHighlight = /* @__PURE__ */ PlatformColor('Highlight'); +const platformColorHighlightText = /* @__PURE__ */ PlatformColor('HighlightText'); +const platformColorHotlight = /* @__PURE__ */ PlatformColor('Hotlight'); +const platformColorWindow = /* @__PURE__ */ PlatformColor('Window'); +const platformColorWindowText = /* @__PURE__ */ PlatformColor('WindowText'); + +const fontWeight400 = '400'; +const fontWeight600 = '600'; +const primary = 'primary'; +const rgb000000 = '#000000'; +const rgb00000000 = '#00000000'; +const rgb00000024 = '#00000024'; +const rgb0000003d = '#0000003d'; +const rgb00000040 = '#00000040'; +const rgb00000047 = '#00000047'; +const rgb0000004d = '#0000004d'; +const rgb0000007a = '#0000007a'; +const rgb094509 = '#094509'; +const rgb0a0a0a = '#0a0a0a'; +const rgb0e336a = '#0e336a'; +const rgb0e700e = '#0e700e'; +const rgb107c10 = '#107c10'; +const rgb13458f = '#13458f'; +const rgb141414 = '#141414'; +const rgb1651aa = '#1651aa'; +const rgb185abd = '#185abd'; +const rgb1a1a1a = '#1a1a1a'; +const rgb1f1f1f = '#1f1f1f'; +const rgb242424 = '#242424'; +const rgb292929 = '#292929'; +const rgb2e2e2e = '#2e2e2e'; +const rgb2e6ac5 = '#2e6ac5'; +const rgb333333 = '#333333'; +const rgb383838 = '#383838'; +const rgb3d3d3d = '#3d3d3d'; +const rgb3f1011 = '#3f1011'; +const rgb424242 = '#424242'; +const rgb474747 = '#474747'; +const rgb4d4d4d = '#4d4d4d'; +const rgb525252 = '#525252'; +const rgb54b054 = '#54b054'; +const rgb575757 = '#575757'; +const rgb5c5c5c = '#5c5c5c'; +const rgb616161 = '#616161'; +const rgb666666 = '#666666'; +const rgb6794d7 = '#6794d7'; +const rgb6d2064 = '#6d2064'; +const rgb707070 = '#707070'; +const rgb751d1f = '#751d1f'; +const rgb757575 = '#757575'; +const rgb7a2101 = '#7a2101'; +const rgb817400 = '#817400'; +const rgb999999 = '#999999'; +const rgb9fd89f = '#9fd89f'; +const rgbadadad = '#adadad'; +const rgbaec6eb = '#aec6eb'; +const rgbaf33a1 = '#af33a1'; +const rgbb3b3b3 = '#b3b3b3'; +const rgbbc2f32 = '#bc2f32'; +const rgbbdbdbd = '#bdbdbd'; +const rgbc239b3 = '#c239b3'; +const rgbd13438 = '#d13438'; +const rgbd161c4 = '#d161c4'; +const rgbd2e0f4 = '#d2e0f4'; +const rgbd6d6d6 = '#d6d6d6'; +const rgbda3b01 = '#da3b01'; +const rgbda7ed0 = '#da7ed0'; +const rgbdc5e62 = '#dc5e62'; +const rgbe0e0e0 = '#e0e0e0'; +const rgbe37d80 = '#e37d80'; +const rgbe6e6e6 = '#e6e6e6'; +const rgbe9835e = '#e9835e'; +const rgbebebeb = '#ebebeb'; +const rgbedbbe7 = '#edbbe7'; +const rgbf0f0f0 = '#f0f0f0'; +const rgbf1bbbc = '#f1bbbc'; +const rgbf4bfab = '#f4bfab'; +const rgbf5f5f5 = '#f5f5f5'; +const rgbfafafa = '#fafafa'; +const rgbfde300 = '#fde300'; +const rgbfdea3d = '#fdea3d'; +const rgbfdf6f6 = '#fdf6f6'; +const rgbfeee66 = '#feee66'; +const rgbfef7b2 = '#fef7b2'; +const rgbffffff = '#ffffff'; + +const body1 = { face: primary, size: 12, weight: fontWeight400 } as const; +const body1Strong = { face: primary, size: 12, weight: fontWeight600 } as const; +const body2 = { face: primary, size: 14, weight: fontWeight400 } as const; +const body2Strong = { face: primary, size: 14, weight: fontWeight600 } as const; +const caption1 = { face: primary, size: 10, weight: fontWeight400 } as const; +const display = { face: primary, size: 40, weight: fontWeight600 } as const; +const largeTitle = { face: primary, size: 40, weight: fontWeight400 } as const; +const shadowLayer1 = { color: '#0000001f', x: 0, y: 0, blur: 2 } as const; +const shadowLayer2 = { color: '#00000033', x: 0, y: 0, blur: 8 } as const; +const shadowLayer3 = { color: rgb0000004d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer4 = { color: rgb0000004d, x: 0, y: 0, blur: 8 } as const; +const shadowLayer5 = { color: rgb0000003d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer6 = { color: '#00000066', x: 0, y: 0, blur: 8 } as const; +const subtitle1 = { face: primary, size: 20, weight: fontWeight400 } as const; +const subtitle1Strong = { face: primary, size: 20, weight: fontWeight600 } as const; +const subtitle2 = { face: primary, size: 16, weight: fontWeight400 } as const; +const subtitle2Strong = { face: primary, size: 16, weight: fontWeight600 } as const; +const title1 = { face: primary, size: 28, weight: fontWeight400 } as const; +const title1Strong = { face: primary, size: 28, weight: fontWeight600 } as const; + +const sharedAliasColors = { + subtleBackground: rgb00000000, + transparentBackground: rgb00000000, + transparentBackgroundHover: rgb00000000, + transparentBackgroundPressed: rgb00000000, + transparentBackgroundSelected: rgb00000000, + neutralBackgroundLightStatic: rgbffffff, + neutralForegroundDarkStatic: rgb000000, + neutralForegroundLightStatic: rgbffffff, +} as const; + +const lightDarkDarkElevatedLightElevatedAliasColors = { + ...sharedAliasColors, + neutralForegroundOnBrand: rgbffffff, + neutralForegroundOnColor: rgbffffff, + brandBackground2: rgbd2e0f4, + brandBackground3: rgbd2e0f4, + brandBackgroundTint: rgbd2e0f4, + compoundBrandBackground1: rgb185abd, + brandBackgroundStatic: rgb185abd, + brandStroke2: rgb6794d7, + brandStrokeTint: rgb6794d7, + compoundBrandStroke1: rgb185abd, + redBackground3: rgbd13438, + neutralForegroundOnBrandHover: rgbffffff, + neutralForegroundOnBrandPressed: rgbffffff, + neutralForegroundOnBrandSelected: rgbffffff, + brandBackground: rgb185abd, + brandBackgroundHover: rgb1651aa, + brandBackgroundPressed: rgb0e336a, + brandBackgroundSelected: rgb13458f, + compoundBrandBackground1Hover: rgb1651aa, + compoundBrandBackground1Pressed: rgb0e336a, + neutralStrokeAccessibleSelected: rgb185abd, + brandStroke1: rgb185abd, + compoundBrandStroke1Hover: rgb1651aa, + compoundBrandStroke1Pressed: rgb0e336a, + transparentStroke: rgb00000000, + transparentStrokeInteractive: rgb00000000, + transparentStrokeDisabled: rgb00000000, + dangerBackground3: rgbd13438, + successBackground3: rgb107c10, + warningBackground3: rgbfde300, + severeBackground3: rgbda3b01, + outofofficeBackground3: rgbc239b3, + brandBackground2Pressed: rgb0e336a, + brandBackground2Selected: rgb13458f, + brandStroke1Pressed: rgb185abd, + brandStroke1Selected: rgb185abd, +} as const; + +const darkDarkElevatedHcDarkHcLightAliasColors = { + ...sharedAliasColors, + neutralBackgroundDarkStatic: rgb3d3d3d, +} as const; + +const sharedShadows = { + shadow2brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 1, blur: 2 } }, + shadow4brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 2, blur: 4 } }, + shadow8brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 4, blur: 8 } }, + shadow16brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 8, blur: 16 } }, + shadow28brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 14, blur: 28 } }, + shadow64brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 32, blur: 64 } }, +} as const; + +const darkDarkElevatedAliasColors = { + ...lightDarkDarkElevatedLightElevatedAliasColors, + ...darkDarkElevatedHcDarkHcLightAliasColors, + neutralForegroundInverted: rgb000000, + brandForegroundLink: rgbaec6eb, + compoundBrandForeground1: rgbaec6eb, + brandForeground2: rgbd2e0f4, + brandForegroundTint: rgbd2e0f4, + brandBackgroundInverted: rgbffffff, + neutralStrokeFocus1: rgb000000, + neutralStrokeFocus2: rgbffffff, + strokeFocus1: rgb000000, + strokeFocus2: rgbffffff, + dangerStroke1: rgbd13438, + successStroke1: rgb107c10, + warningStroke1: rgbfde300, + severeStroke1: rgbda3b01, + dangerBorder1: rgbd13438, + successBorder1: rgb107c10, + warningBorder1: rgbfde300, + severeBorder1: rgbda3b01, + presenceAway: rgbfeee66, + presenceDnd: rgbe37d80, + presenceAvailable: rgb54b054, + presenceOof: rgbda7ed0, + redBackground1: rgb3f1011, + redBackground2: rgb751d1f, + redForeground1: rgbe37d80, + redForeground2: rgbf1bbbc, + redForeground3: rgbe37d80, + redBorderActive: rgbe37d80, + redBorder1: rgbd13438, + redBorder2: rgbdc5e62, + neutralForeground1: rgbffffff, + neutralForeground1Hover: rgbffffff, + neutralForeground1Pressed: rgbffffff, + neutralForeground1Selected: rgbffffff, + neutralForeground2Hover: rgbffffff, + neutralForeground2Pressed: rgbffffff, + neutralForeground2Selected: rgbffffff, + neutralForeground2BrandHover: rgbd2e0f4, + neutralForeground2BrandPressed: rgb2e6ac5, + neutralForeground2BrandSelected: rgbd2e0f4, + neutralForeground3BrandHover: rgbd2e0f4, + neutralForeground3BrandPressed: rgb2e6ac5, + neutralForeground3BrandSelected: rgbd2e0f4, + brandForegroundLinkHover: rgbd2e0f4, + brandForegroundLinkPressed: rgb2e6ac5, + brandForegroundLinkSelected: rgbd2e0f4, + compoundBrandForeground1Hover: rgbd2e0f4, + compoundBrandForeground1Pressed: rgb2e6ac5, + brandForeground1: rgbaec6eb, + neutralBackgroundInverted: rgbffffff, + dangerBackground1: rgb3f1011, + dangerBackground2: rgb751d1f, + dangerForeground1: rgbe37d80, + dangerForeground2: rgbf1bbbc, + dangerForeground3: rgbe37d80, + dangerForegroundInverted: rgbd13438, + dangerBorderActive: rgbe37d80, + dangerBorder2: rgbdc5e62, + successBackground1: '#052505', + successBackground2: rgb094509, + successForeground1: rgb54b054, + successForeground2: rgb9fd89f, + successForeground3: rgb9fd89f, + successForegroundInverted: rgb107c10, + successBorderActive: rgb54b054, + successBorder2: rgb9fd89f, + warningBackground1: '#4c4400', + warningBackground2: rgb817400, + warningForeground1: rgbfeee66, + warningForeground2: rgbfef7b2, + warningForeground3: rgbfdea3d, + warningForegroundInverted: rgb817400, + warningBorderActive: rgbfeee66, + warningBorder2: rgbfdea3d, + severeBackground1: '#411200', + severeBackground2: rgb7a2101, + severeForeground1: rgbe9835e, + severeForeground2: rgbf4bfab, + severeForeground3: rgbe9835e, + severeBorderActive: rgbe9835e, + severeBorder2: rgbe9835e, + outofofficeBackground1: '#3a1136', + outofofficeBackground2: rgb6d2064, + outofofficeForeground1: rgbda7ed0, + outofofficeForeground2: rgbedbbe7, + outofofficeForeground3: rgbd161c4, + outofofficeBorderActive: rgbda7ed0, + outofofficeBorder1: rgbc239b3, + outofofficeBorder2: rgbd161c4, + brandForeground1Pressed: rgbaec6eb, + brandForeground1Selected: rgbaec6eb, +} as const; + +export const lightShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 32, blur: 64 } }, +}; + +export const darkShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 32, blur: 64 } }, +}; + +export const darkElevatedShadows: BaseShadowAliasTokens = darkShadows; +export const hcDarkShadows: BaseShadowAliasTokens = darkShadows; +export const lightElevatedShadows: BaseShadowAliasTokens = lightShadows; +export const hcLightShadows: BaseShadowAliasTokens = darkShadows; + +export const lightAliasColors: Required<AliasColorTokens> = { + ...lightDarkDarkElevatedLightElevatedAliasColors, + neutralForeground4: rgb707070, + neutralForegroundDisabled: rgbbdbdbd, + neutralForegroundDisabled1: rgbbdbdbd, + neutralForegroundDisabled2: rgbbdbdbd, + neutralForegroundInverted: rgbffffff, + neutralForegroundInvertedLink: rgbffffff, + brandForegroundLink: rgb185abd, + compoundBrandForeground1: rgb185abd, + brandForeground2: rgb1651aa, + brandForegroundTint: rgb1651aa, + brandForeground1Disabled: rgbbdbdbd, + brandForegroundDisabled1: rgbbdbdbd, + brandForegroundDisabled2: rgbbdbdbd, + neutralBackgroundCanvas: rgbffffff, + neutralBackgroundLightStaticDisabled: rgbf0f0f0, + brandBackgroundInverted: rgb616161, + brandBackgroundInvertedDisabled: rgbf0f0f0, + brandBackgroundDisabled: rgbf0f0f0, + neutralStroke3: rgbf0f0f0, + neutralStrokeFocus1: rgbffffff, + neutralStrokeFocus2: rgb000000, + strokeFocus1: rgbffffff, + strokeFocus2: rgb000000, + dangerStroke1: rgbf1bbbc, + successStroke1: rgb9fd89f, + warningStroke1: rgbfef7b2, + severeStroke1: rgbf4bfab, + dangerBorder1: rgbf1bbbc, + successBorder1: rgb9fd89f, + warningBorder1: rgbfef7b2, + severeBorder1: rgbf4bfab, + presenceAway: rgb817400, + presenceDnd: rgbbc2f32, + presenceAvailable: rgb0e700e, + presenceOof: rgbaf33a1, + redBackground1: rgbfdf6f6, + redBackground2: rgbf1bbbc, + redForeground1: rgbbc2f32, + redForeground2: rgb751d1f, + redForeground3: rgbd13438, + redBorderActive: rgbd13438, + redBorder1: rgbf1bbbc, + redBorder2: rgbd13438, + neutralForeground1: rgb242424, + neutralForeground1Hover: rgb242424, + neutralForeground1Pressed: rgb242424, + neutralForeground1Selected: rgb242424, + neutralForeground2: rgb424242, + neutralForeground2Hover: rgb242424, + neutralForeground2Pressed: rgb242424, + neutralForeground2Selected: rgb242424, + neutralForeground2BrandHover: rgb1651aa, + neutralForeground2BrandPressed: rgb0e336a, + neutralForeground2BrandSelected: rgb13458f, + neutralForeground3: rgb616161, + neutralForeground3Hover: rgb424242, + neutralForeground3Pressed: rgb424242, + neutralForeground3Selected: rgb424242, + neutralForeground3BrandHover: rgb1651aa, + neutralForeground3BrandPressed: rgb0e336a, + neutralForeground3BrandSelected: rgb13458f, + brandForegroundLinkHover: rgb1651aa, + brandForegroundLinkPressed: rgb0e336a, + brandForegroundLinkSelected: rgb13458f, + compoundBrandForeground1Hover: rgb1651aa, + compoundBrandForeground1Pressed: rgb0e336a, + brandForeground1: rgb185abd, + neutralForegroundInvertedLinkHover: rgbffffff, + neutralForegroundInvertedLinkPressed: rgbffffff, + neutralForegroundInvertedLinkSelected: rgbffffff, + neutralBackground1: rgbffffff, + neutralBackground1Hover: rgbf5f5f5, + neutralBackground1Pressed: rgbe0e0e0, + neutralBackground1Selected: rgbebebeb, + neutralBackground2: rgbfafafa, + neutralBackground2Hover: rgbf0f0f0, + neutralBackground2Pressed: '#dbdbdb', + neutralBackground2Selected: rgbe6e6e6, + neutralBackground3: rgbf5f5f5, + neutralBackground3Hover: rgbebebeb, + neutralBackground3Pressed: rgbd6d6d6, + neutralBackground3Selected: rgbe0e0e0, + neutralBackground4: rgbf0f0f0, + neutralBackground4Hover: rgbfafafa, + neutralBackground4Pressed: rgbf5f5f5, + neutralBackground4Selected: rgbffffff, + neutralBackground5: rgbebebeb, + neutralBackground5Hover: rgbf5f5f5, + neutralBackground5Pressed: rgbf0f0f0, + neutralBackground5Selected: rgbfafafa, + neutralBackground6: rgbe6e6e6, + neutralBackgroundInverted: rgb616161, + subtleBackgroundHover: rgbf5f5f5, + subtleBackgroundPressed: rgbe0e0e0, + subtleBackgroundSelected: rgbebebeb, + neutralBackgroundDisabled: rgbf0f0f0, + neutralStencil1: rgbe6e6e6, + neutralStencil2: rgbfafafa, + neutralStrokeAccessible: rgb616161, + neutralStrokeAccessibleHover: rgb575757, + neutralStrokeAccessiblePressed: rgb4d4d4d, + neutralStroke1: '#d1d1d1', + neutralStroke1Hover: '#c7c7c7', + neutralStroke1Pressed: rgbb3b3b3, + neutralStroke1Selected: rgbbdbdbd, + neutralStroke2: rgbe0e0e0, + neutralStrokeDisabled: rgbe0e0e0, + dangerBackground1: rgbfdf6f6, + dangerBackground2: rgbf1bbbc, + dangerForeground1: rgbbc2f32, + dangerForeground2: rgb751d1f, + dangerForeground3: rgbd13438, + dangerForegroundInverted: rgbdc5e62, + dangerBorderActive: rgbd13438, + dangerBorder2: rgbd13438, + successBackground1: '#f1faf1', + successBackground2: rgb9fd89f, + successForeground1: rgb0e700e, + successForeground2: rgb094509, + successForeground3: rgb107c10, + successForegroundInverted: '#359b35', + successBorderActive: rgb107c10, + successBorder2: rgb107c10, + warningBackground1: '#fffef5', + warningBackground2: rgbfef7b2, + warningForeground1: rgb817400, + warningForeground2: rgb817400, + warningForeground3: rgbfde300, + warningForegroundInverted: rgbfef7b2, + warningBorderActive: rgbfde300, + warningBorder2: rgbfde300, + severeBackground1: '#fdf6f3', + severeBackground2: rgbf4bfab, + severeForeground1: '#c43501', + severeForeground2: rgb7a2101, + severeForeground3: rgbda3b01, + severeBorderActive: rgbda3b01, + severeBorder2: rgbda3b01, + outofofficeBackground1: '#fdf5fc', + outofofficeBackground2: rgbedbbe7, + outofofficeForeground1: rgbaf33a1, + outofofficeForeground2: rgb6d2064, + outofofficeForeground3: rgbc239b3, + outofofficeBorderActive: rgbc239b3, + outofofficeBorder1: rgbedbbe7, + outofofficeBorder2: rgbc239b3, + brandForeground1Pressed: rgb185abd, + neutralBackgroundDarkStatic: rgb242424, + brandForeground1Selected: rgb185abd, +}; + +export const darkAliasColors: Required<AliasColorTokens> = { + ...darkDarkElevatedAliasColors, + neutralForeground4: rgb999999, + neutralForegroundDisabled: rgb5c5c5c, + neutralForegroundDisabled1: rgb5c5c5c, + neutralForegroundDisabled2: rgb5c5c5c, + neutralForegroundInvertedLink: rgb292929, + brandForeground1Disabled: rgb5c5c5c, + brandForegroundDisabled1: rgb5c5c5c, + brandForegroundDisabled2: rgb5c5c5c, + neutralBackgroundCanvas: rgb292929, + neutralBackgroundLightStaticDisabled: rgb141414, + brandBackgroundInvertedDisabled: rgb141414, + brandBackgroundDisabled: rgb141414, + neutralStroke3: rgb3d3d3d, + neutralForeground2: rgbd6d6d6, + neutralForeground3: rgbadadad, + neutralForeground3Hover: rgbd6d6d6, + neutralForeground3Pressed: rgbd6d6d6, + neutralForeground3Selected: rgbd6d6d6, + neutralForegroundInvertedLinkHover: rgb292929, + neutralForegroundInvertedLinkPressed: rgb292929, + neutralForegroundInvertedLinkSelected: rgb292929, + neutralBackground1: rgb292929, + neutralBackground1Hover: rgb3d3d3d, + neutralBackground1Pressed: rgb1f1f1f, + neutralBackground1Selected: rgb383838, + neutralBackground2: rgb1f1f1f, + neutralBackground2Hover: rgb333333, + neutralBackground2Pressed: rgb141414, + neutralBackground2Selected: rgb2e2e2e, + neutralBackground3: rgb141414, + neutralBackground3Hover: rgb292929, + neutralBackground3Pressed: rgb0a0a0a, + neutralBackground3Selected: rgb242424, + neutralBackground4: rgb0a0a0a, + neutralBackground4Hover: rgb1f1f1f, + neutralBackground4Pressed: rgb000000, + neutralBackground4Selected: rgb1a1a1a, + neutralBackground5: rgb000000, + neutralBackground5Hover: rgb141414, + neutralBackground5Pressed: '#050505', + neutralBackground5Selected: '#0f0f0f', + neutralBackground6: rgb333333, + subtleBackgroundHover: rgb3d3d3d, + subtleBackgroundPressed: rgb1f1f1f, + subtleBackgroundSelected: rgb383838, + neutralBackgroundDisabled: rgb141414, + neutralStencil1: rgb333333, + neutralStencil2: rgb575757, + neutralStrokeAccessible: rgbadadad, + neutralStrokeAccessibleHover: rgbbdbdbd, + neutralStrokeAccessiblePressed: rgbb3b3b3, + neutralStroke1: rgb666666, + neutralStroke1Hover: rgb757575, + neutralStroke1Pressed: '#6b6b6b', + neutralStroke1Selected: rgb707070, + neutralStroke2: rgb525252, + neutralStrokeDisabled: rgb424242, +}; + +export const darkElevatedAliasColors: Required<AliasColorTokens> = { + ...darkDarkElevatedAliasColors, + neutralForeground4: '#c2c2c2', + neutralForegroundDisabled: rgb666666, + neutralForegroundDisabled1: rgb666666, + neutralForegroundDisabled2: rgb666666, + neutralForegroundInvertedLink: rgb4d4d4d, + brandForeground1Disabled: rgb666666, + brandForegroundDisabled1: rgb666666, + brandForegroundDisabled2: rgb666666, + neutralBackgroundCanvas: rgb4d4d4d, + neutralBackgroundLightStaticDisabled: rgb383838, + brandBackgroundInvertedDisabled: rgb383838, + brandBackgroundDisabled: rgb383838, + neutralStroke3: rgb616161, + neutralForeground2: rgbe6e6e6, + neutralForeground3: '#cccccc', + neutralForeground3Hover: rgbe6e6e6, + neutralForeground3Pressed: rgbe6e6e6, + neutralForeground3Selected: rgbe6e6e6, + neutralForegroundInvertedLinkHover: rgb4d4d4d, + neutralForegroundInvertedLinkPressed: rgb4d4d4d, + neutralForegroundInvertedLinkSelected: rgb4d4d4d, + neutralBackground1: rgb4d4d4d, + neutralBackground1Hover: rgb5c5c5c, + neutralBackground1Pressed: rgb424242, + neutralBackground1Selected: rgb575757, + neutralBackground2: rgb424242, + neutralBackground2Hover: rgb525252, + neutralBackground2Pressed: rgb383838, + neutralBackground2Selected: rgb4d4d4d, + neutralBackground3: rgb383838, + neutralBackground3Hover: rgb474747, + neutralBackground3Pressed: rgb2e2e2e, + neutralBackground3Selected: rgb424242, + neutralBackground4: rgb2e2e2e, + neutralBackground4Hover: rgb3d3d3d, + neutralBackground4Pressed: rgb242424, + neutralBackground4Selected: rgb383838, + neutralBackground5: rgb242424, + neutralBackground5Hover: rgb333333, + neutralBackground5Pressed: rgb1a1a1a, + neutralBackground5Selected: rgb2e2e2e, + neutralBackground6: rgb1a1a1a, + subtleBackgroundHover: rgb5c5c5c, + subtleBackgroundPressed: rgb424242, + subtleBackgroundSelected: rgb575757, + neutralBackgroundDisabled: rgb383838, + neutralStencil1: rgb1a1a1a, + neutralStencil2: rgb424242, + neutralStrokeAccessible: '#a8a8a8', + neutralStrokeAccessibleHover: '#b8b8b8', + neutralStrokeAccessiblePressed: rgbadadad, + neutralStroke1: '#8a8a8a', + neutralStroke1Hover: rgb999999, + neutralStroke1Pressed: '#8f8f8f', + neutralStroke1Selected: '#949494', + neutralStroke2: rgb757575, + neutralStrokeDisabled: rgb474747, +}; + +export const hcDarkAliasColors: Required<AliasColorTokens> = { + ...darkDarkElevatedHcDarkHcLightAliasColors, + neutralForeground4: platformColorWindowText, + neutralForegroundDisabled: platformColorGrayText, + neutralForegroundDisabled1: platformColorGrayText, + neutralForegroundDisabled2: platformColorGrayText, + neutralForegroundOnBrand: platformColorButtonText, + neutralForegroundOnColor: platformColorButtonText, + neutralForegroundInverted: platformColorWindow, + neutralForegroundInvertedLink: platformColorHotlight, + brandForegroundLink: platformColorHotlight, + compoundBrandForeground1: platformColorHighlight, + brandForeground2: platformColorButtonText, + brandForegroundTint: platformColorButtonText, + brandForeground1Disabled: platformColorGrayText, + brandForegroundDisabled1: platformColorGrayText, + brandForegroundDisabled2: platformColorGrayText, + neutralBackgroundCanvas: platformColorWindow, + neutralBackgroundLightStaticDisabled: platformColorWindow, + brandBackground2: platformColorButtonFace, + brandBackground3: platformColorButtonFace, + brandBackgroundTint: platformColorButtonFace, + brandBackgroundInverted: platformColorWindowText, + brandBackgroundInvertedDisabled: platformColorWindow, + brandBackgroundDisabled: platformColorWindow, + compoundBrandBackground1: platformColorHighlight, + brandBackgroundStatic: platformColorWindow, + neutralStroke3: platformColorWindowText, + neutralStrokeFocus1: platformColorWindow, + neutralStrokeFocus2: platformColorHighlight, + strokeFocus1: platformColorWindow, + strokeFocus2: platformColorHighlight, + brandStroke2: platformColorWindow, + brandStrokeTint: platformColorWindow, + compoundBrandStroke1: platformColorHighlight, + dangerStroke1: platformColorWindowText, + successStroke1: platformColorWindowText, + warningStroke1: platformColorWindowText, + severeStroke1: platformColorWindowText, + dangerBorder1: platformColorWindowText, + successBorder1: platformColorWindowText, + warningBorder1: platformColorWindowText, + severeBorder1: platformColorWindowText, + presenceAway: platformColorWindowText, + presenceDnd: platformColorWindowText, + presenceAvailable: platformColorWindowText, + presenceOof: platformColorWindowText, + redBackground1: platformColorWindow, + redBackground2: platformColorWindow, + redBackground3: platformColorWindowText, + redForeground1: platformColorWindowText, + redForeground2: platformColorWindowText, + redForeground3: platformColorWindowText, + redBorderActive: platformColorHighlight, + redBorder1: platformColorWindowText, + redBorder2: platformColorWindowText, + neutralForeground1: platformColorWindowText, + neutralForeground1Hover: platformColorHighlightText, + neutralForeground1Pressed: platformColorHighlightText, + neutralForeground1Selected: platformColorHighlightText, + neutralForeground2: platformColorWindowText, + neutralForeground2Hover: platformColorHighlightText, + neutralForeground2Pressed: platformColorHighlightText, + neutralForeground2Selected: platformColorHighlightText, + neutralForeground2BrandHover: platformColorHighlightText, + neutralForeground2BrandPressed: platformColorHighlightText, + neutralForeground2BrandSelected: platformColorHighlightText, + neutralForeground3: platformColorWindowText, + neutralForeground3Hover: platformColorHighlightText, + neutralForeground3Pressed: platformColorHighlightText, + neutralForeground3Selected: platformColorHighlightText, + neutralForeground3BrandHover: platformColorHighlightText, + neutralForeground3BrandPressed: platformColorHighlightText, + neutralForeground3BrandSelected: platformColorHighlightText, + brandForegroundLinkHover: platformColorHotlight, + brandForegroundLinkPressed: platformColorHotlight, + brandForegroundLinkSelected: platformColorHotlight, + compoundBrandForeground1Hover: platformColorHighlight, + compoundBrandForeground1Pressed: platformColorHighlight, + brandForeground1: platformColorWindowText, + neutralForegroundOnBrandHover: platformColorHighlightText, + neutralForegroundOnBrandPressed: platformColorHighlightText, + neutralForegroundOnBrandSelected: platformColorHighlightText, + neutralForegroundInvertedLinkHover: platformColorHotlight, + neutralForegroundInvertedLinkPressed: platformColorHotlight, + neutralForegroundInvertedLinkSelected: platformColorHotlight, + neutralBackground1: platformColorWindow, + neutralBackground1Hover: platformColorHighlight, + neutralBackground1Pressed: platformColorHighlight, + neutralBackground1Selected: platformColorHighlight, + neutralBackground2: platformColorWindow, + neutralBackground2Hover: platformColorHighlight, + neutralBackground2Pressed: platformColorHighlight, + neutralBackground2Selected: platformColorHighlight, + neutralBackground3: platformColorWindow, + neutralBackground3Hover: platformColorHighlight, + neutralBackground3Pressed: platformColorHighlight, + neutralBackground3Selected: platformColorHighlight, + neutralBackground4: platformColorWindow, + neutralBackground4Hover: platformColorHighlight, + neutralBackground4Pressed: platformColorHighlight, + neutralBackground4Selected: platformColorHighlight, + neutralBackground5: platformColorWindow, + neutralBackground5Hover: platformColorHighlight, + neutralBackground5Pressed: platformColorHighlight, + neutralBackground5Selected: platformColorHighlight, + neutralBackground6: platformColorWindow, + neutralBackgroundInverted: platformColorWindowText, + subtleBackgroundHover: platformColorHighlight, + subtleBackgroundPressed: platformColorHighlight, + subtleBackgroundSelected: platformColorHighlight, + neutralBackgroundDisabled: platformColorWindow, + neutralStencil1: rgb141414, + neutralStencil2: '#858585', + brandBackground: platformColorButtonFace, + brandBackgroundHover: platformColorHighlight, + brandBackgroundPressed: platformColorHighlight, + brandBackgroundSelected: platformColorHighlight, + compoundBrandBackground1Hover: platformColorHighlight, + compoundBrandBackground1Pressed: platformColorHighlight, + neutralStrokeAccessible: platformColorWindowText, + neutralStrokeAccessibleHover: platformColorHighlight, + neutralStrokeAccessiblePressed: platformColorHighlight, + neutralStrokeAccessibleSelected: platformColorHighlight, + neutralStroke1: platformColorWindowText, + neutralStroke1Hover: platformColorHighlight, + neutralStroke1Pressed: platformColorHighlight, + neutralStroke1Selected: platformColorHighlight, + neutralStroke2: platformColorWindowText, + brandStroke1: platformColorWindowText, + compoundBrandStroke1Hover: platformColorHighlight, + compoundBrandStroke1Pressed: platformColorHighlight, + neutralStrokeDisabled: platformColorGrayText, + transparentStroke: platformColorWindowText, + transparentStrokeInteractive: platformColorHighlight, + transparentStrokeDisabled: platformColorGrayText, + dangerBackground1: platformColorWindow, + dangerBackground2: platformColorWindow, + dangerBackground3: platformColorWindowText, + dangerForeground1: platformColorWindowText, + dangerForeground2: platformColorWindowText, + dangerForeground3: platformColorWindowText, + dangerForegroundInverted: platformColorWindowText, + dangerBorderActive: platformColorHighlight, + dangerBorder2: platformColorWindowText, + successBackground1: platformColorWindow, + successBackground2: platformColorWindow, + successBackground3: platformColorWindowText, + successForeground1: platformColorWindowText, + successForeground2: platformColorWindowText, + successForeground3: platformColorWindowText, + successForegroundInverted: platformColorWindowText, + successBorderActive: platformColorHighlight, + successBorder2: platformColorWindowText, + warningBackground1: platformColorWindow, + warningBackground2: platformColorWindow, + warningBackground3: platformColorWindowText, + warningForeground1: platformColorWindowText, + warningForeground2: platformColorWindowText, + warningForeground3: platformColorWindowText, + warningForegroundInverted: platformColorWindowText, + warningBorderActive: platformColorHighlight, + warningBorder2: platformColorWindowText, + severeBackground1: platformColorWindow, + severeBackground2: platformColorWindow, + severeBackground3: platformColorWindowText, + severeForeground1: platformColorWindowText, + severeForeground2: platformColorWindowText, + severeForeground3: platformColorWindowText, + severeBorderActive: platformColorHighlight, + severeBorder2: platformColorWindowText, + outofofficeBackground1: platformColorWindow, + outofofficeBackground2: platformColorWindow, + outofofficeBackground3: platformColorWindowText, + outofofficeForeground1: platformColorWindowText, + outofofficeForeground2: platformColorWindowText, + outofofficeForeground3: platformColorWindowText, + outofofficeBorderActive: platformColorHighlight, + outofofficeBorder1: platformColorWindowText, + outofofficeBorder2: platformColorWindowText, + brandForeground1Pressed: platformColorWindowText, + brandBackground2Pressed: platformColorHighlight, + brandBackground2Selected: platformColorHighlight, + brandForeground1Selected: platformColorWindowText, + brandStroke1Pressed: platformColorWindowText, + brandStroke1Selected: platformColorWindowText, +}; + +export const lightElevatedAliasColors: Required<AliasColorTokens> = lightAliasColors; +export const hcLightAliasColors: Required<AliasColorTokens> = hcDarkAliasColors; + +/** Font aliases from the light appearance, completed with native equivalents and the platform global ramp. */ +export const fontAliasTokens: Required<Variants> = { + caption1, + body1, + body1Strong, + body2, + body2Strong, + subtitle1, + subtitle1Strong, + subtitle2, + subtitle2Strong, + title1, + title1Strong, + largeTitle, + display, + caption1Strong: { face: primary, size: 10, weight: fontWeight600 }, + caption2: caption1, + title2: subtitle1, + title3: subtitle2, + captionStandard: caption1, + secondaryStandard: body1, + secondarySemibold: body1Strong, + bodyStandard: body2, + bodySemibold: body2Strong, + subheaderStandard: subtitle2, + subheaderSemibold: subtitle2Strong, + headerStandard: subtitle1, + headerSemibold: subtitle1Strong, + heroStandard: title1, + heroSemibold: title1Strong, + heroLargeStandard: largeTitle, + heroLargeSemibold: display, +}; diff --git a/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.windows.ts b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.windows.ts new file mode 100644 index 00000000000..23b273206df --- /dev/null +++ b/packages/agentic/design/src/fluent/defaults/fluentTokens.generated.windows.ts @@ -0,0 +1,750 @@ +/** + * WARNING: This file is auto-generated by scripts/fluent-tokens.cts. Do not edit it manually. + * Complete Fluent tokens: native values, same-platform equivalents, then same-scheme portable defaults. + * An appearance without token data inherits elevated from standard, and high contrast from the other + * high-contrast appearance, else from standard. Shared values are emitted once. + */ +import { PlatformColor } from 'react-native'; + +import type { AliasColorTokens } from '../types/Color.types'; +import type { BaseShadowAliasTokens } from '../types/Shadow.types'; +import type { Variants } from '../types/Typography.types'; + +const platformColorButtonFace = /* @__PURE__ */ PlatformColor('SystemColorButtonFaceColor'); +const platformColorButtonText = /* @__PURE__ */ PlatformColor('SystemColorButtonTextColor'); +const platformColorGrayText = /* @__PURE__ */ PlatformColor('SystemColorGrayTextColor'); +const platformColorHighlight = /* @__PURE__ */ PlatformColor('SystemColorHighlightColor'); +const platformColorHighlightText = /* @__PURE__ */ PlatformColor('SystemColorHighlightTextColor'); +const platformColorHotlight = /* @__PURE__ */ PlatformColor('SystemColorHotlightColor'); +const platformColorWindow = /* @__PURE__ */ PlatformColor('SystemColorWindowColor'); +const platformColorWindowText = /* @__PURE__ */ PlatformColor('SystemColorWindowTextColor'); + +const fontWeight400 = '400'; +const fontWeight600 = '600'; +const primary = 'primary'; +const rgb000000 = '#000000'; +const rgb00000000 = '#00000000'; +const rgb00000024 = '#00000024'; +const rgb0000003d = '#0000003d'; +const rgb00000040 = '#00000040'; +const rgb00000047 = '#00000047'; +const rgb0000004d = '#0000004d'; +const rgb0000007a = '#0000007a'; +const rgb004578 = '#004578'; +const rgb094509 = '#094509'; +const rgb0a0a0a = '#0a0a0a'; +const rgb0e336a = '#0e336a'; +const rgb0e700e = '#0e700e'; +const rgb107c10 = '#107c10'; +const rgb13458f = '#13458f'; +const rgb141414 = '#141414'; +const rgb1651aa = '#1651aa'; +const rgb185abd = '#185abd'; +const rgb1f1f1f = '#1f1f1f'; +const rgb242424 = '#242424'; +const rgb292929 = '#292929'; +const rgb2e2e2e = '#2e2e2e'; +const rgb2e6ac5 = '#2e6ac5'; +const rgb333333 = '#333333'; +const rgb383838 = '#383838'; +const rgb3d3d3d = '#3d3d3d'; +const rgb3f1011 = '#3f1011'; +const rgb424242 = '#424242'; +const rgb54b054 = '#54b054'; +const rgb575757 = '#575757'; +const rgb5c5c5c = '#5c5c5c'; +const rgb616161 = '#616161'; +const rgb6794d7 = '#6794d7'; +const rgb6d2064 = '#6d2064'; +const rgb707070 = '#707070'; +const rgb751d1f = '#751d1f'; +const rgb7a2101 = '#7a2101'; +const rgb817400 = '#817400'; +const rgb9fd89f = '#9fd89f'; +const rgbadadad = '#adadad'; +const rgbaec6eb = '#aec6eb'; +const rgbaf33a1 = '#af33a1'; +const rgbb3b3b3 = '#b3b3b3'; +const rgbbc2f32 = '#bc2f32'; +const rgbbdbdbd = '#bdbdbd'; +const rgbc239b3 = '#c239b3'; +const rgbd13438 = '#d13438'; +const rgbd161c4 = '#d161c4'; +const rgbd2e0f4 = '#d2e0f4'; +const rgbd6d6d6 = '#d6d6d6'; +const rgbda3b01 = '#da3b01'; +const rgbda7ed0 = '#da7ed0'; +const rgbdc5e62 = '#dc5e62'; +const rgbe0e0e0 = '#e0e0e0'; +const rgbe37d80 = '#e37d80'; +const rgbe6e6e6 = '#e6e6e6'; +const rgbe9835e = '#e9835e'; +const rgbebebeb = '#ebebeb'; +const rgbedbbe7 = '#edbbe7'; +const rgbeff6fc = '#eff6fc'; +const rgbf0f0f0 = '#f0f0f0'; +const rgbf1bbbc = '#f1bbbc'; +const rgbf4bfab = '#f4bfab'; +const rgbf5f5f5 = '#f5f5f5'; +const rgbfafafa = '#fafafa'; +const rgbfde300 = '#fde300'; +const rgbfdea3d = '#fdea3d'; +const rgbfdf6f6 = '#fdf6f6'; +const rgbfeee66 = '#feee66'; +const rgbfef7b2 = '#fef7b2'; +const rgbffffff = '#ffffff'; + +const body1 = { face: primary, size: 12, weight: fontWeight400 } as const; +const body1Strong = { face: primary, size: 12, weight: fontWeight600 } as const; +const body2 = { face: primary, size: 14, weight: fontWeight400 } as const; +const body2Strong = { face: primary, size: 14, weight: fontWeight600 } as const; +const caption1 = { face: primary, size: 10, weight: fontWeight400 } as const; +const display = { face: primary, size: 40, weight: fontWeight600 } as const; +const largeTitle = { face: primary, size: 40, weight: fontWeight400 } as const; +const shadowLayer1 = { color: '#0000001f', x: 0, y: 0, blur: 2 } as const; +const shadowLayer2 = { color: '#00000033', x: 0, y: 0, blur: 8 } as const; +const shadowLayer3 = { color: rgb0000004d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer4 = { color: rgb0000004d, x: 0, y: 0, blur: 8 } as const; +const shadowLayer5 = { color: rgb0000003d, x: 0, y: 0, blur: 2 } as const; +const shadowLayer6 = { color: '#00000066', x: 0, y: 0, blur: 8 } as const; +const subtitle1 = { face: primary, size: 20, weight: fontWeight400 } as const; +const subtitle1Strong = { face: primary, size: 20, weight: fontWeight600 } as const; +const subtitle2 = { face: primary, size: 16, weight: fontWeight400 } as const; +const subtitle2Strong = { face: primary, size: 16, weight: fontWeight600 } as const; +const title1 = { face: primary, size: 28, weight: fontWeight400 } as const; +const title1Strong = { face: primary, size: 28, weight: fontWeight600 } as const; + +const sharedAliasColors = { + subtleBackground: rgb00000000, + transparentBackground: rgb00000000, + transparentBackgroundHover: rgb00000000, + transparentBackgroundPressed: rgb00000000, + transparentBackgroundSelected: rgb00000000, + neutralBackgroundLightStatic: rgbffffff, + neutralForegroundDarkStatic: rgb000000, + neutralForegroundLightStatic: rgbffffff, +} as const; + +const lightDarkLightElevatedDarkElevatedAliasColors = { + ...sharedAliasColors, + neutralForegroundOnBrand: rgbffffff, + neutralForegroundOnColor: rgbffffff, + neutralForegroundInvertedLink: rgbffffff, + brandBackgroundStatic: rgb185abd, + redBackground3: rgbd13438, + neutralForegroundOnBrandHover: rgbffffff, + neutralForegroundOnBrandPressed: rgbffffff, + neutralForegroundOnBrandSelected: rgbffffff, + neutralForegroundInvertedLinkHover: rgbffffff, + neutralForegroundInvertedLinkPressed: rgbffffff, + neutralForegroundInvertedLinkSelected: rgbffffff, + brandBackgroundPressed: rgb004578, + brandBackgroundSelected: rgb13458f, + transparentStroke: rgb00000000, + transparentStrokeInteractive: rgb00000000, + transparentStrokeDisabled: rgb00000000, + dangerBackground3: rgbd13438, + successBackground3: rgb107c10, + warningBackground3: rgbfde300, + severeBackground3: rgbda3b01, + outofofficeBackground3: rgbc239b3, + brandBackground2Pressed: rgb004578, + brandBackground2Selected: rgb13458f, +} as const; + +const darkHcDarkDarkElevatedHcLightAliasColors = { + ...sharedAliasColors, + neutralBackgroundDarkStatic: rgb3d3d3d, +} as const; + +const sharedShadows = { + shadow2brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 1, blur: 2 } }, + shadow4brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 2, blur: 4 } }, + shadow8brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 4, blur: 8 } }, + shadow16brand: { ambient: shadowLayer3, key: { color: rgb00000040, x: 0, y: 8, blur: 16 } }, + shadow28brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 14, blur: 28 } }, + shadow64brand: { ambient: shadowLayer4, key: { color: rgb00000040, x: 0, y: 32, blur: 64 } }, +} as const; + +export const lightShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer1, key: { color: rgb00000024, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer2, key: { color: rgb0000003d, x: 0, y: 32, blur: 64 } }, +}; + +export const darkShadows: BaseShadowAliasTokens = { + ...sharedShadows, + shadow2: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 1, blur: 2 } }, + shadow4: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 2, blur: 4 } }, + shadow8: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 4, blur: 8 } }, + shadow16: { ambient: shadowLayer5, key: { color: rgb00000047, x: 0, y: 8, blur: 16 } }, + shadow28: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 14, blur: 28 } }, + shadow64: { ambient: shadowLayer6, key: { color: rgb0000007a, x: 0, y: 32, blur: 64 } }, +}; + +export const hcDarkShadows: BaseShadowAliasTokens = darkShadows; +export const lightElevatedShadows: BaseShadowAliasTokens = lightShadows; +export const darkElevatedShadows: BaseShadowAliasTokens = darkShadows; +export const hcLightShadows: BaseShadowAliasTokens = darkShadows; + +export const lightAliasColors: Required<AliasColorTokens> = { + ...lightDarkLightElevatedDarkElevatedAliasColors, + neutralForeground4: rgb707070, + neutralForegroundDisabled: rgbbdbdbd, + neutralForegroundDisabled1: rgbbdbdbd, + neutralForegroundDisabled2: rgbbdbdbd, + neutralForegroundInverted: rgbffffff, + brandForegroundLink: rgb1651aa, + compoundBrandForeground1: rgb185abd, + brandForeground2: rgb1651aa, + brandForegroundTint: rgb1651aa, + brandForeground1Disabled: rgbbdbdbd, + brandForegroundDisabled1: rgbbdbdbd, + brandForegroundDisabled2: rgbbdbdbd, + neutralBackgroundCanvas: rgbffffff, + neutralBackgroundLightStaticDisabled: rgbf0f0f0, + brandBackground2: rgbeff6fc, + brandBackground3: rgbeff6fc, + brandBackgroundTint: rgbeff6fc, + brandBackgroundInverted: rgb616161, + brandBackgroundInvertedDisabled: rgbf0f0f0, + brandBackgroundDisabled: rgbf0f0f0, + compoundBrandBackground1: rgb185abd, + neutralStroke3: rgbf0f0f0, + neutralStrokeFocus1: rgbffffff, + neutralStrokeFocus2: rgb000000, + strokeFocus1: rgbffffff, + strokeFocus2: rgb000000, + brandStroke2: rgbd2e0f4, + brandStrokeTint: rgbd2e0f4, + compoundBrandStroke1: rgb185abd, + dangerStroke1: rgbf1bbbc, + successStroke1: rgb9fd89f, + warningStroke1: rgbfef7b2, + severeStroke1: rgbf4bfab, + dangerBorder1: rgbf1bbbc, + successBorder1: rgb9fd89f, + warningBorder1: rgbfef7b2, + severeBorder1: rgbf4bfab, + presenceAway: rgb817400, + presenceDnd: rgbbc2f32, + presenceAvailable: rgb0e700e, + presenceOof: rgbaf33a1, + redBackground1: rgbfdf6f6, + redBackground2: rgbf1bbbc, + redForeground1: rgbbc2f32, + redForeground2: rgb751d1f, + redForeground3: rgbd13438, + redBorderActive: rgbd13438, + redBorder1: rgbf1bbbc, + redBorder2: rgbd13438, + neutralForeground1: rgb242424, + neutralForeground1Hover: rgb242424, + neutralForeground1Pressed: rgb242424, + neutralForeground1Selected: rgb242424, + neutralForeground2: rgb424242, + neutralForeground2Hover: rgb242424, + neutralForeground2Pressed: rgb242424, + neutralForeground2Selected: rgb242424, + neutralForeground2BrandHover: rgb185abd, + neutralForeground2BrandPressed: rgb1651aa, + neutralForeground2BrandSelected: rgb185abd, + neutralForeground3: rgb616161, + neutralForeground3Hover: rgb424242, + neutralForeground3Pressed: rgb424242, + neutralForeground3Selected: rgb424242, + neutralForeground3BrandHover: rgb185abd, + neutralForeground3BrandPressed: rgb1651aa, + neutralForeground3BrandSelected: rgb185abd, + brandForegroundLinkHover: rgb13458f, + brandForegroundLinkPressed: rgb004578, + brandForegroundLinkSelected: rgb1651aa, + compoundBrandForeground1Hover: rgb1651aa, + compoundBrandForeground1Pressed: rgb13458f, + brandForeground1: rgb185abd, + neutralBackground1: rgbffffff, + neutralBackground1Hover: rgbf5f5f5, + neutralBackground1Pressed: rgbe0e0e0, + neutralBackground1Selected: rgbebebeb, + neutralBackground2: rgbfafafa, + neutralBackground2Hover: rgbf0f0f0, + neutralBackground2Pressed: '#dbdbdb', + neutralBackground2Selected: rgbe6e6e6, + neutralBackground3: rgbf5f5f5, + neutralBackground3Hover: rgbebebeb, + neutralBackground3Pressed: rgbd6d6d6, + neutralBackground3Selected: rgbe0e0e0, + neutralBackground4: rgbf0f0f0, + neutralBackground4Hover: rgbfafafa, + neutralBackground4Pressed: rgbf5f5f5, + neutralBackground4Selected: rgbffffff, + neutralBackground5: rgbebebeb, + neutralBackground5Hover: rgbf5f5f5, + neutralBackground5Pressed: rgbf0f0f0, + neutralBackground5Selected: rgbfafafa, + neutralBackground6: rgbe6e6e6, + neutralBackgroundInverted: rgb616161, + subtleBackgroundHover: rgbf5f5f5, + subtleBackgroundPressed: rgbe0e0e0, + subtleBackgroundSelected: rgbebebeb, + neutralBackgroundDisabled: rgbf0f0f0, + neutralStencil1: rgbe6e6e6, + neutralStencil2: rgbfafafa, + brandBackground: rgb185abd, + brandBackgroundHover: rgb1651aa, + compoundBrandBackground1Hover: rgb1651aa, + compoundBrandBackground1Pressed: rgb13458f, + neutralStrokeAccessible: rgb616161, + neutralStrokeAccessibleHover: rgb575757, + neutralStrokeAccessiblePressed: '#4d4d4d', + neutralStrokeAccessibleSelected: rgb185abd, + neutralStroke1: '#d1d1d1', + neutralStroke1Hover: '#c7c7c7', + neutralStroke1Pressed: rgbb3b3b3, + neutralStroke1Selected: rgbbdbdbd, + neutralStroke2: rgbe0e0e0, + brandStroke1: rgb185abd, + compoundBrandStroke1Hover: rgb1651aa, + compoundBrandStroke1Pressed: rgb13458f, + neutralStrokeDisabled: rgbe0e0e0, + dangerBackground1: rgbfdf6f6, + dangerBackground2: rgbf1bbbc, + dangerForeground1: rgbbc2f32, + dangerForeground2: rgb751d1f, + dangerForeground3: rgbd13438, + dangerForegroundInverted: rgbdc5e62, + dangerBorderActive: rgbd13438, + dangerBorder2: rgbd13438, + successBackground1: '#f1faf1', + successBackground2: rgb9fd89f, + successForeground1: rgb0e700e, + successForeground2: rgb094509, + successForeground3: rgb107c10, + successForegroundInverted: '#359b35', + successBorderActive: rgb107c10, + successBorder2: rgb107c10, + warningBackground1: '#fffef5', + warningBackground2: rgbfef7b2, + warningForeground1: rgb817400, + warningForeground2: rgb817400, + warningForeground3: rgbfde300, + warningForegroundInverted: rgbfef7b2, + warningBorderActive: rgbfde300, + warningBorder2: rgbfde300, + severeBackground1: '#fdf6f3', + severeBackground2: rgbf4bfab, + severeForeground1: '#c43501', + severeForeground2: rgb7a2101, + severeForeground3: rgbda3b01, + severeBorderActive: rgbda3b01, + severeBorder2: rgbda3b01, + outofofficeBackground1: '#fdf5fc', + outofofficeBackground2: rgbedbbe7, + outofofficeForeground1: rgbaf33a1, + outofofficeForeground2: rgb6d2064, + outofofficeForeground3: rgbc239b3, + outofofficeBorderActive: rgbc239b3, + outofofficeBorder1: rgbedbbe7, + outofofficeBorder2: rgbc239b3, + brandForeground1Pressed: rgb185abd, + neutralBackgroundDarkStatic: rgb242424, + brandForeground1Selected: rgb185abd, + brandStroke1Pressed: rgb185abd, + brandStroke1Selected: rgb185abd, +}; + +export const darkAliasColors: Required<AliasColorTokens> = { + ...lightDarkLightElevatedDarkElevatedAliasColors, + ...darkHcDarkDarkElevatedHcLightAliasColors, + neutralForeground4: '#999999', + neutralForegroundDisabled: rgb5c5c5c, + neutralForegroundDisabled1: rgb5c5c5c, + neutralForegroundDisabled2: rgb5c5c5c, + neutralForegroundInverted: rgb242424, + brandForegroundLink: rgb2e6ac5, + compoundBrandForeground1: rgb2e6ac5, + brandForeground2: rgbaec6eb, + brandForegroundTint: rgbaec6eb, + brandForeground1Disabled: rgb5c5c5c, + brandForegroundDisabled1: rgb5c5c5c, + brandForegroundDisabled2: rgb5c5c5c, + neutralBackgroundCanvas: rgb292929, + neutralBackgroundLightStaticDisabled: rgb141414, + brandBackground2: rgb004578, + brandBackground3: rgb004578, + brandBackgroundTint: rgb004578, + brandBackgroundInverted: rgbffffff, + brandBackgroundInvertedDisabled: rgb141414, + brandBackgroundDisabled: rgb141414, + compoundBrandBackground1: rgb2e6ac5, + neutralStroke3: rgb3d3d3d, + neutralStrokeFocus1: rgb000000, + neutralStrokeFocus2: rgbffffff, + strokeFocus1: rgb000000, + strokeFocus2: rgbffffff, + brandStroke2: rgb0e336a, + brandStrokeTint: rgb0e336a, + compoundBrandStroke1: rgb2e6ac5, + dangerStroke1: rgbd13438, + successStroke1: rgb107c10, + warningStroke1: rgbfde300, + severeStroke1: rgbda3b01, + dangerBorder1: rgbd13438, + successBorder1: rgb107c10, + warningBorder1: rgbfde300, + severeBorder1: rgbda3b01, + presenceAway: rgbfeee66, + presenceDnd: rgbe37d80, + presenceAvailable: rgb54b054, + presenceOof: rgbda7ed0, + redBackground1: rgb3f1011, + redBackground2: rgb751d1f, + redForeground1: rgbe37d80, + redForeground2: rgbf1bbbc, + redForeground3: rgbe37d80, + redBorderActive: rgbe37d80, + redBorder1: rgbd13438, + redBorder2: rgbdc5e62, + neutralForeground1: rgbffffff, + neutralForeground1Hover: rgbffffff, + neutralForeground1Pressed: rgbffffff, + neutralForeground1Selected: rgbffffff, + neutralForeground2: rgbd6d6d6, + neutralForeground2Hover: rgbffffff, + neutralForeground2Pressed: rgbffffff, + neutralForeground2Selected: rgbffffff, + neutralForeground2BrandHover: rgb6794d7, + neutralForeground2BrandPressed: rgb2e6ac5, + neutralForeground2BrandSelected: rgb6794d7, + neutralForeground3: rgbadadad, + neutralForeground3Hover: rgbd6d6d6, + neutralForeground3Pressed: rgbd6d6d6, + neutralForeground3Selected: rgbd6d6d6, + neutralForeground3BrandHover: rgb6794d7, + neutralForeground3BrandPressed: rgb2e6ac5, + neutralForeground3BrandSelected: rgb6794d7, + brandForegroundLinkHover: rgbaec6eb, + brandForegroundLinkPressed: rgb6794d7, + brandForegroundLinkSelected: rgb2e6ac5, + compoundBrandForeground1Hover: rgb6794d7, + compoundBrandForeground1Pressed: rgb185abd, + brandForeground1: rgb6794d7, + neutralBackground1: rgb292929, + neutralBackground1Hover: rgb3d3d3d, + neutralBackground1Pressed: rgb1f1f1f, + neutralBackground1Selected: rgb383838, + neutralBackground2: rgb1f1f1f, + neutralBackground2Hover: rgb333333, + neutralBackground2Pressed: rgb141414, + neutralBackground2Selected: rgb2e2e2e, + neutralBackground3: rgb141414, + neutralBackground3Hover: rgb292929, + neutralBackground3Pressed: rgb0a0a0a, + neutralBackground3Selected: rgb242424, + neutralBackground4: rgb0a0a0a, + neutralBackground4Hover: rgb1f1f1f, + neutralBackground4Pressed: rgb000000, + neutralBackground4Selected: '#1a1a1a', + neutralBackground5: rgb000000, + neutralBackground5Hover: rgb141414, + neutralBackground5Pressed: '#050505', + neutralBackground5Selected: '#0f0f0f', + neutralBackground6: rgb333333, + neutralBackgroundInverted: rgbffffff, + subtleBackgroundHover: rgb383838, + subtleBackgroundPressed: rgb2e2e2e, + subtleBackgroundSelected: rgb333333, + neutralBackgroundDisabled: rgb141414, + neutralStencil1: rgb333333, + neutralStencil2: rgb575757, + brandBackground: rgb1651aa, + brandBackgroundHover: rgb185abd, + compoundBrandBackground1Hover: rgb6794d7, + compoundBrandBackground1Pressed: rgb185abd, + neutralStrokeAccessible: rgbadadad, + neutralStrokeAccessibleHover: rgbbdbdbd, + neutralStrokeAccessiblePressed: rgbb3b3b3, + neutralStrokeAccessibleSelected: rgb6794d7, + neutralStroke1: '#666666', + neutralStroke1Hover: '#757575', + neutralStroke1Pressed: '#6b6b6b', + neutralStroke1Selected: rgb707070, + neutralStroke2: '#525252', + brandStroke1: rgb2e6ac5, + compoundBrandStroke1Hover: rgb6794d7, + compoundBrandStroke1Pressed: rgb185abd, + neutralStrokeDisabled: rgb424242, + dangerBackground1: rgb3f1011, + dangerBackground2: rgb751d1f, + dangerForeground1: rgbe37d80, + dangerForeground2: rgbf1bbbc, + dangerForeground3: rgbe37d80, + dangerForegroundInverted: rgbd13438, + dangerBorderActive: rgbe37d80, + dangerBorder2: rgbdc5e62, + successBackground1: '#052505', + successBackground2: rgb094509, + successForeground1: rgb54b054, + successForeground2: rgb9fd89f, + successForeground3: rgb9fd89f, + successForegroundInverted: rgb107c10, + successBorderActive: rgb54b054, + successBorder2: rgb9fd89f, + warningBackground1: '#4c4400', + warningBackground2: rgb817400, + warningForeground1: rgbfeee66, + warningForeground2: rgbfef7b2, + warningForeground3: rgbfdea3d, + warningForegroundInverted: rgb817400, + warningBorderActive: rgbfeee66, + warningBorder2: rgbfdea3d, + severeBackground1: '#411200', + severeBackground2: rgb7a2101, + severeForeground1: rgbe9835e, + severeForeground2: rgbf4bfab, + severeForeground3: rgbe9835e, + severeBorderActive: rgbe9835e, + severeBorder2: rgbe9835e, + outofofficeBackground1: '#3a1136', + outofofficeBackground2: rgb6d2064, + outofofficeForeground1: rgbda7ed0, + outofofficeForeground2: rgbedbbe7, + outofofficeForeground3: rgbd161c4, + outofofficeBorderActive: rgbda7ed0, + outofofficeBorder1: rgbc239b3, + outofofficeBorder2: rgbd161c4, + brandForeground1Pressed: rgb6794d7, + brandForeground1Selected: rgb6794d7, + brandStroke1Pressed: rgb2e6ac5, + brandStroke1Selected: rgb2e6ac5, +}; + +export const hcDarkAliasColors: Required<AliasColorTokens> = { + ...darkHcDarkDarkElevatedHcLightAliasColors, + neutralForeground4: platformColorWindowText, + neutralForegroundDisabled: platformColorGrayText, + neutralForegroundDisabled1: platformColorGrayText, + neutralForegroundDisabled2: platformColorGrayText, + neutralForegroundOnBrand: platformColorButtonText, + neutralForegroundOnColor: platformColorButtonText, + neutralForegroundInverted: platformColorWindow, + neutralForegroundInvertedLink: platformColorHotlight, + brandForegroundLink: platformColorHotlight, + compoundBrandForeground1: platformColorHighlight, + brandForeground2: platformColorButtonText, + brandForegroundTint: platformColorButtonText, + brandForeground1Disabled: platformColorGrayText, + brandForegroundDisabled1: platformColorGrayText, + brandForegroundDisabled2: platformColorGrayText, + neutralBackgroundCanvas: platformColorWindow, + neutralBackgroundLightStaticDisabled: platformColorWindow, + brandBackground2: platformColorButtonFace, + brandBackground3: platformColorButtonFace, + brandBackgroundTint: platformColorButtonFace, + brandBackgroundInverted: platformColorWindowText, + brandBackgroundInvertedDisabled: platformColorWindow, + brandBackgroundDisabled: platformColorWindow, + compoundBrandBackground1: platformColorHighlight, + brandBackgroundStatic: platformColorWindow, + neutralStroke3: platformColorWindowText, + neutralStrokeFocus1: platformColorWindow, + neutralStrokeFocus2: platformColorHighlight, + strokeFocus1: platformColorWindow, + strokeFocus2: platformColorHighlight, + brandStroke2: platformColorWindow, + brandStrokeTint: platformColorWindow, + compoundBrandStroke1: platformColorHighlight, + dangerStroke1: platformColorWindowText, + successStroke1: platformColorWindowText, + warningStroke1: platformColorWindowText, + severeStroke1: platformColorWindowText, + dangerBorder1: platformColorWindowText, + successBorder1: platformColorWindowText, + warningBorder1: platformColorWindowText, + severeBorder1: platformColorWindowText, + presenceAway: platformColorWindowText, + presenceDnd: platformColorWindowText, + presenceAvailable: platformColorWindowText, + presenceOof: platformColorWindowText, + redBackground1: platformColorWindow, + redBackground2: platformColorWindow, + redBackground3: platformColorWindowText, + redForeground1: platformColorWindowText, + redForeground2: platformColorWindowText, + redForeground3: platformColorWindowText, + redBorderActive: platformColorHighlight, + redBorder1: platformColorWindowText, + redBorder2: platformColorWindowText, + neutralForeground1: platformColorWindowText, + neutralForeground1Hover: platformColorHighlightText, + neutralForeground1Pressed: platformColorHighlightText, + neutralForeground1Selected: platformColorHighlightText, + neutralForeground2: platformColorWindowText, + neutralForeground2Hover: platformColorHighlightText, + neutralForeground2Pressed: platformColorHighlightText, + neutralForeground2Selected: platformColorHighlightText, + neutralForeground2BrandHover: platformColorHighlightText, + neutralForeground2BrandPressed: platformColorHighlightText, + neutralForeground2BrandSelected: platformColorHighlightText, + neutralForeground3: platformColorWindowText, + neutralForeground3Hover: platformColorHighlightText, + neutralForeground3Pressed: platformColorHighlightText, + neutralForeground3Selected: platformColorHighlightText, + neutralForeground3BrandHover: platformColorHighlightText, + neutralForeground3BrandPressed: platformColorHighlightText, + neutralForeground3BrandSelected: platformColorHighlightText, + brandForegroundLinkHover: platformColorHotlight, + brandForegroundLinkPressed: platformColorHotlight, + brandForegroundLinkSelected: platformColorHotlight, + compoundBrandForeground1Hover: platformColorHighlight, + compoundBrandForeground1Pressed: platformColorHighlight, + brandForeground1: platformColorWindowText, + neutralForegroundOnBrandHover: platformColorHighlightText, + neutralForegroundOnBrandPressed: platformColorHighlightText, + neutralForegroundOnBrandSelected: platformColorHighlightText, + neutralForegroundInvertedLinkHover: platformColorHotlight, + neutralForegroundInvertedLinkPressed: platformColorHotlight, + neutralForegroundInvertedLinkSelected: platformColorHotlight, + neutralBackground1: platformColorWindow, + neutralBackground1Hover: platformColorHighlight, + neutralBackground1Pressed: platformColorHighlight, + neutralBackground1Selected: platformColorHighlight, + neutralBackground2: platformColorWindow, + neutralBackground2Hover: platformColorHighlight, + neutralBackground2Pressed: platformColorHighlight, + neutralBackground2Selected: platformColorHighlight, + neutralBackground3: platformColorWindow, + neutralBackground3Hover: platformColorHighlight, + neutralBackground3Pressed: platformColorHighlight, + neutralBackground3Selected: platformColorHighlight, + neutralBackground4: platformColorWindow, + neutralBackground4Hover: platformColorHighlight, + neutralBackground4Pressed: platformColorHighlight, + neutralBackground4Selected: platformColorHighlight, + neutralBackground5: platformColorWindow, + neutralBackground5Hover: platformColorHighlight, + neutralBackground5Pressed: platformColorHighlight, + neutralBackground5Selected: platformColorHighlight, + neutralBackground6: platformColorWindow, + neutralBackgroundInverted: platformColorWindowText, + subtleBackgroundHover: platformColorHighlight, + subtleBackgroundPressed: platformColorHighlight, + subtleBackgroundSelected: platformColorHighlight, + neutralBackgroundDisabled: platformColorWindow, + neutralStencil1: rgb141414, + neutralStencil2: '#858585', + brandBackground: platformColorButtonFace, + brandBackgroundHover: platformColorHighlight, + brandBackgroundPressed: platformColorHighlight, + brandBackgroundSelected: platformColorHighlight, + compoundBrandBackground1Hover: platformColorHighlight, + compoundBrandBackground1Pressed: platformColorHighlight, + neutralStrokeAccessible: platformColorWindowText, + neutralStrokeAccessibleHover: platformColorHighlight, + neutralStrokeAccessiblePressed: platformColorHighlight, + neutralStrokeAccessibleSelected: platformColorHighlight, + neutralStroke1: platformColorWindowText, + neutralStroke1Hover: platformColorHighlight, + neutralStroke1Pressed: platformColorHighlight, + neutralStroke1Selected: platformColorHighlight, + neutralStroke2: platformColorWindowText, + brandStroke1: platformColorWindowText, + compoundBrandStroke1Hover: platformColorHighlight, + compoundBrandStroke1Pressed: platformColorHighlight, + neutralStrokeDisabled: platformColorGrayText, + transparentStroke: platformColorWindowText, + transparentStrokeInteractive: platformColorHighlight, + transparentStrokeDisabled: platformColorGrayText, + dangerBackground1: platformColorWindow, + dangerBackground2: platformColorWindow, + dangerBackground3: platformColorWindowText, + dangerForeground1: platformColorWindowText, + dangerForeground2: platformColorWindowText, + dangerForeground3: platformColorWindowText, + dangerForegroundInverted: platformColorWindowText, + dangerBorderActive: platformColorHighlight, + dangerBorder2: platformColorWindowText, + successBackground1: platformColorWindow, + successBackground2: platformColorWindow, + successBackground3: platformColorWindowText, + successForeground1: platformColorWindowText, + successForeground2: platformColorWindowText, + successForeground3: platformColorWindowText, + successForegroundInverted: platformColorWindowText, + successBorderActive: platformColorHighlight, + successBorder2: platformColorWindowText, + warningBackground1: platformColorWindow, + warningBackground2: platformColorWindow, + warningBackground3: platformColorWindowText, + warningForeground1: platformColorWindowText, + warningForeground2: platformColorWindowText, + warningForeground3: platformColorWindowText, + warningForegroundInverted: platformColorWindowText, + warningBorderActive: platformColorHighlight, + warningBorder2: platformColorWindowText, + severeBackground1: platformColorWindow, + severeBackground2: platformColorWindow, + severeBackground3: platformColorWindowText, + severeForeground1: platformColorWindowText, + severeForeground2: platformColorWindowText, + severeForeground3: platformColorWindowText, + severeBorderActive: platformColorHighlight, + severeBorder2: platformColorWindowText, + outofofficeBackground1: platformColorWindow, + outofofficeBackground2: platformColorWindow, + outofofficeBackground3: platformColorWindowText, + outofofficeForeground1: platformColorWindowText, + outofofficeForeground2: platformColorWindowText, + outofofficeForeground3: platformColorWindowText, + outofofficeBorderActive: platformColorHighlight, + outofofficeBorder1: platformColorWindowText, + outofofficeBorder2: platformColorWindowText, + brandForeground1Pressed: platformColorWindowText, + brandBackground2Pressed: platformColorHighlight, + brandBackground2Selected: platformColorHighlight, + brandForeground1Selected: platformColorWindowText, + brandStroke1Pressed: platformColorWindowText, + brandStroke1Selected: platformColorWindowText, +}; + +export const lightElevatedAliasColors: Required<AliasColorTokens> = lightAliasColors; +export const darkElevatedAliasColors: Required<AliasColorTokens> = darkAliasColors; +export const hcLightAliasColors: Required<AliasColorTokens> = hcDarkAliasColors; + +/** Font aliases from the light appearance, completed with native equivalents and the platform global ramp. */ +export const fontAliasTokens: Required<Variants> = { + caption1, + body1, + body1Strong, + body2, + body2Strong, + subtitle1, + subtitle1Strong, + subtitle2, + subtitle2Strong, + title1, + title1Strong, + largeTitle, + display, + caption1Strong: { face: primary, size: 10, weight: fontWeight600 }, + caption2: caption1, + title2: subtitle1, + title3: subtitle2, + captionStandard: caption1, + secondaryStandard: body1, + secondarySemibold: body1Strong, + bodyStandard: body2, + bodySemibold: body2Strong, + subheaderStandard: subtitle2, + subheaderSemibold: subtitle2Strong, + headerStandard: subtitle1, + headerSemibold: subtitle1Strong, + heroStandard: title1, + heroSemibold: title1Strong, + heroLargeStandard: largeTitle, + heroLargeSemibold: display, +}; diff --git a/packages/agentic/design/src/fluent/defaults/fluentTokens.test.ts b/packages/agentic/design/src/fluent/defaults/fluentTokens.test.ts new file mode 100644 index 00000000000..bcabc13d5a3 --- /dev/null +++ b/packages/agentic/design/src/fluent/defaults/fluentTokens.test.ts @@ -0,0 +1,205 @@ +import { readFileSync } from 'node:fs'; +import path from 'node:path'; + +import { parse } from '@babel/parser'; +import blackAliasTokens from '@fluentui-react-native/design-tokens-win32/black/tokens-aliases.json'; +import blackShadowTokens from '@fluentui-react-native/design-tokens-win32/black/tokens-shadow.json'; +import colorfulAliasTokens from '@fluentui-react-native/design-tokens-win32/colorful/tokens-aliases.json'; +import colorfulShadowTokens from '@fluentui-react-native/design-tokens-win32/colorful/tokens-shadow.json'; +import darkGrayAliasTokens from '@fluentui-react-native/design-tokens-win32/darkgray/tokens-aliases.json'; +import darkGrayShadowTokens from '@fluentui-react-native/design-tokens-win32/darkgray/tokens-shadow.json'; +import hcAliasTokens from '@fluentui-react-native/design-tokens-win32/hc/tokens-aliases.json'; +import hcShadowTokens from '@fluentui-react-native/design-tokens-win32/hc/tokens-shadow.json'; +import { PlatformColor } from 'react-native'; + +import { mapPipelineToShadow } from '../../deprecated/mapPipelineToShadow'; +import { mapFontPipelineToTheme, mapPipelineToTheme } from '../../deprecated/mapPipelineToTheme'; +import * as androidMapper from '../../deprecated/mapPipelineToTheme.android'; +import * as iosMapper from '../../deprecated/mapPipelineToTheme.ios'; +import { + processAliasTokens, + transformWin32PlatformColorName, + transformWindowsPlatformColorName, +} from '../../deprecated/tokens/highContrast/processAliasTokens'; +import * as android from './fluentTokens.generated.android'; +import * as ios from './fluentTokens.generated.ios'; +import * as macos from './fluentTokens.generated.macos'; +import * as windows from './fluentTokens.generated.windows'; + +// An explicit extension bypasses Jest's platform resolution for the Win32 fallback module. +const generated = jest.requireActual<typeof macos>('./fluentTokens.generated.ts'); + +function definedEntries(values: object) { + return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined)); +} + +// processAliasTokens converts the high-contrast PlatformColor strings in place, so it gets a copy. +const processedHcAliasTokens = processAliasTokens(JSON.parse(JSON.stringify(hcAliasTokens)), transformWin32PlatformColorName); + +const appearances = [ + ['light', generated.lightAliasColors, generated.lightShadows, colorfulAliasTokens, colorfulShadowTokens], + ['dark', generated.darkAliasColors, generated.darkShadows, blackAliasTokens, blackShadowTokens], + ['darkElevated', generated.darkElevatedAliasColors, generated.darkElevatedShadows, darkGrayAliasTokens, darkGrayShadowTokens], + ['hcDark', generated.hcDarkAliasColors, generated.hcDarkShadows, processedHcAliasTokens, hcShadowTokens], +] as const; + +describe('generated win32 Fluent tokens', () => { + it.each(appearances)('match the runtime mapping for %s', (_, aliasColors, shadows, aliasTokens, shadowTokens) => { + expect(aliasColors).toMatchObject(definedEntries(mapPipelineToTheme(aliasTokens))); + expect(shadows).toEqual(mapPipelineToShadow(shadowTokens)); + }); + + it('match the runtime font mapping', () => { + expect(generated.fontAliasTokens).toMatchObject(mapFontPipelineToTheme(colorfulAliasTokens)); + }); + + it('emit high-contrast colors as distinct PlatformColor values', () => { + expect(generated.hcDarkAliasColors.neutralForeground1).toEqual(PlatformColor('WindowText')); + expect(PlatformColor('WindowText')).not.toEqual(PlatformColor('ButtonFace')); + }); +}); + +function interfaceKeys(filename: string, name: string): string[] { + const ast = parse(readFileSync(path.resolve(__dirname, '../types', filename), 'utf8'), { sourceType: 'module', plugins: ['typescript'] }); + for (const statement of ast.program.body) { + const declaration = statement.type === 'ExportNamedDeclaration' ? statement.declaration : undefined; + if (declaration?.type === 'TSInterfaceDeclaration' && declaration.id.name === name) { + return declaration.body.body + .map((property) => { + if (property.type !== 'TSPropertySignature' || property.key.type !== 'Identifier') { + throw new Error(`Unsupported property in ${name}`); + } + return property.key.name; + }) + .sort(); + } + } + throw new Error(`Missing interface ${name}`); +} + +function expectDefined(value: unknown): void { + expect(value).not.toBeUndefined(); + expect(value).not.toBeNull(); + if (value && typeof value === 'object') { + Object.values(value).forEach(expectDefined); + } +} + +const allAppearances = ['light', 'dark', 'lightElevated', 'darkElevated', 'hcLight', 'hcDark'] as const; +type Appearance = (typeof allAppearances)[number]; +const platforms = [ + { + platform: 'win32', + tokens: generated, + mapper: { mapPipelineToTheme, mapFontPipelineToTheme }, + sources: { light: 'win32/colorful', dark: 'win32/black', darkElevated: 'win32/darkgray', hcDark: 'win32/hc' }, + }, + { + platform: 'macos', + tokens: macos, + mapper: { mapPipelineToTheme, mapFontPipelineToTheme }, + sources: { light: 'macos/light', dark: 'macos/dark', hcLight: 'macos/hclight', hcDark: 'macos/hcdark' }, + }, + { + platform: 'windows', + tokens: windows, + mapper: { mapPipelineToTheme, mapFontPipelineToTheme }, + sources: { light: 'windows/light', dark: 'windows/dark', hcDark: 'win32/hc' }, + }, + { platform: 'android', tokens: android, mapper: androidMapper, sources: { light: 'android/light', dark: 'android/dark' } }, + { + platform: 'ios', + tokens: ios, + mapper: iosMapper, + sources: { light: 'ios/light', dark: 'ios/dark', hcLight: 'ios/hclight', hcDark: 'ios/hcdark', darkElevated: 'ios/elevateddark' }, + }, +] as const; + +describe.each(platforms)('complete $platform Fluent tokens', ({ platform, tokens, mapper, sources }) => { + it('covers the entire color and font contracts in every appearance with no undefined values', () => { + const colorKeys = interfaceKeys('Color.types.ts', 'AliasColorTokens'); + const fontKeys = interfaceKeys('Typography.types.ts', 'Variants'); + const shadowKeys = interfaceKeys('Shadow.types.ts', 'BaseShadowAliasTokens'); + expect(Object.keys(tokens).sort()).toEqual( + ['fontAliasTokens', ...allAppearances.flatMap((appearance) => [`${appearance}AliasColors`, `${appearance}Shadows`])].sort(), + ); + expect(Object.keys(tokens.fontAliasTokens).sort()).toEqual(fontKeys); + for (const appearance of allAppearances) { + expect(Object.keys(tokens[`${appearance}AliasColors`]).sort()).toEqual(colorKeys); + expect(Object.keys(tokens[`${appearance}Shadows`]).sort()).toEqual(shadowKeys); + } + expectDefined(tokens); + }); + + it('preserves every defined runtime-mapped native color, font alias, and shadow', () => { + const colorName = platform === 'windows' ? transformWindowsPlatformColorName : transformWin32PlatformColorName; + for (const [appearance, source] of Object.entries(sources)) { + const packagePath = `@fluentui-react-native/design-tokens-${source}/`; + const raw = require(`${packagePath}tokens-aliases.json`); + const aliases = processAliasTokens(JSON.parse(JSON.stringify(raw)), colorName); + const shadows = require(`${packagePath}tokens-shadow.json`); + const key = appearance as Appearance; + // iOS high-contrast files contain fonts only, with no native colors to preserve. + if (aliases.neutralBackground1) { + expect(tokens[`${key}AliasColors`]).toMatchObject(definedEntries(mapper.mapPipelineToTheme(aliases))); + } + if (aliases.caption1) { + expect(tokens.fontAliasTokens).toMatchObject(mapper.mapFontPipelineToTheme(aliases)); + } + expect(tokens[`${key}Shadows`]).toEqual(mapPipelineToShadow(shadows)); + } + }); +}); + +describe('Fluent token fallbacks', () => { + it.each([ios, android])('uses native rest colors and native fonts for missing mobile states and aliases', (tokens) => { + expect(tokens.darkAliasColors.brandBackground2).toBe(tokens.darkAliasColors.brandBackground); + expect(tokens.darkAliasColors.brandBackground2Pressed).toBe(tokens.darkAliasColors.brandBackgroundPressed); + expect(tokens.lightAliasColors.neutralBackground1Hover).toBe(tokens.lightAliasColors.neutralBackground1); + expect(tokens.lightAliasColors.neutralForegroundOnBrand).toBe(tokens.lightAliasColors.neutralForegroundOnColor); + expect(tokens.fontAliasTokens.subtitle1).toEqual(tokens.fontAliasTokens.title2); + expect(tokens.fontAliasTokens.subtitle2).toEqual(tokens.fontAliasTokens.title3); + expect(tokens.lightAliasColors.outofofficeBackground3).toBe(generated.lightAliasColors.outofofficeBackground3); + expect(tokens.darkAliasColors.outofofficeBackground3).toBe(generated.darkAliasColors.outofofficeBackground3); + }); + + it.each([ + ['win32', generated, { lightElevated: 'light', hcLight: 'hcDark' }], + ['macos', macos, { lightElevated: 'light', darkElevated: 'dark' }], + ['windows', windows, { lightElevated: 'light', darkElevated: 'dark', hcLight: 'hcDark' }], + ['android', android, { lightElevated: 'light', darkElevated: 'dark', hcLight: 'light', hcDark: 'dark' }], + ['ios', ios, { lightElevated: 'light' }], + ] as const)('%s returns the inherited appearance for each appearance without token data', (_, tokens, inherited) => { + for (const [appearance, source] of Object.entries(inherited) as [Appearance, Appearance][]) { + expect(tokens[`${appearance}AliasColors`]).toBe(tokens[`${source}AliasColors`]); + expect(tokens[`${appearance}Shadows`]).toBe(tokens[`${source}Shadows`]); + } + }); + + it('uses standard colors for color-free high-contrast sets and system colors only for Windows high contrast', () => { + expect(ios.hcLightAliasColors).toEqual(ios.lightAliasColors); + expect(ios.hcDarkAliasColors).toEqual(ios.darkAliasColors); + for (const { platform, tokens } of platforms) { + for (const appearance of allAppearances) { + const systemColors = (platform === 'win32' || platform === 'windows') && appearance.startsWith('hc'); + expect(Object.values(tokens[`${appearance}AliasColors`]).some((color) => typeof color !== 'string')).toBe(systemColors); + } + } + }); + + it.each([ + ['macos', macos], + ['windows', windows], + ] as const)('uses %s global fonts when the pipeline has no aliases', (platform, tokens) => { + const { font } = require(`@fluentui-react-native/design-tokens-${platform}/light/tokens-global.json`); + expect(tokens.fontAliasTokens.caption1).toEqual({ face: 'primary', size: font.size100, weight: font.weight.regular }); + expect(tokens.fontAliasTokens.body1Strong).toEqual({ face: 'primary', size: font.size200, weight: font.weight.semibold }); + }); + + it('keeps native states omitted by the legacy mapper and aliases deprecated colors', () => { + const source = require('@fluentui-react-native/design-tokens-macos/light/tokens-aliases.json'); + expect(macos.lightAliasColors.brandForeground1Selected).toBe(source.brandForeground1.selected); + expect(macos.lightAliasColors.brandStroke1Pressed).toBe(source.brandStroke1.pressed); + expect(ios.darkAliasColors.redForeground1).toBe(ios.darkAliasColors.dangerForeground1); + }); +}); diff --git a/packages/agentic/design/src/theming/legacySource.ts b/packages/agentic/design/src/fluent/legacySource.ts similarity index 65% rename from packages/agentic/design/src/theming/legacySource.ts rename to packages/agentic/design/src/fluent/legacySource.ts index 8389dd10878..baf196e0073 100644 --- a/packages/agentic/design/src/theming/legacySource.ts +++ b/packages/agentic/design/src/fluent/legacySource.ts @@ -1,3 +1,3 @@ export { ThemeReference } from './themeReference'; export type { OnThemeChange, ThemeRecipe, ThemeReferenceOptions, ThemeTransform } from './themeReference'; -export type { LegacyThemeSource, ThemeSourceBase } from './themeSource'; +export type { LegacyThemeSource, ThemeSourceBase } from '../theming/themeSource'; diff --git a/packages/agentic/design/src/theming/mergeTheme.ts b/packages/agentic/design/src/fluent/mergeTheme.ts similarity index 80% rename from packages/agentic/design/src/theming/mergeTheme.ts rename to packages/agentic/design/src/fluent/mergeTheme.ts index dc7d5e4bc92..b282cd49f64 100644 --- a/packages/agentic/design/src/theming/mergeTheme.ts +++ b/packages/agentic/design/src/fluent/mergeTheme.ts @@ -1,6 +1,6 @@ import { immutableMerge } from '@fluentui-react-native/framework-base'; -import type { Theme, PartialTheme } from './index'; +import type { PartialTheme, Theme } from './types/Theme.types'; export function mergeTheme<TTheme extends Theme, TPartial extends PartialTheme>(base: TTheme, partial: TPartial): TTheme { return immutableMerge(base, partial as unknown as TTheme); diff --git a/packages/agentic/design/src/theming/platformUtils.defaults.ts b/packages/agentic/design/src/fluent/platformUtils.defaults.ts similarity index 100% rename from packages/agentic/design/src/theming/platformUtils.defaults.ts rename to packages/agentic/design/src/fluent/platformUtils.defaults.ts diff --git a/packages/agentic/design/src/theming/platformUtils.macos.ts b/packages/agentic/design/src/fluent/platformUtils.macos.ts similarity index 79% rename from packages/agentic/design/src/theming/platformUtils.macos.ts rename to packages/agentic/design/src/fluent/platformUtils.macos.ts index b1ad5dbbe2f..69acda42e90 100644 --- a/packages/agentic/design/src/theming/platformUtils.macos.ts +++ b/packages/agentic/design/src/fluent/platformUtils.macos.ts @@ -1,5 +1,5 @@ import type { Theme } from './types/Theme.types'; -import { platformAppearance, setPlatformHighContrast } from './platformAppearance'; +import { platformAppearance, setPlatformHighContrast } from '../theming/platformAppearance'; export { getCurrentAppearance } from './platformUtils.defaults'; diff --git a/packages/agentic/design/src/theming/platformUtils.ts b/packages/agentic/design/src/fluent/platformUtils.ts similarity index 100% rename from packages/agentic/design/src/theming/platformUtils.ts rename to packages/agentic/design/src/fluent/platformUtils.ts diff --git a/packages/agentic/design/src/theming/platformUtils.win32.ts b/packages/agentic/design/src/fluent/platformUtils.win32.ts similarity index 100% rename from packages/agentic/design/src/theming/platformUtils.win32.ts rename to packages/agentic/design/src/fluent/platformUtils.win32.ts diff --git a/packages/agentic/design/src/theming/platformUtils.windows.ts b/packages/agentic/design/src/fluent/platformUtils.windows.ts similarity index 100% rename from packages/agentic/design/src/theming/platformUtils.windows.ts rename to packages/agentic/design/src/fluent/platformUtils.windows.ts diff --git a/packages/agentic/design/src/styling/stylesheet/index.ts b/packages/agentic/design/src/fluent/styling/stylesheet/index.ts similarity index 100% rename from packages/agentic/design/src/styling/stylesheet/index.ts rename to packages/agentic/design/src/fluent/styling/stylesheet/index.ts diff --git a/packages/agentic/design/src/styling/stylesheet/themedStyleSheet.test.ts b/packages/agentic/design/src/fluent/styling/stylesheet/themedStyleSheet.test.ts similarity index 100% rename from packages/agentic/design/src/styling/stylesheet/themedStyleSheet.test.ts rename to packages/agentic/design/src/fluent/styling/stylesheet/themedStyleSheet.test.ts diff --git a/packages/agentic/design/src/styling/stylesheet/themedStyleSheet.ts b/packages/agentic/design/src/fluent/styling/stylesheet/themedStyleSheet.ts similarity index 100% rename from packages/agentic/design/src/styling/stylesheet/themedStyleSheet.ts rename to packages/agentic/design/src/fluent/styling/stylesheet/themedStyleSheet.ts diff --git a/packages/agentic/design/src/styling/tokens/border-tokens.ts b/packages/agentic/design/src/fluent/styling/tokens/border-tokens.ts similarity index 93% rename from packages/agentic/design/src/styling/tokens/border-tokens.ts rename to packages/agentic/design/src/fluent/styling/tokens/border-tokens.ts index cd25b4084be..60837e3569b 100644 --- a/packages/agentic/design/src/styling/tokens/border-tokens.ts +++ b/packages/agentic/design/src/fluent/styling/tokens/border-tokens.ts @@ -1,6 +1,6 @@ import type { ViewStyle, ColorValue, AnimatableNumericValue } from 'react-native'; -import type { Theme } from '../../theming'; +import type { Theme } from '../../types/Theme.types'; import { getPaletteFromTheme } from './color-tokens'; import type { OperationSet } from './token.types'; diff --git a/packages/agentic/design/src/styling/tokens/color-tokens.ts b/packages/agentic/design/src/fluent/styling/tokens/color-tokens.ts similarity index 86% rename from packages/agentic/design/src/styling/tokens/color-tokens.ts rename to packages/agentic/design/src/fluent/styling/tokens/color-tokens.ts index 2905961adc0..011b3f2200f 100644 --- a/packages/agentic/design/src/styling/tokens/color-tokens.ts +++ b/packages/agentic/design/src/fluent/styling/tokens/color-tokens.ts @@ -1,6 +1,7 @@ import type { ColorValue } from 'react-native'; -import type { Theme, ThemeColorDefinition } from '../../theming'; +import type { ThemeColorDefinition } from '../../types/Color.types'; +import type { Theme } from '../../types/Theme.types'; import type { OperationSet } from './token.types'; diff --git a/packages/agentic/design/src/styling/tokens/index.ts b/packages/agentic/design/src/fluent/styling/tokens/index.ts similarity index 100% rename from packages/agentic/design/src/styling/tokens/index.ts rename to packages/agentic/design/src/fluent/styling/tokens/index.ts diff --git a/packages/agentic/design/src/styling/tokens/layout-tokens.ts b/packages/agentic/design/src/fluent/styling/tokens/layout-tokens.ts similarity index 95% rename from packages/agentic/design/src/styling/tokens/layout-tokens.ts rename to packages/agentic/design/src/fluent/styling/tokens/layout-tokens.ts index 675818d4750..9af4c388bcc 100644 --- a/packages/agentic/design/src/styling/tokens/layout-tokens.ts +++ b/packages/agentic/design/src/fluent/styling/tokens/layout-tokens.ts @@ -1,6 +1,6 @@ import type { ViewStyle } from 'react-native'; -import type { Theme } from '../../theming'; +import type { Theme } from '../../types/Theme.types'; import type { OperationSet } from './token.types'; import { tokenBuilder } from './tokenBuilder'; diff --git a/packages/agentic/design/src/styling/tokens/shadow-tokens.ts b/packages/agentic/design/src/fluent/styling/tokens/shadow-tokens.ts similarity index 93% rename from packages/agentic/design/src/styling/tokens/shadow-tokens.ts rename to packages/agentic/design/src/fluent/styling/tokens/shadow-tokens.ts index 3aa84aaefbe..3a0d78fd293 100644 --- a/packages/agentic/design/src/styling/tokens/shadow-tokens.ts +++ b/packages/agentic/design/src/fluent/styling/tokens/shadow-tokens.ts @@ -1,6 +1,6 @@ import type { AnimatableNumericValue, ColorValue, ViewStyle } from 'react-native'; -import type { Theme } from '../../theming'; +import type { Theme } from '../../types/Theme.types'; import type { OperationSet } from './token.types'; import { tokenBuilder } from './tokenBuilder'; diff --git a/packages/agentic/design/src/styling/tokens/text-tokens.ts b/packages/agentic/design/src/fluent/styling/tokens/text-tokens.ts similarity index 96% rename from packages/agentic/design/src/styling/tokens/text-tokens.ts rename to packages/agentic/design/src/fluent/styling/tokens/text-tokens.ts index 2715856f39d..7f59dba822b 100644 --- a/packages/agentic/design/src/styling/tokens/text-tokens.ts +++ b/packages/agentic/design/src/fluent/styling/tokens/text-tokens.ts @@ -1,7 +1,8 @@ import type { TextProps, TextStyle } from 'react-native'; import type { ITextProps, ITextStyle } from '@fluentui-react-native/adapters'; -import type { Theme, Typography } from '../../theming'; +import type { Theme } from '../../types/Theme.types'; +import type { Typography } from '../../types/Typography.types'; import { styleFunction } from './token.function'; import type { TokenBuilder } from './tokenBuilder'; diff --git a/packages/agentic/design/src/styling/tokens/token.function.ts b/packages/agentic/design/src/fluent/styling/tokens/token.function.ts similarity index 100% rename from packages/agentic/design/src/styling/tokens/token.function.ts rename to packages/agentic/design/src/fluent/styling/tokens/token.function.ts diff --git a/packages/agentic/design/src/styling/tokens/token.types.ts b/packages/agentic/design/src/fluent/styling/tokens/token.types.ts similarity index 100% rename from packages/agentic/design/src/styling/tokens/token.types.ts rename to packages/agentic/design/src/fluent/styling/tokens/token.types.ts diff --git a/packages/agentic/design/src/styling/tokens/tokenBuilder.ts b/packages/agentic/design/src/fluent/styling/tokens/tokenBuilder.ts similarity index 92% rename from packages/agentic/design/src/styling/tokens/tokenBuilder.ts rename to packages/agentic/design/src/fluent/styling/tokens/tokenBuilder.ts index 6f0f304255c..5b907b22dcd 100644 --- a/packages/agentic/design/src/styling/tokens/tokenBuilder.ts +++ b/packages/agentic/design/src/fluent/styling/tokens/tokenBuilder.ts @@ -1,6 +1,6 @@ import type { ViewStyle, TextStyle, ImageStyle } from 'react-native'; -import type { Theme } from '../../theming'; +import type { Theme } from '../../types/Theme.types'; export type TokenBuilder<TTokens, TStyle extends ViewStyle | TextStyle | ImageStyle> = { from: (tokens: TTokens, theme: Theme) => TStyle; diff --git a/packages/agentic/design/src/theming/themeReference.ts b/packages/agentic/design/src/fluent/themeReference.ts similarity index 92% rename from packages/agentic/design/src/theming/themeReference.ts rename to packages/agentic/design/src/fluent/themeReference.ts index 380b601b751..0a06578a57b 100644 --- a/packages/agentic/design/src/theming/themeReference.ts +++ b/packages/agentic/design/src/fluent/themeReference.ts @@ -1,12 +1,17 @@ -import type { Theme, PartialTheme } from './index'; +import type { PartialTheme, Theme } from './types/Theme.types'; -import { appearanceOptionsFromLegacy, resolveThemeAppearance, themeAppearanceKey } from './appearance'; -import type { ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceSource } from './appearance.types'; +import { + appearanceOptionsFromLegacy, + internResolvedThemeAppearance, + resolveThemeAppearance, + themeAppearanceKey, +} from '../theming/appearance'; +import type { ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceSource } from '../types/appearance.types'; import { mergeTheme } from './mergeTheme'; -import { platformAppearance } from './platformAppearance'; -import type { LegacyThemeSource, OnThemeChange } from './themeSource'; +import { platformAppearance } from '../theming/platformAppearance'; +import type { LegacyThemeSource, OnThemeChange } from '../theming/themeSource'; -export type { OnThemeChange } from './themeSource'; +export type { OnThemeChange } from '../theming/themeSource'; /** * A function that takes in a parent theme, then returns a partial set of changes to be merged with the parent theme to update @@ -143,10 +148,12 @@ export class ThemeReference<TTheme extends Theme = Theme, TPartial extends Parti /** * Resolve the legacy Theme for one concrete appearance. Repeated resolutions - * share identity until this reference is invalidated. + * share identity until this reference is invalidated. A missing tone means + * cool; transforms always receive a concrete tone. */ - public resolveTheme(appearance: ResolvedThemeAppearance): TTheme { + public resolveTheme(requestedAppearance: ResolvedThemeAppearance): TTheme { this.syncParentRevision(); + const appearance = internResolvedThemeAppearance(requestedAppearance); const key = themeAppearanceKey(appearance); const cached = this.themesByAppearance.get(key); if (cached) { diff --git a/packages/agentic/design/src/theming/types/Color.types.ts b/packages/agentic/design/src/fluent/types/Color.types.ts similarity index 100% rename from packages/agentic/design/src/theming/types/Color.types.ts rename to packages/agentic/design/src/fluent/types/Color.types.ts diff --git a/packages/agentic/design/src/theming/types/Shadow.types.ts b/packages/agentic/design/src/fluent/types/Shadow.types.ts similarity index 100% rename from packages/agentic/design/src/theming/types/Shadow.types.ts rename to packages/agentic/design/src/fluent/types/Shadow.types.ts diff --git a/packages/agentic/design/src/theming/types/Theme.types.ts b/packages/agentic/design/src/fluent/types/Theme.types.ts similarity index 100% rename from packages/agentic/design/src/theming/types/Theme.types.ts rename to packages/agentic/design/src/fluent/types/Theme.types.ts diff --git a/packages/agentic/design/src/theming/types/Typography.types.ts b/packages/agentic/design/src/fluent/types/Typography.types.ts similarity index 100% rename from packages/agentic/design/src/theming/types/Typography.types.ts rename to packages/agentic/design/src/fluent/types/Typography.types.ts diff --git a/packages/agentic/design/src/theming/types/palette.types.ts b/packages/agentic/design/src/fluent/types/palette.types.ts similarity index 100% rename from packages/agentic/design/src/theming/types/palette.types.ts rename to packages/agentic/design/src/fluent/types/palette.types.ts diff --git a/packages/agentic/design/src/theming/useTheme.test.ts b/packages/agentic/design/src/fluent/useTheme.test.ts similarity index 87% rename from packages/agentic/design/src/theming/useTheme.test.ts rename to packages/agentic/design/src/fluent/useTheme.test.ts index 7d32b7e0f88..4ec5ab15fc0 100644 --- a/packages/agentic/design/src/theming/useTheme.test.ts +++ b/packages/agentic/design/src/fluent/useTheme.test.ts @@ -3,13 +3,13 @@ import * as React from 'react'; import { act, create } from 'react-test-renderer'; import type { ReactTestRenderer } from 'react-test-renderer'; -import { mockTheme } from '../testing/mockTheme'; -import { useThemeState } from '../useThemeState'; -import type { ThemeState } from '../useThemeState'; -import type { ThemeAppearanceSource } from './appearance.types'; -import { ThemeContext } from './context'; -import { FlexThemeReference } from './flexThemeReference'; -import { ThemeProvider } from './ThemeProvider'; +import { mockTheme } from '../test/fixtures/mockTheme'; +import { useThemeState } from '../flex/useThemeState'; +import type { ThemeState } from '../flex/themeState.types'; +import type { ThemeAppearanceSource } from '../types/appearance.types'; +import { ThemeContext } from '../theming/context'; +import { FlexThemeReference } from '../flex/flexThemeReference'; +import { ThemeProvider } from '../theming/ThemeProvider'; import type { Theme } from './types/Theme.types'; import { useTheme } from './useTheme'; @@ -112,7 +112,7 @@ describe('useTheme', () => { }); expect(themes[0]).toBe(rawTheme); - expect(states[0].tokens.color.backgroundNeutralSubtle).toBe('#654321'); + expect(states[0].tokens.color.backgroundNeutralSubtle.rest).toBe('#654321'); act(() => component!.unmount()); }); }); diff --git a/packages/agentic/design/src/theming/useTheme.ts b/packages/agentic/design/src/fluent/useTheme.ts similarity index 75% rename from packages/agentic/design/src/theming/useTheme.ts rename to packages/agentic/design/src/fluent/useTheme.ts index 4d5393dd48b..31141524314 100644 --- a/packages/agentic/design/src/theming/useTheme.ts +++ b/packages/agentic/design/src/fluent/useTheme.ts @@ -1,10 +1,10 @@ import type { PartialTheme, Theme } from './types/Theme.types'; import { themeFromFlexTokens } from './compat'; -import { themeAppearanceKey } from './appearance'; -import type { ResolvedThemeAppearance } from './appearance.types'; -import { useThemeBoundary } from './context'; -import { getFlexTokens } from './themeRuntime'; -import type { FlexThemeSource } from './themeSource'; +import { themeAppearanceKey } from '../theming/appearance'; +import type { ResolvedThemeAppearance } from '../types/appearance.types'; +import { useThemeBoundary } from '../theming/context'; +import { getFlexSourceTokens } from '../theming/themeRuntime'; +import type { FlexThemeSource } from '../theming/themeSource'; type LegacyCache = { revision: number; @@ -24,7 +24,7 @@ function getLegacyTheme(source: FlexThemeSource, appearance: ResolvedThemeAppear let theme = cache.byAppearance.get(key); if (!theme) { const fallback: Theme | PartialTheme | undefined = source.resolveLegacyFallback?.(appearance); - theme = themeFromFlexTokens(getFlexTokens(source, appearance), appearance, { fallback }); + theme = themeFromFlexTokens(getFlexSourceTokens(source, appearance), appearance, { fallback }); cache.byAppearance.set(key, theme); } return theme; diff --git a/packages/agentic/design/src/index.ts b/packages/agentic/design/src/index.ts index a3fa3c501c5..8b89a6c5ca3 100644 --- a/packages/agentic/design/src/index.ts +++ b/packages/agentic/design/src/index.ts @@ -1,22 +1,43 @@ -export type { FontSize, FontWeight } from './concepts/textAttributes'; -export { fontSize, fontWeight } from './concepts/textAttributes'; +export type { FontSize, FontWeight } from './tokens/textAttributes'; +export { fontSize, fontWeight } from './tokens/textAttributes'; export type { + ColorEntry, + ColorTuple, + FlexColorDescription, + FlexColorInput, + FlexEasing, + FlexShadow, + FlexShadowEntry, + FlexShadowLayer, + FlexTokenDescription, FlexTokens, - InteractiveColorOverrides, + InteractiveColor, + InteractiveColorOptions, + InteractiveColorType, + PartialSemanticColors, SemanticBorderRadii, + SemanticColorDescriptions, + SemanticColorName, SemanticColors, SemanticColorTokenValues, SemanticFontFamilies, SemanticFontSizes, SemanticFontWeights, SemanticLineHeights, + SemanticMotion, + SemanticShadowEntries, SemanticShadows, SemanticSpacing, SemanticStrokeWidths, SemanticTokens, UnsupportedFlexTokens, -} from './tokens/flex.types'; -export { flexTokensFromTheme } from './tokens/flexTokensFromTheme'; +} from './flex/tokens.types'; +export { INTERACTIVE_COLOR_TOKENS, isInteractiveColorToken, isInverseInteractionToken } from './flex/colors/interactiveTokens'; +export { flexColor, selectColorEntry } from './flex/colors/flexColor'; +export type { ColorSchemeSelector } from './flex/colors/flexColor'; +export { selectShadowEntry } from './flex/flexShadow'; +export type { InteractiveColorToken } from './flex/colors/interactiveTokens'; +export { flexTokensFromTheme } from './flex/adapters/flexTokensFromTheme'; export { createThemeAppearanceSource, FlexThemeReference, @@ -30,6 +51,8 @@ export { useRootInputModality, } from './theming/modern'; export type { + ColorTone, + FlexThemeDescription, FlexThemeInput, FlexThemeRecipe, FlexThemeReferenceOptions, @@ -37,6 +60,7 @@ export type { InputModality, LegacyThemeFallback, LegacyThemeSource, + NormalizedThemeAppearance, PartialFlexTokens, ResolvedThemeAppearance, RootSettings, @@ -54,5 +78,6 @@ export type { ThemeSource, ThemeSourceBase, } from './theming/modern'; -export type { ThemeState, ThemeStyleSheet } from './useThemeState'; -export { themedStyleSheetFactory, useThemeAppearance, useThemeState } from './useThemeState'; +export type { ThemeStyleSheet } from './flex/useThemeState'; +export type { ThemeState } from './flex/themeState.types'; +export { themedStyleSheetFactory, useThemeAppearance, useThemeState } from './flex/useThemeState'; diff --git a/packages/agentic/design/src/styling/branchedStyle.test.ts b/packages/agentic/design/src/styling/branchedStyle.test.ts index ab03abd8667..4804477e459 100644 --- a/packages/agentic/design/src/styling/branchedStyle.test.ts +++ b/packages/agentic/design/src/styling/branchedStyle.test.ts @@ -1,8 +1,8 @@ import type { ViewStyle } from 'react-native'; import { defaultResolvedThemeAppearance } from '../theming/appearance'; -import { defaultFlexTokens } from '../tokens/defaultTokens'; -import type { ThemeState } from '../useThemeState'; +import { defaultFlexTokens } from '../flex/defaults/defaultTokens'; +import type { ThemeState } from '../flex/themeState.types'; import { getActiveState, diff --git a/packages/agentic/design/src/styling/branchedStyle.ts b/packages/agentic/design/src/styling/branchedStyle.ts index 8c7abc28a39..f624080b9d8 100644 --- a/packages/agentic/design/src/styling/branchedStyle.ts +++ b/packages/agentic/design/src/styling/branchedStyle.ts @@ -1,7 +1,7 @@ import type { ImageStyle, TextStyle, ViewStyle } from 'react-native'; -import type { FlexTokens } from '../tokens/flex.types'; -import type { ThemeState } from '../useThemeState'; +import type { FlexTokens } from '../flex/tokens.types'; +import type { ThemeState } from '../flex/themeState.types'; type AnyStyle = ViewStyle | ImageStyle | TextStyle; diff --git a/packages/agentic/design/src/styling/index.ts b/packages/agentic/design/src/styling/index.ts index 60f05389508..6936f0651d3 100644 --- a/packages/agentic/design/src/styling/index.ts +++ b/packages/agentic/design/src/styling/index.ts @@ -8,7 +8,7 @@ export { styleDefinitionToBranchedStyles, } from './branchedStyle'; export { getGapStyleValue } from './gapStyleValue'; -export type { ColorKey, ColorStyleDefinition, TextColorStyle, ViewColorStyle } from './colorStyles'; -export { colorStyleDef, getThemedColorStyleFactory } from './colorStyles'; +export type { ColorKey, ColorStyleDefinition, TextColorStyle, ViewColorStyle } from '../flex/styling/colorStyles'; +export { colorStyleDef, getThemedColorStyleFactory } from '../flex/styling/colorStyles'; export { interactiveStatePriority } from './interactiveStatePriority'; export { getNumericStyleValue } from './numericStyleValue'; diff --git a/packages/agentic/design/src/testing/README.md b/packages/agentic/design/src/test/README.md similarity index 100% rename from packages/agentic/design/src/testing/README.md rename to packages/agentic/design/src/test/README.md diff --git a/packages/agentic/design/src/testing/color-validation/constants.ts b/packages/agentic/design/src/test/color-validation/constants.ts similarity index 100% rename from packages/agentic/design/src/testing/color-validation/constants.ts rename to packages/agentic/design/src/test/color-validation/constants.ts diff --git a/packages/agentic/design/src/testing/color-validation/pairings.ts b/packages/agentic/design/src/test/color-validation/pairings.ts similarity index 98% rename from packages/agentic/design/src/testing/color-validation/pairings.ts rename to packages/agentic/design/src/test/color-validation/pairings.ts index 053d26f32df..23b7b538333 100644 --- a/packages/agentic/design/src/testing/color-validation/pairings.ts +++ b/packages/agentic/design/src/test/color-validation/pairings.ts @@ -16,7 +16,7 @@ function token(tokenName: ContrastColorToken): ContrastTokenReference { * Test-only canonical x3 contrast pairings adapted to FURN token names, plus the * issue-required FURN visible-stroke pairing. * - * Source: x3-design/fluent-design@d334acf5cbad813f2b7cd554da942b09a7ff8f10. + * Source: x3-design/fluent-design@206e890b645fb450ad7c5df2ff981765349a2b58. */ export const PAIRINGS = [ { diff --git a/packages/agentic/design/src/testing/color-validation/types.ts b/packages/agentic/design/src/test/color-validation/types.ts similarity index 96% rename from packages/agentic/design/src/testing/color-validation/types.ts rename to packages/agentic/design/src/test/color-validation/types.ts index 794f082ede2..45d250dcfc1 100644 --- a/packages/agentic/design/src/testing/color-validation/types.ts +++ b/packages/agentic/design/src/test/color-validation/types.ts @@ -1,7 +1,7 @@ import type { ColorValue } from 'react-native'; import type { ColorDiagnostic, ColorMode } from '../../color-lib'; -import type { SemanticColorTokenValues } from '../../tokens/flex.types'; +import type { SemanticColorTokenValues } from '../../flex/tokens.types'; export type ContrastColorToken = keyof SemanticColorTokenValues; diff --git a/packages/agentic/design/src/testing/color-validation/validation.test.ts b/packages/agentic/design/src/test/color-validation/validation.test.ts similarity index 72% rename from packages/agentic/design/src/testing/color-validation/validation.test.ts rename to packages/agentic/design/src/test/color-validation/validation.test.ts index fe9bca69f7e..666bc4f92ad 100644 --- a/packages/agentic/design/src/testing/color-validation/validation.test.ts +++ b/packages/agentic/design/src/test/color-validation/validation.test.ts @@ -1,34 +1,26 @@ import { PlatformColor } from 'react-native'; -import { getInteractionColorOverrides, INTERACTIVE_COLOR_TOKENS } from '../../color-lib/interaction'; -import type { ColorMode, InteractionColorState, InteractionColorVariant } from '../../color-lib/types'; -import { defaultFlexTokens } from '../../tokens/defaultTokens'; -import type { SemanticColorTokenValues } from '../../tokens/flex.types'; +import type { ColorMode, InteractionColorState } from '../../color-lib/types'; +import { resolveFlexTokenDescription } from '../../flex/colors/interactionPolicy'; +import { defaultFlexTokens, getDefaultFlexTokenDescription } from '../../flex/defaults/defaultTokens'; +import type { SemanticColorTokenValues } from '../../flex/tokens.types'; +import type { ColorTone } from '../../types/appearance.types'; import { getContrastFailures, getUnresolvableContrastPairs, MODE_SURFACE, PAIRINGS, validateContrastPairs, WCAG } from '../index'; -import { x3BebopWarmInteractionConformance, x3InteractionConformance } from './x3InteractionConformance'; +import { restColorValues, stateColorValues } from '../fixtures/interactionColors'; -function conformanceColors( +// The shipping defaults for one appearance; x3Defaults.test.ts proves they match the pinned design source. +function defaultColors( mode: ColorMode, - conformance: typeof x3InteractionConformance | typeof x3BebopWarmInteractionConformance = x3InteractionConformance, + colorTone: ColorTone = 'cool', + state: 'rest' | InteractionColorState = 'rest', ): SemanticColorTokenValues { - const restIndex = mode === 'light' ? 0 : 3; - const { hover: _hover, pressed: _pressed, ...colors } = defaultFlexTokens.color; - for (const token of INTERACTIVE_COLOR_TOKENS) { - colors[token] = conformance[token][restIndex]; - } - return colors; -} - -function interactionConformanceColors( - mode: ColorMode, - state: InteractionColorState, - variant: InteractionColorVariant, -): SemanticColorTokenValues { - const colors = conformanceColors(mode, variant === 'bebopWarm' ? x3BebopWarmInteractionConformance : x3InteractionConformance); - return { - ...colors, - ...getInteractionColorOverrides(colors, mode, state, { variant }).overrides, - }; + const tokens = resolveFlexTokenDescription(getDefaultFlexTokenDescription(colorTone), { + colorScheme: mode, + contrast: 'standard', + interfaceLevel: 'base', + colorTone, + }); + return stateColorValues(tokens.color, state); } const expectedPairs = [ @@ -87,21 +79,22 @@ describe('color validation constants', () => { }); describe.each(['light', 'dark'] as const)('%s contrast validation', (mode) => { - it('passes every canonical rest pairing', () => { - const results = validateContrastPairs(conformanceColors(mode), mode); + it.each(['cool', 'warm'] as const)('passes every canonical %s rest pairing', (colorTone) => { + const results = validateContrastPairs(defaultColors(mode, colorTone), mode); expect(results.map((result) => `${result.foreground.token}/${result.background.token}`)).toEqual(expectedPairs); expect(getContrastFailures(results)).toEqual([]); expect(getUnresolvableContrastPairs(results)).toEqual([]); }); - it.each(['default', 'bebopWarm'] as const)('audits %s interaction values', (variant) => { + // Audit outcomes for the shipping defaults, kept visible rather than corrected away from the design source. + it.each(['cool', 'warm'] as const)('audits %s interaction values', (colorTone) => { for (const state of ['hover', 'pressed'] as const) { - const failures = getContrastFailures(validateContrastPairs(interactionConformanceColors(mode, state, variant), mode)).map( + const failures = getContrastFailures(validateContrastPairs(defaultColors(mode, colorTone, state), mode)).map( (result) => `${result.foreground.token}/${result.background.token}`, ); const expectedFailures = - mode === 'dark' && variant === 'bebopWarm' && state === 'pressed' + mode === 'dark' && colorTone === 'warm' && state === 'pressed' ? [ 'foregroundDangerPrimary/surfaceNeutralNearer', 'foregroundDangerPrimary/backgroundDangerSubtle', @@ -117,9 +110,17 @@ describe.each(['light', 'dark'] as const)('%s contrast validation', (mode) => { }); }); +describe('resolved color validation', () => { + it('audits resolved Flex colors at rest', () => { + expect(validateContrastPairs(defaultFlexTokens.color, 'light')).toEqual( + validateContrastPairs(restColorValues(defaultFlexTokens.color), 'light'), + ); + }); +}); + describe('unresolvable color validation', () => { it('identifies native foreground colors', () => { - const colors = conformanceColors('light'); + const colors = defaultColors('light'); colors.foregroundNeutralPrimary = PlatformColor('labelColor'); const results = getUnresolvableContrastPairs(validateContrastPairs(colors, 'light')).filter( (result) => result.foreground.token === 'foregroundNeutralPrimary', @@ -136,7 +137,7 @@ describe('unresolvable color validation', () => { }); it('identifies native background colors', () => { - const colors = conformanceColors('dark'); + const colors = defaultColors('dark'); colors.backgroundSuccessSoft = PlatformColor('windowBackgroundColor'); const result = getUnresolvableContrastPairs(validateContrastPairs(colors, 'dark')).find( (pair) => pair.background.token === 'backgroundSuccessSoft', diff --git a/packages/agentic/design/src/testing/color-validation/validation.ts b/packages/agentic/design/src/test/color-validation/validation.ts similarity index 75% rename from packages/agentic/design/src/testing/color-validation/validation.ts rename to packages/agentic/design/src/test/color-validation/validation.ts index b33cd1df6ac..33924cfc4c7 100644 --- a/packages/agentic/design/src/testing/color-validation/validation.ts +++ b/packages/agentic/design/src/test/color-validation/validation.ts @@ -1,6 +1,8 @@ import { parseColorValue, resolveContrastColors } from '../../color-lib'; import type { ColorDiagnostic, ColorMode } from '../../color-lib'; -import type { SemanticColorTokenValues } from '../../tokens/flex.types'; +import type { ColorValue } from 'react-native'; + +import type { InteractiveColor, SemanticColors, SemanticColorTokenValues } from '../../flex/tokens.types'; import { MODE_SURFACE } from './constants'; import { PAIRINGS } from './pairings'; import type { @@ -24,23 +26,33 @@ function diagnosticFor( }; } +function isResolvedColor(value: ColorValue | InteractiveColor): value is InteractiveColor { + return typeof value === 'object' && value !== null && 'rest' in value; +} + +function colorValue(colors: SemanticColorTokenValues | SemanticColors, token: ContrastColorToken): ColorValue { + const value = colors[token]; + return isResolvedColor(value) ? value.rest : value; +} + /** * Audit semantic colors against canonical or caller-supplied contrast - * pairings. This helper is intended for tests and design validation tooling, - * not component render paths. + * pairings. Resolved Flex colors are audited at rest; pass a flat map of hover + * or pressed values to audit an interaction state. This helper is intended for + * tests and design validation tooling, not component render paths. */ export function validateContrastPairs( - colors: SemanticColorTokenValues, + colors: SemanticColorTokenValues | SemanticColors, mode: ColorMode, pairings: readonly ContrastPairing[] = PAIRINGS, ): ContrastPairResult[] { const results: ContrastPairResult[] = []; for (const pairing of pairings) { - const foregroundValue = colors[pairing.foreground.token]; + const foregroundValue = colorValue(colors, pairing.foreground.token); const foreground = parseColorValue(foregroundValue); for (const backgroundReference of pairing.backgrounds) { - const backgroundValue = colors[backgroundReference.token]; + const backgroundValue = colorValue(colors, backgroundReference.token); const background = parseColorValue(backgroundValue); const base = { pairing, diff --git a/packages/agentic/design/src/test/compatibility/__snapshots__/compatibilityBaseline.test.ts.snap b/packages/agentic/design/src/test/compatibility/__snapshots__/compatibilityBaseline.test.ts.snap new file mode 100644 index 00000000000..e4587d1d4e7 --- /dev/null +++ b/packages/agentic/design/src/test/compatibility/__snapshots__/compatibilityBaseline.test.ts.snap @@ -0,0 +1,193 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Flex default baseline keeps the dark legacy projection of the default Flex tokens 1`] = ` +{ + "colorCount": 318, + "colors": "00e96311260ec7a0", + "components": "75484377ab62c281", + "host": "e8e4ef993a27738e", + "shadows": "6cc8dc2e49311041", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; + +exports[`Flex default baseline keeps the darkElevated legacy projection of the default Flex tokens 1`] = ` +{ + "colorCount": 318, + "colors": "00e96311260ec7a0", + "components": "75484377ab62c281", + "host": "f94ca80c0bbf7966", + "shadows": "6cc8dc2e49311041", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; + +exports[`Flex default baseline keeps the highContrast legacy projection of the default Flex tokens 1`] = ` +{ + "colorCount": 318, + "colors": "95d8ba84933eb351", + "components": "75484377ab62c281", + "host": "9db06d0a5ce1e422", + "shadows": "6cc8dc2e49311041", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; + +exports[`Flex default baseline keeps the light legacy projection of the default Flex tokens 1`] = ` +{ + "colorCount": 318, + "colors": "17121c304beef7e4", + "components": "75484377ab62c281", + "host": "6be4fd450402dc4f", + "shadows": "6cc8dc2e49311041", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; + +exports[`Flex default baseline keeps the values consumers read from the default Flex tokens 1`] = ` +{ + "borderRadius": "cfa8c2371a72707b", + "color": "404280ad7ea5242b", + "colorCount": 119, + "fontFamily": "7a4e96787cf538ad", + "fontSize": "4a646185b2b8a198", + "fontWeight": "51d94cec151d0fba", + "lineHeight": "ef6cefe619d4be48", + "motion": "4d1fcc8da5a5ae8e", + "shadow": "67f2d9a2496a3ba8", + "spacing": "3bb2ea09d57c34c3", + "strokeWidth": "d7b6d097ecd34db0", +} +`; + +exports[`legacy compatibility baseline keeps Flex values converted from the dark Fluent projection base 1`] = ` +{ + "borderRadius": "13bd91dc683ef515", + "color": "79755e1e202aa0e8", + "colorCount": 119, + "fontFamily": "7a4e96787cf538ad", + "fontSize": "52fa58b4bacaf329", + "fontWeight": "8fe4b9b24b1f62c7", + "lineHeight": "e10b09e52a79eb29", + "motion": "4d1fcc8da5a5ae8e", + "shadow": "3abb099ca48f96cf", + "spacing": "b696c8094b46fe18", + "strokeWidth": "d7b6d097ecd34db0", +} +`; + +exports[`legacy compatibility baseline keeps Flex values converted from the darkElevated Fluent projection base 1`] = ` +{ + "borderRadius": "13bd91dc683ef515", + "color": "79755e1e202aa0e8", + "colorCount": 119, + "fontFamily": "7a4e96787cf538ad", + "fontSize": "52fa58b4bacaf329", + "fontWeight": "8fe4b9b24b1f62c7", + "lineHeight": "e10b09e52a79eb29", + "motion": "4d1fcc8da5a5ae8e", + "shadow": "3abb099ca48f96cf", + "spacing": "b696c8094b46fe18", + "strokeWidth": "d7b6d097ecd34db0", +} +`; + +exports[`legacy compatibility baseline keeps Flex values converted from the highContrast Fluent projection base 1`] = ` +{ + "borderRadius": "13bd91dc683ef515", + "color": "a6b03a11b350d9af", + "colorCount": 119, + "fontFamily": "7a4e96787cf538ad", + "fontSize": "52fa58b4bacaf329", + "fontWeight": "8fe4b9b24b1f62c7", + "lineHeight": "e10b09e52a79eb29", + "motion": "4d1fcc8da5a5ae8e", + "shadow": "3abb099ca48f96cf", + "spacing": "b696c8094b46fe18", + "strokeWidth": "d7b6d097ecd34db0", +} +`; + +exports[`legacy compatibility baseline keeps Flex values converted from the light Fluent projection base 1`] = ` +{ + "borderRadius": "13bd91dc683ef515", + "color": "6887e2160d35b879", + "colorCount": 119, + "fontFamily": "7a4e96787cf538ad", + "fontSize": "52fa58b4bacaf329", + "fontWeight": "8fe4b9b24b1f62c7", + "lineHeight": "e10b09e52a79eb29", + "motion": "4d1fcc8da5a5ae8e", + "shadow": "92288e2a96923296", + "spacing": "b696c8094b46fe18", + "strokeWidth": "d7b6d097ecd34db0", +} +`; + +exports[`legacy compatibility baseline keeps Flex values converted from the mock theme 1`] = ` +{ + "borderRadius": "13bd91dc683ef515", + "color": "182c4b50bcf5e1b8", + "colorCount": 119, + "fontFamily": "dc70eb85181162c3", + "fontSize": "5f02d7a42f1f300e", + "fontWeight": "8fe4b9b24b1f62c7", + "lineHeight": "e10b09e52a79eb29", + "motion": "4d1fcc8da5a5ae8e", + "shadow": "79d43104cbb1984a", + "spacing": "b696c8094b46fe18", + "strokeWidth": "d7b6d097ecd34db0", +} +`; + +exports[`legacy compatibility baseline keeps the dark Fluent projection base 1`] = ` +{ + "colorCount": 316, + "colors": "b56d0c7ca32cf2cf", + "components": "44136fa355b3678a", + "host": "e8e4ef993a27738e", + "shadows": "3388fc7114c96ee3", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; + +exports[`legacy compatibility baseline keeps the darkElevated Fluent projection base 1`] = ` +{ + "colorCount": 316, + "colors": "b56d0c7ca32cf2cf", + "components": "44136fa355b3678a", + "host": "e8e4ef993a27738e", + "shadows": "3388fc7114c96ee3", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; + +exports[`legacy compatibility baseline keeps the highContrast Fluent projection base 1`] = ` +{ + "colorCount": 316, + "colors": "bc1662992dbe6db5", + "components": "44136fa355b3678a", + "host": "9db06d0a5ce1e422", + "shadows": "3388fc7114c96ee3", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; + +exports[`legacy compatibility baseline keeps the light Fluent projection base 1`] = ` +{ + "colorCount": 316, + "colors": "e8b1164fbd03da1f", + "components": "44136fa355b3678a", + "host": "6be4fd450402dc4f", + "shadows": "6cb9f79865a74b20", + "spacing": "ae5c5f37376210ff", + "typography": "03f7ecba1c80477d", +} +`; diff --git a/packages/agentic/design/src/test/compatibility/__snapshots__/entryPoints.test.ts.snap b/packages/agentic/design/src/test/compatibility/__snapshots__/entryPoints.test.ts.snap new file mode 100644 index 00000000000..dfc0a221e84 --- /dev/null +++ b/packages/agentic/design/src/test/compatibility/__snapshots__/entryPoints.test.ts.snap @@ -0,0 +1,1032 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`public entry points . keeps its runtime export names 1`] = ` +[ + "FlexThemeReference: function", + "INTERACTIVE_COLOR_TOKENS: object", + "RootContext: object", + "RootInputBoundary: object", + "ThemeProvider: function", + "ThemedRoot: object", + "createThemeAppearanceSource: function", + "flexColor: function", + "flexTokensFromTheme: function", + "fontSize: function", + "fontWeight: function", + "isInteractiveColorToken: function", + "isInverseInteractionToken: function", + "normalizeThemeAppearanceRequest: function", + "resolveThemeAppearance: function", + "selectColorEntry: function", + "selectShadowEntry: function", + "themedStyleSheetFactory: function", + "useRootInputModality: function", + "useRootSettings: function", + "useThemeAppearance: function", + "useThemeState: function", +] +`; + +exports[`public entry points ./color-lib keeps its runtime export names 1`] = ` +[ + "compositeColor: function", + "compositeRgba: function", + "getContrastRatio: function", + "getHoverColor: function", + "getInteractionColor: function", + "getPressColor: function", + "oklchToRgb: function", + "parseColorValue: function", + "resolveContrastColors: function", + "rgbToOklch: function", + "rgbaToHex: function", +] +`; + +exports[`public entry points ./deprecated keeps its runtime export names 1`] = ` +[ + "getAliasTokens: function", + "getShadowTokens: function", + "globalTokens: object", + "hcAliasTokens: object", + "mapFontPipelineToTheme: function", + "mapPipelineToShadow: function", + "mapPipelineToTheme: function", +] +`; + +exports[`public entry points ./styling keeps its runtime export names 1`] = ` +[ + "colorStyleDef: function", + "createStateLevelMap: function", + "getActiveState: function", + "getGapStyleValue: function", + "getNumericStyleValue: function", + "getStateStyleFactory: function", + "getThemedColorStyleFactory: function", + "getThemedStateStyleFactory: function", + "interactiveStatePriority: object", + "pickActiveStyle: function", + "styleDefinitionToBranchedStyles: function", +] +`; + +exports[`public entry points ./styling/stylesheet keeps its runtime export names 1`] = ` +[ + "themedStyleSheet: function", +] +`; + +exports[`public entry points ./styling/tokens keeps its runtime export names 1`] = ` +[ + "backgroundColorTokens: object", + "borderStyles: object", + "borderTokens: object", + "colorTokens: object", + "fontStyles: object", + "foregroundColorTokens: object", + "getPaletteFromTheme: function", + "layoutStyles: object", + "layoutTokens: object", + "shadowStyles: object", + "shadowTokens: object", + "styleFunction: function", + "textTokens: function", + "tokenBuilder: function", +] +`; + +exports[`public entry points ./testing keeps its runtime export names 1`] = ` +[ + "MODE_SURFACE: object", + "PAIRINGS: object", + "WCAG: object", + "defaultFlexTokens: object", + "defaultResolvedThemeAppearance: object", + "getContrastFailures: function", + "getUnresolvableContrastPairs: function", + "mockTheme: object", + "validateContrastPairs: function", +] +`; + +exports[`public entry points ./themes keeps its runtime export names 1`] = ` +[ + "flexTheme: object", + "flexWarmTheme: object", + "fluentDarkTheme: object", + "fluentHcTheme: object", + "fluentLightTheme: object", + "fluentTheme: object", +] +`; + +exports[`public entry points ./theming keeps its runtime export names 1`] = ` +[ + "FlexThemeReference: function", + "RootContext: object", + "RootInputBoundary: object", + "ThemeContext: object", + "ThemeProvider: function", + "ThemeReference: function", + "ThemedRoot: object", + "appearanceOptionFromResolved: function", + "appearanceOptionsFromLegacy: function", + "createThemeAppearanceSource: function", + "flexColor: function", + "getCurrentAppearance: function", + "isHighContrast: function", + "normalizeThemeAppearanceRequest: function", + "resolveThemeAppearance: function", + "selectColorEntry: function", + "selectShadowEntry: function", + "setIsHighContrast: function", + "themeAppearanceKey: function", + "useRootInputModality: function", + "useRootSettings: function", + "useTheme: function", +] +`; + +exports[`public entry points ./theming/compat keeps its runtime export names 1`] = ` +[ + "themeFromFlexTokens: function", +] +`; + +exports[`public entry points ./theming/legacy-source keeps its runtime export names 1`] = ` +[ + "ThemeReference: function", +] +`; + +exports[`public entry points ./tokens/global keeps its runtime export names 1`] = ` +[ + "colorAnchorPrimary: string", + "colorAnchorShade10: string", + "colorAnchorShade20: string", + "colorAnchorShade30: string", + "colorAnchorShade40: string", + "colorAnchorShade50: string", + "colorAnchorTint10: string", + "colorAnchorTint20: string", + "colorAnchorTint30: string", + "colorAnchorTint40: string", + "colorAnchorTint50: string", + "colorAnchorTint60: string", + "colorBeigePrimary: string", + "colorBeigeShade10: string", + "colorBeigeShade20: string", + "colorBeigeShade30: string", + "colorBeigeShade40: string", + "colorBeigeShade50: string", + "colorBeigeTint10: string", + "colorBeigeTint20: string", + "colorBeigeTint30: string", + "colorBeigeTint40: string", + "colorBeigeTint50: string", + "colorBeigeTint60: string", + "colorBerryPrimary: string", + "colorBerryShade10: string", + "colorBerryShade20: string", + "colorBerryShade30: string", + "colorBerryShade40: string", + "colorBerryShade50: string", + "colorBerryTint10: string", + "colorBerryTint20: string", + "colorBerryTint30: string", + "colorBerryTint40: string", + "colorBerryTint50: string", + "colorBerryTint60: string", + "colorBlack: string", + "colorBlackAlpha10: string", + "colorBlackAlpha20: string", + "colorBlackAlpha30: string", + "colorBlackAlpha40: string", + "colorBlackAlpha5: string", + "colorBlackAlpha50: string", + "colorBlackAlpha60: string", + "colorBlackAlpha70: string", + "colorBlackAlpha80: string", + "colorBlackAlpha90: string", + "colorBluePrimary: string", + "colorBlueShade10: string", + "colorBlueShade20: string", + "colorBlueShade30: string", + "colorBlueShade40: string", + "colorBlueShade50: string", + "colorBlueTint10: string", + "colorBlueTint20: string", + "colorBlueTint30: string", + "colorBlueTint40: string", + "colorBlueTint50: string", + "colorBlueTint60: string", + "colorBrand10: string", + "colorBrand100: string", + "colorBrand110: string", + "colorBrand120: string", + "colorBrand130: string", + "colorBrand140: string", + "colorBrand150: string", + "colorBrand160: string", + "colorBrand20: string", + "colorBrand30: string", + "colorBrand40: string", + "colorBrand50: string", + "colorBrand60: string", + "colorBrand70: string", + "colorBrand80: string", + "colorBrand90: string", + "colorBrandShade40: string", + "colorBrandShade50: string", + "colorBrandShade60: string", + "colorBrandShadowAmbient: string", + "colorBrandShadowKey: string", + "colorBrandTint50: string", + "colorBrandTint60: string", + "colorBrassPrimary: string", + "colorBrassShade10: string", + "colorBrassShade20: string", + "colorBrassShade30: string", + "colorBrassShade40: string", + "colorBrassShade50: string", + "colorBrassTint10: string", + "colorBrassTint20: string", + "colorBrassTint30: string", + "colorBrassTint40: string", + "colorBrassTint50: string", + "colorBrassTint60: string", + "colorBronzePrimary: string", + "colorBronzeShade10: string", + "colorBronzeShade20: string", + "colorBronzeShade30: string", + "colorBronzeShade40: string", + "colorBronzeShade50: string", + "colorBronzeTint10: string", + "colorBronzeTint20: string", + "colorBronzeTint30: string", + "colorBronzeTint40: string", + "colorBronzeTint50: string", + "colorBronzeTint60: string", + "colorBrownPrimary: string", + "colorBrownShade10: string", + "colorBrownShade20: string", + "colorBrownShade30: string", + "colorBrownShade40: string", + "colorBrownShade50: string", + "colorBrownTint10: string", + "colorBrownTint20: string", + "colorBrownTint30: string", + "colorBrownTint40: string", + "colorBrownTint50: string", + "colorBrownTint60: string", + "colorBurgundyPrimary: string", + "colorBurgundyShade10: string", + "colorBurgundyShade20: string", + "colorBurgundyShade30: string", + "colorBurgundyShade40: string", + "colorBurgundyShade50: string", + "colorBurgundyTint10: string", + "colorBurgundyTint20: string", + "colorBurgundyTint30: string", + "colorBurgundyTint40: string", + "colorBurgundyTint50: string", + "colorBurgundyTint60: string", + "colorCharcoalPrimary: string", + "colorCharcoalShade10: string", + "colorCharcoalShade20: string", + "colorCharcoalShade30: string", + "colorCharcoalShade40: string", + "colorCharcoalShade50: string", + "colorCharcoalTint10: string", + "colorCharcoalTint20: string", + "colorCharcoalTint30: string", + "colorCharcoalTint40: string", + "colorCharcoalTint50: string", + "colorCharcoalTint60: string", + "colorCornflowerPrimary: string", + "colorCornflowerShade10: string", + "colorCornflowerShade20: string", + "colorCornflowerShade30: string", + "colorCornflowerShade40: string", + "colorCornflowerShade50: string", + "colorCornflowerTint10: string", + "colorCornflowerTint20: string", + "colorCornflowerTint30: string", + "colorCornflowerTint40: string", + "colorCornflowerTint50: string", + "colorCornflowerTint60: string", + "colorCranberryPrimary: string", + "colorCranberryShade10: string", + "colorCranberryShade20: string", + "colorCranberryShade30: string", + "colorCranberryShade40: string", + "colorCranberryShade50: string", + "colorCranberryTint10: string", + "colorCranberryTint20: string", + "colorCranberryTint30: string", + "colorCranberryTint40: string", + "colorCranberryTint50: string", + "colorCranberryTint60: string", + "colorCyanPrimary: string", + "colorCyanShade10: string", + "colorCyanShade20: string", + "colorCyanShade30: string", + "colorCyanShade40: string", + "colorCyanShade50: string", + "colorCyanTint10: string", + "colorCyanTint20: string", + "colorCyanTint30: string", + "colorCyanTint40: string", + "colorCyanTint50: string", + "colorCyanTint60: string", + "colorDarkBluePrimary: string", + "colorDarkBlueShade10: string", + "colorDarkBlueShade20: string", + "colorDarkBlueShade30: string", + "colorDarkBlueShade40: string", + "colorDarkBlueShade50: string", + "colorDarkBlueTint10: string", + "colorDarkBlueTint20: string", + "colorDarkBlueTint30: string", + "colorDarkBlueTint40: string", + "colorDarkBlueTint50: string", + "colorDarkBlueTint60: string", + "colorDarkBrownPrimary: string", + "colorDarkBrownShade10: string", + "colorDarkBrownShade20: string", + "colorDarkBrownShade30: string", + "colorDarkBrownShade40: string", + "colorDarkBrownShade50: string", + "colorDarkBrownTint10: string", + "colorDarkBrownTint20: string", + "colorDarkBrownTint30: string", + "colorDarkBrownTint40: string", + "colorDarkBrownTint50: string", + "colorDarkBrownTint60: string", + "colorDarkGreenPrimary: string", + "colorDarkGreenShade10: string", + "colorDarkGreenShade20: string", + "colorDarkGreenShade30: string", + "colorDarkGreenShade40: string", + "colorDarkGreenShade50: string", + "colorDarkGreenTint10: string", + "colorDarkGreenTint20: string", + "colorDarkGreenTint30: string", + "colorDarkGreenTint40: string", + "colorDarkGreenTint50: string", + "colorDarkGreenTint60: string", + "colorDarkOrangePrimary: string", + "colorDarkOrangeShade10: string", + "colorDarkOrangeShade20: string", + "colorDarkOrangeShade30: string", + "colorDarkOrangeShade40: string", + "colorDarkOrangeShade50: string", + "colorDarkOrangeTint10: string", + "colorDarkOrangeTint20: string", + "colorDarkOrangeTint30: string", + "colorDarkOrangeTint40: string", + "colorDarkOrangeTint50: string", + "colorDarkOrangeTint60: string", + "colorDarkPurplePrimary: string", + "colorDarkPurpleShade10: string", + "colorDarkPurpleShade20: string", + "colorDarkPurpleShade30: string", + "colorDarkPurpleShade40: string", + "colorDarkPurpleShade50: string", + "colorDarkPurpleTint10: string", + "colorDarkPurpleTint20: string", + "colorDarkPurpleTint30: string", + "colorDarkPurpleTint40: string", + "colorDarkPurpleTint50: string", + "colorDarkPurpleTint60: string", + "colorDarkRedPrimary: string", + "colorDarkRedShade10: string", + "colorDarkRedShade20: string", + "colorDarkRedShade30: string", + "colorDarkRedShade40: string", + "colorDarkRedShade50: string", + "colorDarkRedTint10: string", + "colorDarkRedTint20: string", + "colorDarkRedTint30: string", + "colorDarkRedTint40: string", + "colorDarkRedTint50: string", + "colorDarkRedTint60: string", + "colorDarkTealPrimary: string", + "colorDarkTealShade10: string", + "colorDarkTealShade20: string", + "colorDarkTealShade30: string", + "colorDarkTealShade40: string", + "colorDarkTealShade50: string", + "colorDarkTealTint10: string", + "colorDarkTealTint20: string", + "colorDarkTealTint30: string", + "colorDarkTealTint40: string", + "colorDarkTealTint50: string", + "colorDarkTealTint60: string", + "colorExcelPrimary: string", + "colorExcelShade10: string", + "colorExcelShade20: string", + "colorExcelShade30: string", + "colorExcelShade40: string", + "colorExcelShade50: string", + "colorExcelShade60: string", + "colorExcelTint10: string", + "colorExcelTint20: string", + "colorExcelTint30: string", + "colorExcelTint40: string", + "colorExcelTint50: string", + "colorExcelTint60: string", + "colorForestPrimary: string", + "colorForestShade10: string", + "colorForestShade20: string", + "colorForestShade30: string", + "colorForestShade40: string", + "colorForestShade50: string", + "colorForestTint10: string", + "colorForestTint20: string", + "colorForestTint30: string", + "colorForestTint40: string", + "colorForestTint50: string", + "colorForestTint60: string", + "colorGoldPrimary: string", + "colorGoldShade10: string", + "colorGoldShade20: string", + "colorGoldShade30: string", + "colorGoldShade40: string", + "colorGoldShade50: string", + "colorGoldTint10: string", + "colorGoldTint20: string", + "colorGoldTint30: string", + "colorGoldTint40: string", + "colorGoldTint50: string", + "colorGoldTint60: string", + "colorGrapePrimary: string", + "colorGrapeShade10: string", + "colorGrapeShade20: string", + "colorGrapeShade30: string", + "colorGrapeShade40: string", + "colorGrapeShade50: string", + "colorGrapeTint10: string", + "colorGrapeTint20: string", + "colorGrapeTint30: string", + "colorGrapeTint40: string", + "colorGrapeTint50: string", + "colorGrapeTint60: string", + "colorGreenPrimary: string", + "colorGreenShade10: string", + "colorGreenShade20: string", + "colorGreenShade30: string", + "colorGreenShade40: string", + "colorGreenShade50: string", + "colorGreenTint10: string", + "colorGreenTint20: string", + "colorGreenTint30: string", + "colorGreenTint40: string", + "colorGreenTint50: string", + "colorGreenTint60: string", + "colorGrey10: string", + "colorGrey10Alpha10: string", + "colorGrey10Alpha20: string", + "colorGrey10Alpha30: string", + "colorGrey10Alpha40: string", + "colorGrey10Alpha5: string", + "colorGrey10Alpha50: string", + "colorGrey10Alpha60: string", + "colorGrey10Alpha70: string", + "colorGrey10Alpha80: string", + "colorGrey10Alpha90: string", + "colorGrey12: string", + "colorGrey12Alpha10: string", + "colorGrey12Alpha20: string", + "colorGrey12Alpha30: string", + "colorGrey12Alpha40: string", + "colorGrey12Alpha5: string", + "colorGrey12Alpha50: string", + "colorGrey12Alpha60: string", + "colorGrey12Alpha70: string", + "colorGrey12Alpha80: string", + "colorGrey12Alpha90: string", + "colorGrey14: string", + "colorGrey14Alpha10: string", + "colorGrey14Alpha20: string", + "colorGrey14Alpha30: string", + "colorGrey14Alpha40: string", + "colorGrey14Alpha5: string", + "colorGrey14Alpha50: string", + "colorGrey14Alpha60: string", + "colorGrey14Alpha70: string", + "colorGrey14Alpha80: string", + "colorGrey14Alpha90: string", + "colorGrey16: string", + "colorGrey18: string", + "colorGrey2: string", + "colorGrey20: string", + "colorGrey22: string", + "colorGrey24: string", + "colorGrey26: string", + "colorGrey28: string", + "colorGrey30: string", + "colorGrey32: string", + "colorGrey34: string", + "colorGrey36: string", + "colorGrey38: string", + "colorGrey4: string", + "colorGrey40: string", + "colorGrey42: string", + "colorGrey44: string", + "colorGrey46: string", + "colorGrey48: string", + "colorGrey50: string", + "colorGrey52: string", + "colorGrey54: string", + "colorGrey56: string", + "colorGrey58: string", + "colorGrey6: string", + "colorGrey60: string", + "colorGrey62: string", + "colorGrey64: string", + "colorGrey66: string", + "colorGrey68: string", + "colorGrey70: string", + "colorGrey72: string", + "colorGrey74: string", + "colorGrey76: string", + "colorGrey78: string", + "colorGrey8: string", + "colorGrey80: string", + "colorGrey82: string", + "colorGrey84: string", + "colorGrey86: string", + "colorGrey88: string", + "colorGrey90: string", + "colorGrey92: string", + "colorGrey94: string", + "colorGrey96: string", + "colorGrey98: string", + "colorHcButtonFace: string", + "colorHcButtonText: string", + "colorHcCanvas: string", + "colorHcCanvasText: string", + "colorHcDisabled: string", + "colorHcHighlight: string", + "colorHcHighlightText: string", + "colorHcHyperlink: string", + "colorHotPinkPrimary: string", + "colorHotPinkShade10: string", + "colorHotPinkShade20: string", + "colorHotPinkShade30: string", + "colorHotPinkShade40: string", + "colorHotPinkShade50: string", + "colorHotPinkTint10: string", + "colorHotPinkTint20: string", + "colorHotPinkTint30: string", + "colorHotPinkTint40: string", + "colorHotPinkTint50: string", + "colorHotPinkTint60: string", + "colorLavenderPrimary: string", + "colorLavenderShade10: string", + "colorLavenderShade20: string", + "colorLavenderShade30: string", + "colorLavenderShade40: string", + "colorLavenderShade50: string", + "colorLavenderTint10: string", + "colorLavenderTint20: string", + "colorLavenderTint30: string", + "colorLavenderTint40: string", + "colorLavenderTint50: string", + "colorLavenderTint60: string", + "colorLightBluePrimary: string", + "colorLightBlueShade10: string", + "colorLightBlueShade20: string", + "colorLightBlueShade30: string", + "colorLightBlueShade40: string", + "colorLightBlueShade50: string", + "colorLightBlueTint10: string", + "colorLightBlueTint20: string", + "colorLightBlueTint30: string", + "colorLightBlueTint40: string", + "colorLightBlueTint50: string", + "colorLightBlueTint60: string", + "colorLightGreenPrimary: string", + "colorLightGreenShade10: string", + "colorLightGreenShade20: string", + "colorLightGreenShade30: string", + "colorLightGreenShade40: string", + "colorLightGreenShade50: string", + "colorLightGreenTint10: string", + "colorLightGreenTint20: string", + "colorLightGreenTint30: string", + "colorLightGreenTint40: string", + "colorLightGreenTint50: string", + "colorLightGreenTint60: string", + "colorLightTealPrimary: string", + "colorLightTealShade10: string", + "colorLightTealShade20: string", + "colorLightTealShade30: string", + "colorLightTealShade40: string", + "colorLightTealShade50: string", + "colorLightTealTint10: string", + "colorLightTealTint20: string", + "colorLightTealTint30: string", + "colorLightTealTint40: string", + "colorLightTealTint50: string", + "colorLightTealTint60: string", + "colorLilacPrimary: string", + "colorLilacShade10: string", + "colorLilacShade20: string", + "colorLilacShade30: string", + "colorLilacShade40: string", + "colorLilacShade50: string", + "colorLilacTint10: string", + "colorLilacTint20: string", + "colorLilacTint30: string", + "colorLilacTint40: string", + "colorLilacTint50: string", + "colorLilacTint60: string", + "colorLimePrimary: string", + "colorLimeShade10: string", + "colorLimeShade20: string", + "colorLimeShade30: string", + "colorLimeShade40: string", + "colorLimeShade50: string", + "colorLimeTint10: string", + "colorLimeTint20: string", + "colorLimeTint30: string", + "colorLimeTint40: string", + "colorLimeTint50: string", + "colorLimeTint60: string", + "colorMagentaPrimary: string", + "colorMagentaShade10: string", + "colorMagentaShade20: string", + "colorMagentaShade30: string", + "colorMagentaShade40: string", + "colorMagentaShade50: string", + "colorMagentaTint10: string", + "colorMagentaTint20: string", + "colorMagentaTint30: string", + "colorMagentaTint40: string", + "colorMagentaTint50: string", + "colorMagentaTint60: string", + "colorMarigoldPrimary: string", + "colorMarigoldShade10: string", + "colorMarigoldShade20: string", + "colorMarigoldShade30: string", + "colorMarigoldShade40: string", + "colorMarigoldShade50: string", + "colorMarigoldTint10: string", + "colorMarigoldTint20: string", + "colorMarigoldTint30: string", + "colorMarigoldTint40: string", + "colorMarigoldTint50: string", + "colorMarigoldTint60: string", + "colorMinkPrimary: string", + "colorMinkShade10: string", + "colorMinkShade20: string", + "colorMinkShade30: string", + "colorMinkShade40: string", + "colorMinkShade50: string", + "colorMinkTint10: string", + "colorMinkTint20: string", + "colorMinkTint30: string", + "colorMinkTint40: string", + "colorMinkTint50: string", + "colorMinkTint60: string", + "colorNavyPrimary: string", + "colorNavyShade10: string", + "colorNavyShade20: string", + "colorNavyShade30: string", + "colorNavyShade40: string", + "colorNavyShade50: string", + "colorNavyTint10: string", + "colorNavyTint20: string", + "colorNavyTint30: string", + "colorNavyTint40: string", + "colorNavyTint50: string", + "colorNavyTint60: string", + "colorNeutralShadowAmbient: string", + "colorNeutralShadowAmbientDarker: string", + "colorNeutralShadowAmbientLighter: string", + "colorNeutralShadowKey: string", + "colorNeutralShadowKeyDarker: string", + "colorNeutralShadowKeyLighter: string", + "colorOfficePrimary: string", + "colorOfficeShade10: string", + "colorOfficeShade20: string", + "colorOfficeShade30: string", + "colorOfficeShade40: string", + "colorOfficeShade50: string", + "colorOfficeShade60: string", + "colorOfficeTint10: string", + "colorOfficeTint20: string", + "colorOfficeTint30: string", + "colorOfficeTint40: string", + "colorOfficeTint50: string", + "colorOfficeTint60: string", + "colorOneNotePrimary: string", + "colorOneNoteShade10: string", + "colorOneNoteShade20: string", + "colorOneNoteShade30: string", + "colorOneNoteShade40: string", + "colorOneNoteShade50: string", + "colorOneNoteShade60: string", + "colorOneNoteTint10: string", + "colorOneNoteTint20: string", + "colorOneNoteTint30: string", + "colorOneNoteTint40: string", + "colorOneNoteTint50: string", + "colorOneNoteTint60: string", + "colorOrangePrimary: string", + "colorOrangeShade10: string", + "colorOrangeShade20: string", + "colorOrangeShade30: string", + "colorOrangeShade40: string", + "colorOrangeShade50: string", + "colorOrangeTint10: string", + "colorOrangeTint20: string", + "colorOrangeTint30: string", + "colorOrangeTint40: string", + "colorOrangeTint50: string", + "colorOrangeTint60: string", + "colorOrchidPrimary: string", + "colorOrchidShade10: string", + "colorOrchidShade20: string", + "colorOrchidShade30: string", + "colorOrchidShade40: string", + "colorOrchidShade50: string", + "colorOrchidTint10: string", + "colorOrchidTint20: string", + "colorOrchidTint30: string", + "colorOrchidTint40: string", + "colorOrchidTint50: string", + "colorOrchidTint60: string", + "colorOutlookPrimary: string", + "colorOutlookShade10: string", + "colorOutlookShade20: string", + "colorOutlookShade30: string", + "colorOutlookShade40: string", + "colorOutlookShade50: string", + "colorOutlookShade60: string", + "colorOutlookTint10: string", + "colorOutlookTint20: string", + "colorOutlookTint30: string", + "colorOutlookTint40: string", + "colorOutlookTint50: string", + "colorOutlookTint60: string", + "colorPeachPrimary: string", + "colorPeachShade10: string", + "colorPeachShade20: string", + "colorPeachShade30: string", + "colorPeachShade40: string", + "colorPeachShade50: string", + "colorPeachTint10: string", + "colorPeachTint20: string", + "colorPeachTint30: string", + "colorPeachTint40: string", + "colorPeachTint50: string", + "colorPeachTint60: string", + "colorPinkPrimary: string", + "colorPinkShade10: string", + "colorPinkShade20: string", + "colorPinkShade30: string", + "colorPinkShade40: string", + "colorPinkShade50: string", + "colorPinkTint10: string", + "colorPinkTint20: string", + "colorPinkTint30: string", + "colorPinkTint40: string", + "colorPinkTint50: string", + "colorPinkTint60: string", + "colorPlatinumPrimary: string", + "colorPlatinumShade10: string", + "colorPlatinumShade20: string", + "colorPlatinumShade30: string", + "colorPlatinumShade40: string", + "colorPlatinumShade50: string", + "colorPlatinumTint10: string", + "colorPlatinumTint20: string", + "colorPlatinumTint30: string", + "colorPlatinumTint40: string", + "colorPlatinumTint50: string", + "colorPlatinumTint60: string", + "colorPlumPrimary: string", + "colorPlumShade10: string", + "colorPlumShade20: string", + "colorPlumShade30: string", + "colorPlumShade40: string", + "colorPlumShade50: string", + "colorPlumTint10: string", + "colorPlumTint20: string", + "colorPlumTint30: string", + "colorPlumTint40: string", + "colorPlumTint50: string", + "colorPlumTint60: string", + "colorPowerPointPrimary: string", + "colorPowerPointShade10: string", + "colorPowerPointShade20: string", + "colorPowerPointShade30: string", + "colorPowerPointShade40: string", + "colorPowerPointShade50: string", + "colorPowerPointShade60: string", + "colorPowerPointTint10: string", + "colorPowerPointTint20: string", + "colorPowerPointTint30: string", + "colorPowerPointTint40: string", + "colorPowerPointTint50: string", + "colorPowerPointTint60: string", + "colorPumpkinPrimary: string", + "colorPumpkinShade10: string", + "colorPumpkinShade20: string", + "colorPumpkinShade30: string", + "colorPumpkinShade40: string", + "colorPumpkinShade50: string", + "colorPumpkinTint10: string", + "colorPumpkinTint20: string", + "colorPumpkinTint30: string", + "colorPumpkinTint40: string", + "colorPumpkinTint50: string", + "colorPumpkinTint60: string", + "colorPurplePrimary: string", + "colorPurpleShade10: string", + "colorPurpleShade20: string", + "colorPurpleShade30: string", + "colorPurpleShade40: string", + "colorPurpleShade50: string", + "colorPurpleTint10: string", + "colorPurpleTint20: string", + "colorPurpleTint30: string", + "colorPurpleTint40: string", + "colorPurpleTint50: string", + "colorPurpleTint60: string", + "colorRedPrimary: string", + "colorRedShade10: string", + "colorRedShade20: string", + "colorRedShade30: string", + "colorRedShade40: string", + "colorRedShade50: string", + "colorRedTint10: string", + "colorRedTint20: string", + "colorRedTint30: string", + "colorRedTint40: string", + "colorRedTint50: string", + "colorRedTint60: string", + "colorRoyalBluePrimary: string", + "colorRoyalBlueShade10: string", + "colorRoyalBlueShade20: string", + "colorRoyalBlueShade30: string", + "colorRoyalBlueShade40: string", + "colorRoyalBlueShade50: string", + "colorRoyalBlueTint10: string", + "colorRoyalBlueTint20: string", + "colorRoyalBlueTint30: string", + "colorRoyalBlueTint40: string", + "colorRoyalBlueTint50: string", + "colorRoyalBlueTint60: string", + "colorSeafoamPrimary: string", + "colorSeafoamShade10: string", + "colorSeafoamShade20: string", + "colorSeafoamShade30: string", + "colorSeafoamShade40: string", + "colorSeafoamShade50: string", + "colorSeafoamTint10: string", + "colorSeafoamTint20: string", + "colorSeafoamTint30: string", + "colorSeafoamTint40: string", + "colorSeafoamTint50: string", + "colorSeafoamTint60: string", + "colorSilverPrimary: string", + "colorSilverShade10: string", + "colorSilverShade20: string", + "colorSilverShade30: string", + "colorSilverShade40: string", + "colorSilverShade50: string", + "colorSilverTint10: string", + "colorSilverTint20: string", + "colorSilverTint30: string", + "colorSilverTint40: string", + "colorSilverTint50: string", + "colorSilverTint60: string", + "colorSteelPrimary: string", + "colorSteelShade10: string", + "colorSteelShade20: string", + "colorSteelShade30: string", + "colorSteelShade40: string", + "colorSteelShade50: string", + "colorSteelTint10: string", + "colorSteelTint20: string", + "colorSteelTint30: string", + "colorSteelTint40: string", + "colorSteelTint50: string", + "colorSteelTint60: string", + "colorTealPrimary: string", + "colorTealShade10: string", + "colorTealShade20: string", + "colorTealShade30: string", + "colorTealShade40: string", + "colorTealShade50: string", + "colorTealTint10: string", + "colorTealTint20: string", + "colorTealTint30: string", + "colorTealTint40: string", + "colorTealTint50: string", + "colorTealTint60: string", + "colorWhite: string", + "colorWhiteAlpha10: string", + "colorWhiteAlpha20: string", + "colorWhiteAlpha30: string", + "colorWhiteAlpha40: string", + "colorWhiteAlpha5: string", + "colorWhiteAlpha50: string", + "colorWhiteAlpha60: string", + "colorWhiteAlpha70: string", + "colorWhiteAlpha80: string", + "colorWhiteAlpha90: string", + "colorWordPrimary: string", + "colorWordShade10: string", + "colorWordShade20: string", + "colorWordShade30: string", + "colorWordShade40: string", + "colorWordShade50: string", + "colorWordShade60: string", + "colorWordTint10: string", + "colorWordTint20: string", + "colorWordTint30: string", + "colorWordTint40: string", + "colorWordTint50: string", + "colorWordTint60: string", + "colorYellowPrimary: string", + "colorYellowShade10: string", + "colorYellowShade20: string", + "colorYellowShade30: string", + "colorYellowShade40: string", + "colorYellowShade50: string", + "colorYellowTint10: string", + "colorYellowTint20: string", + "colorYellowTint30: string", + "colorYellowTint40: string", + "colorYellowTint50: string", + "colorYellowTint60: string", + "cornerRadius120: number", + "cornerRadius20: number", + "cornerRadius40: number", + "cornerRadius60: number", + "cornerRadius80: number", + "cornerRadiusCircular: number", + "cornerRadiusNone: number", + "fontFamilyBase: string", + "fontFamilyMonospace: string", + "fontFamilyNumeric: string", + "fontLineHeight100: number", + "fontLineHeight1000: number", + "fontLineHeight200: number", + "fontLineHeight300: number", + "fontLineHeight400: number", + "fontLineHeight500: number", + "fontLineHeight600: number", + "fontLineHeight700: number", + "fontLineHeight800: number", + "fontLineHeight900: number", + "fontSize100: number", + "fontSize1000: number", + "fontSize200: number", + "fontSize300: number", + "fontSize400: number", + "fontSize500: number", + "fontSize600: number", + "fontSize700: number", + "fontSize800: number", + "fontSize900: number", + "fontWeightBold: string", + "fontWeightMedium: string", + "fontWeightRegular: string", + "fontWeightSemibold: string", + "size100: number", + "size120: number", + "size1200: number", + "size160: number", + "size20: number", + "size200: number", + "size240: number", + "size280: number", + "size320: number", + "size360: number", + "size40: number", + "size400: number", + "size480: number", + "size560: number", + "size60: number", + "size640: number", + "size720: number", + "size80: number", + "size800: number", + "sizeNone: number", + "strokeWidth05: number", + "strokeWidth10: number", + "strokeWidth15: number", + "strokeWidth20: number", + "strokeWidth30: number", + "strokeWidth40: number", + "strokeWidth60: number", + "strokeWidthNone: number", +] +`; diff --git a/packages/agentic/design/src/test/compatibility/compatibilityBaseline.test.ts b/packages/agentic/design/src/test/compatibility/compatibilityBaseline.test.ts new file mode 100644 index 00000000000..10eef486f8f --- /dev/null +++ b/packages/agentic/design/src/test/compatibility/compatibilityBaseline.test.ts @@ -0,0 +1,69 @@ +import { PlatformColor } from 'react-native'; + +import { themeFromFlexTokens } from '../../fluent/compat/themeFromFlexTokens'; +import { selectFluentTheme } from '../../themes/fluent/selectFluentTheme'; +import type { ResolvedThemeAppearance } from '../../types/appearance.types'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { mockTheme } from '../fixtures/mockTheme'; +import { defaultFlexTokens } from '../../flex/defaults/defaultTokens'; +import { flexTokensFromTheme } from '../../flex/adapters/flexTokensFromTheme'; +import { flexTokenFingerprints, themeFingerprints } from './fingerprint'; + +const appearances: [string, ResolvedThemeAppearance][] = [ + ['light', { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base' }], + ['dark', { colorScheme: 'dark', contrast: 'standard', interfaceLevel: 'base' }], + ['darkElevated', { colorScheme: 'dark', contrast: 'standard', interfaceLevel: 'elevated' }], + ['highContrast', { colorScheme: 'dark', contrast: 'highContrast', interfaceLevel: 'base' }], +]; + +/** + * Legacy Fluent consumers must observe identical values through every Flex + * refactoring phase. The forward-adapter baseline compares the values a + * consumer reads for each color state, so a representation change that keeps + * those values passes unchanged. + */ +describe('legacy compatibility baseline', () => { + it.each(appearances)('keeps the %s Fluent projection base', (_name, appearance) => { + expect(themeFingerprints(selectFluentTheme(appearance))).toMatchSnapshot(); + }); + + it.each(appearances)('keeps Flex values converted from the %s Fluent projection base', (_name, appearance) => { + expect(flexTokenFingerprints(flexTokensFromTheme(selectFluentTheme(appearance)))).toMatchSnapshot(); + }); + + it('keeps Flex values converted from the mock theme', () => { + expect(flexTokenFingerprints(flexTokensFromTheme(mockTheme))).toMatchSnapshot(); + }); + + it('keeps native colors authored in a legacy theme through both adapters', () => { + const rest = PlatformColor('controlAccentColor'); + const hover = PlatformColor('selectedControlColor'); + const theme: Theme = { + ...mockTheme, + colors: { ...mockTheme.colors, brandBackground: rest, brandBackgroundHover: hover }, + }; + + const tokens = flexTokensFromTheme(theme); + expect(tokens.color.backgroundBrandHeavy.rest).toBe(rest); + expect(tokens.color.backgroundBrandHeavy.hover).toBe(hover); + + const projected = themeFromFlexTokens(tokens, appearances[0][1]); + expect(projected.colors.brandBackground).toEqual(rest); + expect(projected.colors.brandBackgroundHover).toEqual(hover); + }); +}); + +/** + * Flex-sourced values. These intentionally change when the Flex defaults adopt + * current x3 sources; they must not change during mechanical or + * representation-only phases. + */ +describe('Flex default baseline', () => { + it('keeps the values consumers read from the default Flex tokens', () => { + expect(flexTokenFingerprints(defaultFlexTokens)).toMatchSnapshot(); + }); + + it.each(appearances)('keeps the %s legacy projection of the default Flex tokens', (_name, appearance) => { + expect(themeFingerprints(themeFromFlexTokens(defaultFlexTokens, appearance))).toMatchSnapshot(); + }); +}); diff --git a/packages/agentic/design/src/test/compatibility/entryPoints.test.ts b/packages/agentic/design/src/test/compatibility/entryPoints.test.ts new file mode 100644 index 00000000000..45018161be0 --- /dev/null +++ b/packages/agentic/design/src/test/compatibility/entryPoints.test.ts @@ -0,0 +1,65 @@ +type ExportConditions = { + types: string; + 'react-native': string; + import: string; + default: string; +}; + +type PackageJson = { + exports: Record<string, ExportConditions | string>; +}; + +const packageJson = jest.requireActual<PackageJson>('../../../package.json'); + +const publicEntryPoints = [ + '.', + './tokens/global', + './color-lib', + './theming', + './theming/legacy-source', + './theming/compat', + './themes', + './testing', + './deprecated', + './styling', + './styling/stylesheet', + './styling/tokens', +]; + +const moduleEntries = Object.entries(packageJson.exports).filter(([key]) => key !== './package.json') as [string, ExportConditions][]; + +function sourceStem(target: string): string { + const prefix = './src/'; + const extension = target.endsWith('.tsx') ? '.tsx' : '.ts'; + expect(target.startsWith(prefix)).toBe(true); + expect(target.endsWith(extension)).toBe(true); + return target.slice(prefix.length, target.length - extension.length); +} + +function describeExports(moduleExports: Record<string, unknown>): string[] { + return Object.keys(moduleExports) + .sort() + .map((name) => `${name}: ${typeof moduleExports[name]}`); +} + +describe('public entry points', () => { + it('retains every supported package subpath', () => { + expect(Object.keys(packageJson.exports).sort()).toEqual([...publicEntryPoints, './package.json'].sort()); + expect(packageJson.exports['./package.json']).toBe('./package.json'); + }); + + it.each(moduleEntries)('%s keeps mirrored types, react-native, import, and default conditions', (_key, conditions) => { + expect(Object.keys(conditions)).toEqual(['types', 'react-native', 'import', 'default']); + expect(conditions.default).toBe(conditions['react-native']); + + const stem = sourceStem(conditions['react-native']); + expect(conditions.types).toBe(`./lib/${stem}.d.ts`); + expect(conditions.import).toBe(`./lib/${stem}.js`); + }); + + it.each(moduleEntries)('%s keeps its runtime export names', (_key, conditions) => { + const moduleExports = jest.requireActual<Record<string, unknown>>(`../../../${conditions['react-native'].slice(2)}`); + + expect(describeExports(moduleExports)).toMatchSnapshot(); + }); +}); diff --git a/packages/agentic/design/src/test/compatibility/entryPoints.types.test.ts b/packages/agentic/design/src/test/compatibility/entryPoints.types.test.ts new file mode 100644 index 00000000000..bd00e9958cf --- /dev/null +++ b/packages/agentic/design/src/test/compatibility/entryPoints.types.test.ts @@ -0,0 +1,269 @@ +import type { TextStyle } from 'react-native'; + +import { flexTokensFromTheme, useThemeState } from '../../index'; +import type { + FontSize as RootFontSize, + FontWeight as RootFontWeight, + ResolvedThemeAppearance as RootResolvedThemeAppearance, + ThemeAppearanceOptions as RootThemeAppearanceOptions, + ThemeState, +} from '../../index'; +import { + getAliasTokens, + getShadowTokens, + globalTokens, + hcAliasTokens, + mapFontPipelineToTheme, + mapPipelineToShadow, + mapPipelineToTheme, +} from '../../deprecated/index'; +import { themeFromFlexTokens } from '../../fluent/compat/index'; +import type { ThemeFromFlexTokensOptions } from '../../fluent/compat/index'; +import { + getCurrentAppearance, + isHighContrast, + resolveThemeAppearance, + setIsHighContrast, + ThemeContext, + ThemeProvider, + ThemeReference, + themeAppearanceKey, + useTheme, +} from '../../theming/index'; +import type { + AliasColorTokens, + AppearanceOptions, + BaseShadowAliasTokens, + Color, + FabricWebPalette, + FontDynamicTypeRamp, + FontFamilies, + FontFamily, + FontFamilyValue, + FontSize, + FontSizeValuePoints, + FontSizes, + FontWeight, + FontWeightValue, + FontWeights, + OfficePalette, + OnThemeChange, + Palette, + PaletteBackgroundColors, + PaletteTextColors, + PartialPalette, + PartialShadowDefinition, + PartialTheme, + PartialTypography, + ResolvedThemeAppearance, + ShadowToken, + ShadowValue, + Spacing, + TextStyling, + Theme, + ThemeColorDefinition, + ThemeOptions, + ThemeProviderProps, + ThemeRecipe, + ThemeShadowDefinition, + ThemeTransform, + Typography, + Variant, + Variants, + VariantValue, +} from '../../theming/index'; +import { ThemeReference as LegacySourceThemeReference } from '../../fluent/legacySource'; +import type { OnThemeChange as LegacySourceOnThemeChange, ThemeRecipe as LegacySourceThemeRecipe } from '../../fluent/legacySource'; +import { themedStyleSheet } from '../../fluent/styling/stylesheet/index'; +import type { NamedStyles } from '../../fluent/styling/stylesheet/index'; +import { fluentDarkTheme } from '../../themes/index'; +import { + backgroundColorTokens, + borderStyles, + borderTokens, + colorTokens, + fontStyles, + foregroundColorTokens, + getPaletteFromTheme, + layoutStyles, + layoutTokens, + shadowStyles, + shadowTokens, + styleFunction, + textTokens, + tokenBuilder, +} from '../../fluent/styling/tokens/index'; +import type { + FontDecorationTokens, + FontStyleTokens, + FontTokens, + FontVariantTokens, + IBackgroundColorTokens, + IBorderTokens, + IColorTokens, + IForegroundColorTokens, + IShadowTokens, + LayoutTokens, + LookupThemePart, + OperationSet, + StyleFactoryFunction, + StyleFactoryFunctionRaw, + StyleFactoryOperation, + TokenBuilder, +} from '../../fluent/styling/tokens/index'; + +/** + * Every type name the compatibility packages re-export must remain importable + * from its owning design entry point. + */ +export type LegacyThemeTypeInventory = [ + AliasColorTokens, + AppearanceOptions, + BaseShadowAliasTokens, + Color, + FabricWebPalette, + FontDynamicTypeRamp, + FontFamilies, + FontFamily, + FontFamilyValue, + FontSize, + FontSizeValuePoints, + FontSizes, + FontWeight, + FontWeightValue, + FontWeights, + OfficePalette, + OnThemeChange, + LegacySourceOnThemeChange, + Palette, + PaletteBackgroundColors, + PaletteTextColors, + PartialPalette, + PartialShadowDefinition, + PartialTheme, + PartialTypography, + ShadowToken, + ShadowValue, + Spacing, + TextStyling, + Theme, + ThemeColorDefinition, + ThemeOptions, + ThemeProviderProps, + ThemeRecipe<Theme, PartialTheme>, + LegacySourceThemeRecipe<Theme, PartialTheme>, + ThemeShadowDefinition, + ThemeTransform<Theme, PartialTheme>, + Typography, + Variant, + VariantValue, + Variants, + ThemeFromFlexTokensOptions, +]; + +export type LegacyStylingTypeInventory = [ + FontDecorationTokens, + FontStyleTokens, + FontTokens, + FontVariantTokens, + IBackgroundColorTokens, + IBorderTokens, + IColorTokens, + IForegroundColorTokens, + IShadowTokens, + LayoutTokens, + LookupThemePart<Theme>, + OperationSet<object, Theme>, + StyleFactoryFunction<object, object, Theme>, + StyleFactoryFunctionRaw<object, object, Theme>, + StyleFactoryOperation<object, Theme>, + TokenBuilder<object, TextStyle>, + NamedStyles<{ root: object }>, +]; + +// The root and legacy entry points keep their distinct meanings for these names. +export type RootTextAttributeInventory = [RootFontSize, RootFontWeight]; + +// External code declares three-field appearance literals and must keep compiling. +const legacyAppearance: ResolvedThemeAppearance = { + colorScheme: 'dark', + contrast: 'standard', + interfaceLevel: 'base', +}; +const rootAppearance: RootResolvedThemeAppearance = { + colorScheme: 'light', + contrast: 'highContrast', + interfaceLevel: 'elevated', +}; +const rootAppearanceOptions: RootThemeAppearanceOptions = { colorScheme: 'system', contrast: 'standard' }; +const fallbackAppearance: Partial<ResolvedThemeAppearance> = { colorScheme: 'dark' }; + +function externalAppearanceKey(appearance: ResolvedThemeAppearance): string { + return themeAppearanceKey(appearance); +} + +function appearanceFromState(state: ThemeState): ResolvedThemeAppearance { + return state.appearance; +} + +const legacyTransform: ThemeTransform<Theme, PartialTheme> = (parent: Theme, appearance?: ResolvedThemeAppearance) => ({ + colors: { bodyText: appearance?.colorScheme === 'dark' ? parent.colors.bodyText : '#010203' }, +}); + +describe('legacy compatibility types', () => { + it('accepts three-field appearance values at every legacy-facing boundary', () => { + expect(externalAppearanceKey(legacyAppearance)).toBe('dark|standard|base'); + expect(themeAppearanceKey(rootAppearance)).toBe('light|highContrast|elevated'); + expect(resolveThemeAppearance(rootAppearanceOptions, {}, fallbackAppearance).resolved).toEqual( + expect.objectContaining({ colorScheme: 'dark', contrast: 'standard', interfaceLevel: 'base' }), + ); + + const legacyTheme = fluentDarkTheme; + expect(themeFromFlexTokens(flexTokensFromTheme(legacyTheme), legacyAppearance).host.appearance).toBe('dark'); + + const reference = new ThemeReference(legacyTheme, legacyTransform); + expect(reference.resolveTheme(legacyAppearance).colors.bodyText).toBe(legacyTheme.colors.bodyText); + expect(reference.resolveTheme(rootAppearance).colors.bodyText).toBe('#010203'); + expect(appearanceFromState).toEqual(expect.any(Function)); + }); + + it('shares legacy constructors and contexts across entry points', () => { + expect(LegacySourceThemeReference).toBe(ThemeReference); + expect(ThemeContext).toBeDefined(); + expect(ThemeProvider).toEqual(expect.any(Function)); + expect(useTheme).toEqual(expect.any(Function)); + expect(useThemeState).toEqual(expect.any(Function)); + }); + + it('keeps legacy utility and token builder values', () => { + for (const value of [ + getCurrentAppearance, + isHighContrast, + mapFontPipelineToTheme, + mapPipelineToShadow, + mapPipelineToTheme, + setIsHighContrast, + getAliasTokens, + getShadowTokens, + themedStyleSheet, + backgroundColorTokens, + borderStyles, + borderTokens, + colorTokens, + fontStyles, + foregroundColorTokens, + getPaletteFromTheme, + layoutStyles, + layoutTokens, + shadowStyles, + shadowTokens, + styleFunction, + textTokens, + tokenBuilder, + ]) { + expect(value).toBeDefined(); + } + expect(globalTokens).toBeDefined(); + expect(hcAliasTokens).toBeDefined(); + }); +}); diff --git a/packages/agentic/design/src/test/compatibility/fingerprint.ts b/packages/agentic/design/src/test/compatibility/fingerprint.ts new file mode 100644 index 00000000000..6d869658c3e --- /dev/null +++ b/packages/agentic/design/src/test/compatibility/fingerprint.ts @@ -0,0 +1,71 @@ +import { createHash } from 'node:crypto'; + +import type { Theme } from '../../fluent/types/Theme.types'; +import type { FlexTokens } from '../../flex/tokens.types'; + +type EffectiveColor = { rest: unknown; hover: unknown; pressed: unknown }; + +function sortValue(value: unknown): unknown { + if (Array.isArray(value)) { + return value.map(sortValue); + } + if (typeof value === 'function') { + return '[function]'; + } + if (value && typeof value === 'object') { + const record = value as Record<string, unknown>; + return Object.fromEntries( + Object.keys(record) + .sort() + .map((key) => [key, sortValue(record[key])]), + ); + } + return value; +} + +/** + * A short, order-independent digest of a JSON-compatible value. Snapshots of + * these digests detect any value change without checking in large payloads. + */ +export function fingerprint(value: unknown): string { + return createHash('sha256') + .update(JSON.stringify(sortValue(value)) ?? 'undefined') + .digest('hex') + .slice(0, 16); +} + +/** + * The color values a consumer observes for each token and interaction state, + * independent of how the token representation stores omitted states. + */ +export function effectiveFlexColors(color: FlexTokens['color']): Record<string, EffectiveColor> { + const result: Record<string, EffectiveColor> = {}; + for (const name of Object.keys(color).sort()) { + const { rest, hover, pressed } = color[name as keyof typeof color]; + result[name] = { rest, hover, pressed }; + } + return result; +} + +export function flexTokenFingerprints(tokens: FlexTokens): Record<string, string | number> { + const { color, ...groups } = tokens; + const colors = effectiveFlexColors(color); + const result: Record<string, string | number> = { + colorCount: Object.keys(colors).length, + color: fingerprint(colors), + }; + for (const group of Object.keys(groups).sort()) { + result[group] = fingerprint(groups[group as keyof typeof groups]); + } + return result; +} + +export function themeFingerprints(theme: Theme): Record<string, string | number> { + const result: Record<string, string | number> = { + colorCount: Object.keys(theme.colors).length, + }; + for (const section of Object.keys(theme).sort()) { + result[section] = fingerprint(theme[section as keyof Theme]); + } + return result; +} diff --git a/packages/agentic/design/src/test/compatibility/importBoundaries.test.ts b/packages/agentic/design/src/test/compatibility/importBoundaries.test.ts new file mode 100644 index 00000000000..36094087658 --- /dev/null +++ b/packages/agentic/design/src/test/compatibility/importBoundaries.test.ts @@ -0,0 +1,319 @@ +import { parse } from '@babel/parser'; +import fs from 'node:fs'; +import path from 'node:path'; + +type Statement = ReturnType<typeof parse>['program']['body'][number]; + +const srcRoot = path.resolve(__dirname, '../..'); +const platformSuffixes = ['android', 'ios', 'macos', 'native', 'win32', 'windows']; + +type ImportEdge = { specifier: string; typeOnly: boolean }; + +function toSrcPath(file: string): string { + return path.relative(srcRoot, file).split(path.sep).join('/'); +} + +const statementCache = new Map<string, Statement[]>(); + +function readStatements(file: string): Statement[] { + let statements = statementCache.get(file); + if (!statements) { + const plugins: ('typescript' | 'jsx')[] = file.endsWith('.tsx') ? ['typescript', 'jsx'] : ['typescript']; + statements = parse(fs.readFileSync(file, 'utf8'), { sourceType: 'module', plugins }).program.body; + statementCache.set(file, statements); + } + return statements; +} + +function readImports(file: string): ImportEdge[] { + const edges: ImportEdge[] = []; + for (const statement of readStatements(file)) { + if (statement.type === 'ImportDeclaration') { + const typeOnly = + statement.importKind === 'type' || + (statement.specifiers.length > 0 && + statement.specifiers.every((specifier) => specifier.type === 'ImportSpecifier' && specifier.importKind === 'type')); + edges.push({ specifier: statement.source.value, typeOnly }); + } else if (statement.type === 'ExportNamedDeclaration' && statement.source) { + const typeOnly = + statement.exportKind === 'type' || + (statement.specifiers.length > 0 && + statement.specifiers.every((specifier) => specifier.type === 'ExportSpecifier' && specifier.exportKind === 'type')); + edges.push({ specifier: statement.source.value, typeOnly }); + } else if (statement.type === 'ExportAllDeclaration') { + edges.push({ specifier: statement.source.value, typeOnly: statement.exportKind === 'type' }); + } + } + return edges; +} + +function isFile(candidate: string): boolean { + return fs.existsSync(candidate) && fs.statSync(candidate).isFile(); +} + +/** Resolve a relative specifier to every platform file Metro or esbuild could select. */ +function resolveRelative(fromFile: string, specifier: string): string[] { + const base = path.resolve(path.dirname(fromFile), specifier); + const exact = [base, `${base}.ts`, `${base}.tsx`, `${base}.json`].find(isFile); + const variants = platformSuffixes.flatMap((platform) => [`${base}.${platform}.ts`, `${base}.${platform}.tsx`]).filter(isFile); + const resolved = exact ? [exact, ...variants] : variants; + if (resolved.length === 0) { + const index = [path.join(base, 'index.ts'), path.join(base, 'index.tsx')].find(isFile); + if (index) { + resolved.push(index); + } + } + if (resolved.length === 0) { + throw new Error(`Cannot resolve "${specifier}" from ${toSrcPath(fromFile)}.`); + } + return resolved; +} + +function runtimeGraph(entry: string): Set<string> { + const reached = new Set<string>(); + const pending = [path.join(srcRoot, entry)]; + while (pending.length > 0) { + const file = pending.pop() as string; + const srcPath = toSrcPath(file); + if (reached.has(srcPath)) { + continue; + } + reached.add(srcPath); + if (file.endsWith('.json')) { + continue; + } + for (const edge of readImports(file)) { + if (!edge.typeOnly && edge.specifier.startsWith('.')) { + pending.push(...resolveRelative(file, edge.specifier)); + } + } + } + return reached; +} + +function listSourceFiles(dir: string): string[] { + return fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => { + const file = path.join(dir, entry.name); + if (entry.isDirectory()) { + return listSourceFiles(file); + } + return /\.tsx?$/.test(entry.name) ? [file] : []; + }); +} + +function isTestSource(srcPath: string): boolean { + return srcPath.startsWith('test/') || srcPath.includes('/__tests__/') || /\.test(\.[a-z0-9]+)?\.tsx?$/.test(srcPath); +} + +function reachedUnder(graph: Set<string>, prefix: string): string[] { + return [...graph].filter((file) => file.startsWith(prefix)).sort(); +} + +function isTypeOnlyStatement(statement: Statement): boolean { + switch (statement.type) { + case 'TSTypeAliasDeclaration': + case 'TSInterfaceDeclaration': + return true; + case 'ImportDeclaration': + case 'ExportNamedDeclaration': + case 'ExportAllDeclaration': + if (statement.type === 'ExportNamedDeclaration' && statement.declaration) { + return statement.declaration.type === 'TSTypeAliasDeclaration' || statement.declaration.type === 'TSInterfaceDeclaration'; + } + return statement.type === 'ImportDeclaration' ? statement.importKind === 'type' : statement.exportKind === 'type'; + default: + return false; + } +} + +const productionFiles = listSourceFiles(srcRoot).filter((file) => !isTestSource(toSrcPath(file))); + +describe('production code never depends on test collateral', () => { + it('resolves test-only imports when they exist', () => { + const testImporter = path.join(srcRoot, 'fluent/__tests__/themeReference.test.ts'); + const resolvedTestImports = readImports(testImporter) + .filter((edge) => edge.specifier.startsWith('.')) + .flatMap((edge) => resolveRelative(testImporter, edge.specifier).map(toSrcPath)); + expect(resolvedTestImports).toContain('test/index.ts'); + }); + + it('has no production import of src/test or the testing entry point', () => { + expect(productionFiles.length).toBeGreaterThan(50); + const violations = productionFiles.flatMap((file) => + readImports(file) + .filter((edge) => + edge.specifier.startsWith('.') + ? resolveRelative(file, edge.specifier).some((resolved) => toSrcPath(resolved).startsWith('test/')) + : edge.specifier === '@fluentui-react-native/design/testing', + ) + .map((edge) => `${toSrcPath(file)} -> ${edge.specifier}`), + ); + expect(violations).toEqual([]); + }); +}); + +describe('deprecated code stays behind its boundary', () => { + const deprecatedSpecifier = '@fluentui-react-native/design/deprecated'; + const tokenPackagePrefix = '@fluentui-react-native/design-tokens-'; + const nonDeprecatedProductionFiles = productionFiles.filter((file) => !toSrcPath(file).startsWith('deprecated/')); + + function importsTokenPackage(edge: ImportEdge): boolean { + return edge.specifier.startsWith(tokenPackagePrefix); + } + + it('detects the deprecated token payloads', () => { + expect(readImports(path.join(srcRoot, 'deprecated/tokens/getTokens.ts')).some(importsTokenPackage)).toBe(true); + expect(nonDeprecatedProductionFiles.length).toBeGreaterThan(50); + }); + + it('has no production import of src/deprecated or the deprecated entry point outside src/deprecated', () => { + const violations = nonDeprecatedProductionFiles.flatMap((file) => + readImports(file) + .filter((edge) => + edge.specifier.startsWith('.') + ? resolveRelative(file, edge.specifier).some((resolved) => toSrcPath(resolved).startsWith('deprecated/')) + : edge.specifier === deprecatedSpecifier || edge.specifier.startsWith(`${deprecatedSpecifier}/`), + ) + .map((edge) => `${toSrcPath(file)} -> ${edge.specifier}`), + ); + expect(violations).toEqual([]); + }); + + it('keeps the Fluent 2 token packages out of production code outside src/deprecated', () => { + const violations = nonDeprecatedProductionFiles.flatMap((file) => + readImports(file) + .filter(importsTokenPackage) + .map((edge) => `${toSrcPath(file)} -> ${edge.specifier}`), + ); + expect(violations).toEqual([]); + }); + + it('keeps every production entry point free of deprecated code', () => { + const packageJson = jest.requireActual<{ exports: Record<string, string | { 'react-native': string }> }>('../../../package.json'); + const entries = Object.entries(packageJson.exports).flatMap(([subpath, conditions]) => + typeof conditions === 'string' || subpath === './deprecated' || subpath === './testing' + ? [] + : [conditions['react-native'].slice('./src/'.length)], + ); + expect(entries).toContain('fluent/compat/index.ts'); + for (const entry of entries) { + expect([entry, reachedUnder(runtimeGraph(entry), 'deprecated/')]).toEqual([entry, []]); + } + expect(reachedUnder(runtimeGraph('deprecated/index.ts'), 'deprecated/').length).toBeGreaterThan(1); + }); +}); + +describe('runtime graph ownership', () => { + const legacyThemingGraph = runtimeGraph('theming/index.ts'); + + it('detects the legacy projection and its Fluent base from the legacy theming entry', () => { + expect(legacyThemingGraph).toContain('fluent/useTheme.ts'); + expect(legacyThemingGraph).toContain('fluent/compat/themeFromFlexTokens.ts'); + expect(legacyThemingGraph).toContain('themes/fluent/selectFluentTheme.ts'); + expect(legacyThemingGraph).toContain('fluent/defaults/fluentTokens.generated.ts'); + }); + + it('keeps the modern root free of legacy Fluent runtime and test collateral', () => { + const rootGraph = runtimeGraph('index.ts'); + expect(rootGraph).toContain('flex/useThemeState.ts'); + expect(rootGraph).toContain('flex/flexThemeReference.ts'); + expect(rootGraph).toContain('flex/adapters/flexTokensFromTheme.ts'); + expect(rootGraph).toContain('flex/colors/interactionPolicy.ts'); + expect(rootGraph).toContain('color-lib/interaction.ts'); + expect(rootGraph).toContain('theming/ThemeProvider.tsx'); + expect(reachedUnder(rootGraph, 'fluent/')).toEqual([]); + expect(reachedUnder(rootGraph, 'test/')).toEqual([]); + }); + + it('keeps legacy theme runtime free of the Flex engine and color library', () => { + for (const entry of ['fluent/useTheme.ts', 'fluent/themeReference.ts', 'theming/ThemeProvider.tsx']) { + const graph = runtimeGraph(entry); + expect([entry, reachedUnder(graph, 'flex/')]).toEqual([entry, []]); + expect([entry, reachedUnder(graph, 'color-lib/')]).toEqual([entry, []]); + } + expect(runtimeGraph('theming/ThemedRoot.tsx')).toContain('flex/colors/interactionPolicy.ts'); + }); + + it('keeps the forward Theme adapter and its Fluent fallback free of the interaction engine', () => { + const adapterGraph = runtimeGraph('flex/adapters/flexTokensFromTheme.ts'); + expect(adapterGraph).toContain('flex/adapters/fluentFallbackTokens.ts'); + expect(adapterGraph).not.toContain('flex/colors/interactionPolicy.ts'); + expect(adapterGraph).not.toContain('flex/defaults/defaultTokens.ts'); + expect(reachedUnder(adapterGraph, 'color-lib/')).toEqual([]); + }); + + it('keeps the color library free of token, theme, and test ownership', () => { + const colorLibGraph = runtimeGraph('color-lib/index.ts'); + expect(colorLibGraph).toContain('color-lib/interaction.ts'); + expect([...colorLibGraph].filter((file) => !file.startsWith('color-lib/')).sort()).toEqual([]); + }); + + it('keeps the shared styling entry free of legacy Fluent runtime', () => { + const stylingGraph = runtimeGraph('styling/index.ts'); + expect(stylingGraph).toContain('flex/styling/colorStyles.ts'); + expect(reachedUnder(stylingGraph, 'fluent/')).toEqual([]); + expect(reachedUnder(stylingGraph, 'test/')).toEqual([]); + }); + + it('keeps the legacy-source entry free of the projection and legacy payloads', () => { + const legacySourceGraph = runtimeGraph('fluent/legacySource.ts'); + expect(legacySourceGraph).toContain('fluent/themeReference.ts'); + expect(reachedUnder(legacySourceGraph, 'fluent/compat/')).toEqual([]); + expect(reachedUnder(legacySourceGraph, 'deprecated/')).toEqual([]); + }); + + it('keeps the themes entry free of the legacy projection, payloads, and test collateral', () => { + const themesGraph = runtimeGraph('themes/index.ts'); + expect(themesGraph).toContain('themes/fluent/fluentTheme.ts'); + expect(themesGraph).toContain('themes/flex/flexWarmTheme.ts'); + expect(themesGraph).not.toContain('fluent/useTheme.ts'); + for (const prefix of ['test/', 'fluent/compat/', 'deprecated/']) { + expect([prefix, reachedUnder(themesGraph, prefix)]).toEqual([prefix, []]); + } + }); + + it('keeps the Fluent themes on generated tokens and the legacy source, free of the Flex engine', () => { + for (const entry of [ + 'themes/fluent/fluentLightTheme.ts', + 'themes/fluent/fluentDarkTheme.ts', + 'themes/fluent/fluentHcTheme.ts', + 'themes/fluent/fluentTheme.ts', + ]) { + const graph = runtimeGraph(entry); + expect(graph).toContain('fluent/defaults/fluentTokens.generated.ts'); + expect(graph).toContain('tokens/global.generated.ts'); + for (const prefix of ['flex/', 'color-lib/']) { + expect([entry, prefix, reachedUnder(graph, prefix)]).toEqual([entry, prefix, []]); + } + } + expect(runtimeGraph('themes/fluent/fluentTheme.ts')).toContain('fluent/themeReference.ts'); + expect(runtimeGraph('themes/fluent/fluentHcTheme.ts')).toContain('fluent/themeReference.ts'); + }); + + it('keeps the Flex themes on the generated Flex defaults, free of legacy Fluent runtime', () => { + for (const entry of ['themes/flex/flexTheme.ts', 'themes/flex/flexWarmTheme.ts']) { + const graph = runtimeGraph(entry); + expect(graph).toContain('flex/defaults/defaultTokens.generated.ts'); + expect([entry, reachedUnder(graph, 'fluent/')]).toEqual([entry, []]); + expect(graph).not.toContain('color-lib/compositing.ts'); + } + }); +}); + +describe('shared types', () => { + it('contain only type declarations and type-only imports', () => { + const typeFiles = [...listSourceFiles(path.join(srcRoot, 'types')), path.join(srcRoot, 'flex/themeState.types.ts')]; + expect(typeFiles.map(toSrcPath).sort()).toEqual(expect.arrayContaining(['types/appearance.types.ts', 'flex/themeState.types.ts'])); + const runtimeStatements = typeFiles.flatMap((file) => + readStatements(file) + .filter((statement) => !isTypeOnlyStatement(statement)) + .map((statement) => `${toSrcPath(file)}:${statement.loc?.start.line} ${statement.type}`), + ); + expect(runtimeStatements).toEqual([]); + }); + + it('reject runtime statements', () => { + const runtimeModule = path.join(srcRoot, 'theming/appearance.ts'); + expect(readStatements(runtimeModule).some((statement) => !isTypeOnlyStatement(statement))).toBe(true); + }); +}); diff --git a/packages/agentic/design/src/test/fixtures/interactionColors.ts b/packages/agentic/design/src/test/fixtures/interactionColors.ts new file mode 100644 index 00000000000..5b9e5eaed53 --- /dev/null +++ b/packages/agentic/design/src/test/fixtures/interactionColors.ts @@ -0,0 +1,63 @@ +import type { ColorValue } from 'react-native'; + +import { getInteractionColor } from '../../color-lib/interaction'; +import type { ColorMode, InteractionColorDiagnostic, InteractionColorState } from '../../color-lib/types'; +import { getInteractionCompositing, getInteractionDirection, INTERACTIVE_COLOR_TOKENS } from '../../flex/colors/interactiveTokens'; +import type { InteractiveColorToken } from '../../flex/colors/interactiveTokens'; +import type { SemanticColors, SemanticColorTokenValues } from '../../flex/tokens.types'; +import type { ColorTone } from '../../types/appearance.types'; + +export interface InteractionAuditDiagnostic extends InteractionColorDiagnostic { + readonly token: InteractiveColorToken; +} + +export type InteractionColorOverrides = Partial<Record<InteractiveColorToken, ColorValue>>; + +export interface InteractionOverridesResult { + readonly overrides: InteractionColorOverrides; + readonly diagnostics: readonly InteractionAuditDiagnostic[]; +} + +/** + * Test-only bulk generation of one interaction state for every interactive + * token. Unlike the Flex runtime policy, unresolvable rest values are reported + * for audits instead of falling back to rest. + */ +export function getInteractionColorOverrides( + colors: SemanticColorTokenValues, + mode: ColorMode, + state: InteractionColorState, + colorTone: ColorTone = 'cool', +): InteractionOverridesResult { + const overrides: InteractionColorOverrides = {}; + const diagnostics: InteractionAuditDiagnostic[] = []; + + for (const token of INTERACTIVE_COLOR_TOKENS) { + const result = getInteractionColor(colors[token], mode, state, { + colorTone, + direction: getInteractionDirection(token), + compositing: getInteractionCompositing(token), + }); + if (result.status === 'derived') { + overrides[token] = result.value; + } else { + diagnostics.push({ ...result.diagnostic, token }); + } + } + + return { overrides, diagnostics }; +} + +/** + * One state of every resolved color, keyed by token. + */ +export function stateColorValues(colors: SemanticColors, state: 'rest' | InteractionColorState): SemanticColorTokenValues { + return Object.fromEntries(Object.entries(colors).map(([name, color]) => [name, color[state]])) as SemanticColorTokenValues; +} + +/** + * The rest value of every resolved color, keyed by token. + */ +export function restColorValues(colors: SemanticColors): SemanticColorTokenValues { + return stateColorValues(colors, 'rest'); +} diff --git a/packages/agentic/design/src/testing/mockTheme.ts b/packages/agentic/design/src/test/fixtures/mockTheme.ts similarity index 99% rename from packages/agentic/design/src/testing/mockTheme.ts rename to packages/agentic/design/src/test/fixtures/mockTheme.ts index 5fc3e4b206d..5dc943d8ca1 100644 --- a/packages/agentic/design/src/testing/mockTheme.ts +++ b/packages/agentic/design/src/test/fixtures/mockTheme.ts @@ -1,4 +1,4 @@ -import type { Theme } from '../theming'; +import type { Theme } from '../../fluent/types/Theme.types'; const black = 'black'; const neutralDark = '#201f1e'; diff --git a/packages/agentic/design/src/testing/color-validation/x3InteractionConformance.ts b/packages/agentic/design/src/test/fixtures/x3InteractionConformance.ts similarity index 84% rename from packages/agentic/design/src/testing/color-validation/x3InteractionConformance.ts rename to packages/agentic/design/src/test/fixtures/x3InteractionConformance.ts index 71cb11f9ced..bcb103f2b08 100644 --- a/packages/agentic/design/src/testing/color-validation/x3InteractionConformance.ts +++ b/packages/agentic/design/src/test/fixtures/x3InteractionConformance.ts @@ -1,4 +1,4 @@ -import type { InteractiveColorToken } from '../../color-lib'; +import type { InteractiveColorToken } from '../../flex/colors/interactiveTokens'; export type InteractionConformanceVector = readonly [ lightRest: string, @@ -10,8 +10,9 @@ export type InteractionConformanceVector = readonly [ ]; /** - * Test fixture with base and interaction fallback values from the pinned x3 source commit. - * Each row covers hover and pressed in both light and dark modes. + * Cool rest and interaction fallback values from x3-design/fluent-design@206e890b + * (`semantic-{light,dark}.css` and `interaction-fallback-{light,dark}.css`). + * Each row covers rest, hover, and pressed in light and then dark. */ export const x3InteractionConformance = { surfaceNeutralFarther: ['#ebebeb', '#e1e1e1', '#d7d7d7', '#1b1b1b', '#2f2f2f', '#454545'], @@ -75,8 +76,8 @@ export const x3InteractionConformance = { foregroundSuccessOnloud: ['#ffffff', '#ffffff', '#ffffff', '#000000db', '#000000db', '#000000db'], } as const satisfies Record<InteractiveColorToken, InteractionConformanceVector>; -/** Base and generated interaction values for the pinned Bebop Warm theme. */ -export const x3BebopWarmInteractionConformance = { +/** Warm rest and interaction fallback values from the same pinned `warm/` stylesheets. */ +export const x3WarmInteractionConformance = { surfaceNeutralFarther: ['#f0eae5', '#e8e0d9', '#dfd6ce', '#1e1916', '#342d29', '#4b423d'], surfaceNeutralFar: ['#faf4f0', '#f2eae4', '#e9dfd9', '#231e1a', '#38312b', '#4d453e'], surfaceNeutralNear: ['#f6f1ec', '#ede7e0', '#e5ddd4', '#1c1714', '#322b27', '#4b413c'], @@ -139,60 +140,60 @@ export const x3BebopWarmInteractionConformance = { } as const satisfies Record<InteractiveColorToken, InteractionConformanceVector>; /** - * The generated x3 table routes these entries through its separately scoped - * Bebop Warm path. `defaultValue` is the result of the default algorithm - * requested by #4268; `warmValue` is retained to make every table deviation - * explicit. + * Cool table states the cool interaction policy does not reproduce. The x3 + * generator routes these entries through its warm path, so the default cool + * description authors `sourceValue` explicitly; `derivedValue` is what the + * cool policy computes from rest. */ -export const x3WarmVariantDeviations = { +export const x3CoolExplicitStates = { 'backgroundNeutralTranslucent.hover.light': { - warmValue: '#d8d8d88a', - defaultValue: '#dfdfdf8a', - reason: 'The warm path composites this translucent background against a reference surface before shifting it.', + sourceValue: '#d8d8d88a', + derivedValue: '#dfdfdf8a', + reason: 'The source composites this translucent background against a reference surface before shifting it.', }, 'backgroundNeutralTranslucent.pressed.light': { - warmValue: '#cacaca94', - defaultValue: '#d5d5d594', - reason: 'The warm path composites this translucent background against a reference surface before shifting it.', + sourceValue: '#cacaca94', + derivedValue: '#d5d5d594', + reason: 'The source composites this translucent background against a reference surface before shifting it.', }, 'backgroundNeutralTranslucent.hover.dark': { - warmValue: '#56565688', - defaultValue: '#47474788', - reason: 'The warm path composites this translucent background against a reference surface before shifting it.', + sourceValue: '#56565688', + derivedValue: '#47474788', + reason: 'The source composites this translucent background against a reference surface before shifting it.', }, 'backgroundNeutralTranslucent.pressed.dark': { - warmValue: '#6d6d6d8f', - defaultValue: '#5353538f', - reason: 'The warm path composites this translucent background against a reference surface before shifting it.', + sourceValue: '#6d6d6d8f', + derivedValue: '#5353538f', + reason: 'The source composites this translucent background against a reference surface before shifting it.', }, 'strokeNeutralSoft.hover.light': { - warmValue: '#02020277', - defaultValue: '#00000077', - reason: 'The warm path adds chroma while the default algorithm preserves chroma.', + sourceValue: '#02020277', + derivedValue: '#00000077', + reason: 'The source adds chroma while the cool policy preserves chroma.', }, 'strokeNeutralSoft.pressed.light': { - warmValue: '#04040481', - defaultValue: '#00000081', - reason: 'The warm path adds chroma while the default algorithm preserves chroma.', + sourceValue: '#04040481', + derivedValue: '#00000081', + reason: 'The source adds chroma while the cool policy preserves chroma.', }, 'strokeNeutralSubtle.pressed.light': { - warmValue: '#05050535', - defaultValue: '#00000035', - reason: 'The warm path adds chroma while the default algorithm preserves chroma.', + sourceValue: '#05050535', + derivedValue: '#00000035', + reason: 'The source adds chroma while the cool policy preserves chroma.', }, 'strokeBrandSoft.hover.light': { - warmValue: '#02020277', - defaultValue: '#00000077', - reason: 'The warm path adds chroma while the default algorithm preserves chroma.', + sourceValue: '#02020277', + derivedValue: '#00000077', + reason: 'The source adds chroma while the cool policy preserves chroma.', }, 'strokeBrandSoft.pressed.light': { - warmValue: '#04040481', - defaultValue: '#00000081', - reason: 'The warm path adds chroma while the default algorithm preserves chroma.', + sourceValue: '#04040481', + derivedValue: '#00000081', + reason: 'The source adds chroma while the cool policy preserves chroma.', }, 'strokeBrandSubtle.pressed.light': { - warmValue: '#05050535', - defaultValue: '#00000035', - reason: 'The warm path adds chroma while the default algorithm preserves chroma.', + sourceValue: '#05050535', + derivedValue: '#00000035', + reason: 'The source adds chroma while the cool policy preserves chroma.', }, } as const; diff --git a/packages/agentic/design/src/testing/index.ts b/packages/agentic/design/src/test/index.ts similarity index 82% rename from packages/agentic/design/src/testing/index.ts rename to packages/agentic/design/src/test/index.ts index 7ee6cf4c010..6e66d4c4727 100644 --- a/packages/agentic/design/src/testing/index.ts +++ b/packages/agentic/design/src/test/index.ts @@ -1,5 +1,5 @@ export { defaultResolvedThemeAppearance } from '../theming/appearance'; -export { defaultFlexTokens } from '../tokens/defaultTokens'; +export { defaultFlexTokens } from '../flex/defaults/defaultTokens'; export type { ContrastColorDiagnostic, ContrastColorToken, @@ -12,4 +12,4 @@ export type { export { MODE_SURFACE, WCAG } from './color-validation/constants'; export { PAIRINGS } from './color-validation/pairings'; export { getContrastFailures, getUnresolvableContrastPairs, validateContrastPairs } from './color-validation/validation'; -export { mockTheme } from './mockTheme'; +export { mockTheme } from './fixtures/mockTheme'; diff --git a/packages/agentic/design/src/themes/flex/flexTheme.ts b/packages/agentic/design/src/themes/flex/flexTheme.ts new file mode 100644 index 00000000000..fee34cc8af7 --- /dev/null +++ b/packages/agentic/design/src/themes/flex/flexTheme.ts @@ -0,0 +1,7 @@ +import { defaultFlexTokenDescription } from '../../flex/defaults/defaultTokens'; +import type { FlexThemeDescription } from '../../flex/themeState.types'; + +/** + * The cool-tone Flex theme: the x3 cool default tokens for light and dark. + */ +export const flexTheme: FlexThemeDescription = { tokens: defaultFlexTokenDescription, colorTone: 'cool' }; diff --git a/packages/agentic/design/src/themes/flex/flexThemes.test.tsx b/packages/agentic/design/src/themes/flex/flexThemes.test.tsx new file mode 100644 index 00000000000..3f5667e89ba --- /dev/null +++ b/packages/agentic/design/src/themes/flex/flexThemes.test.tsx @@ -0,0 +1,50 @@ +import { act, create } from 'react-test-renderer'; + +import { FlexThemeReference } from '../../flex/flexThemeReference'; +import type { ThemeState } from '../../flex/themeState.types'; +import { useThemeState } from '../../flex/useThemeState'; +import { ThemeProvider } from '../../theming/ThemeProvider'; +import type { ColorTone } from '../../types/appearance.types'; +import { flexTheme, flexWarmTheme } from '../index'; + +describe('Flex themes', () => { + it.each([ + ['flexTheme', flexTheme, 'cool'], + ['flexWarmTheme', flexWarmTheme, 'warm'], + ] as const)('%s reproduces the package defaults for its tone in light and dark', (_name, theme, colorTone) => { + const reference = new FlexThemeReference({ base: theme }); + const defaults = new FlexThemeReference(); + + for (const colorScheme of ['light', 'dark'] as const) { + const appearance = { colorScheme, contrast: 'standard', interfaceLevel: 'base', colorTone } as const; + expect(reference.resolveFlexTokens(appearance)).toEqual(defaults.resolveFlexTokens(appearance)); + } + }); + + it('makes a reference built on flexWarmTheme warm until a provider requests another tone', () => { + const reference = new FlexThemeReference({ base: flexWarmTheme }); + const seen: ThemeState[] = []; + const Probe = () => { + seen.push(useThemeState()); + return null; + }; + const render = (colorTone?: ColorTone) => ( + <ThemeProvider theme={reference} appearance={colorTone ? { colorScheme: 'light', colorTone } : { colorScheme: 'light' }}> + <Probe /> + </ThemeProvider> + ); + let component!: ReturnType<typeof create>; + + act(() => { + component = create(render()); + }); + expect(seen.at(-1)?.appearance.colorTone).toBe('warm'); + expect(seen.at(-1)?.tokens.color.surfaceNeutralFarther.rest).toBe('#f0eae5'); + + act(() => component.update(render('cool'))); + expect(seen.at(-1)?.appearance.colorTone).toBe('cool'); + expect(seen.at(-1)?.tokens.color.surfaceNeutralFarther.rest).toBe('#f0eae5'); + + act(() => component.unmount()); + }); +}); diff --git a/packages/agentic/design/src/themes/flex/flexWarmTheme.ts b/packages/agentic/design/src/themes/flex/flexWarmTheme.ts new file mode 100644 index 00000000000..615aef26272 --- /dev/null +++ b/packages/agentic/design/src/themes/flex/flexWarmTheme.ts @@ -0,0 +1,7 @@ +import { getDefaultFlexTokenDescription } from '../../flex/defaults/defaultTokens'; +import type { FlexThemeDescription } from '../../flex/themeState.types'; + +/** + * The warm-tone Flex theme: the x3 warm default tokens for light and dark. + */ +export const flexWarmTheme: FlexThemeDescription = { tokens: /* @__PURE__ */ getDefaultFlexTokenDescription('warm'), colorTone: 'warm' }; diff --git a/packages/agentic/design/src/themes/fluent/createFluentTheme.ts b/packages/agentic/design/src/themes/fluent/createFluentTheme.ts new file mode 100644 index 00000000000..2af9fe282a2 --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/createFluentTheme.ts @@ -0,0 +1,77 @@ +import { fontAliasTokens } from '../../fluent/defaults/fluentTokens.generated'; +import type { AliasColorTokens } from '../../fluent/types/Color.types'; +import type { BaseShadowAliasTokens } from '../../fluent/types/Shadow.types'; +import type { AppearanceOptions, Spacing, Theme } from '../../fluent/types/Theme.types'; +import { + fontFamilyBase, + fontFamilyMonospace, + fontFamilyNumeric, + fontSize100, + fontSize200, + fontSize300, + fontSize400, + fontSize500, + fontSize700, + fontSize900, + fontWeightRegular, + fontWeightSemibold, + size160, + size200, + size320, + size40, + size80, +} from '../../tokens/global.generated'; +import { legacyPaletteFromAliasColors } from './legacyPalette'; + +/** + * Assemble a complete legacy `Theme` from Fluent 2 tokens. The theme is a view over the generated alias colors, + * shadows and font variants plus global tokens, so nothing here is a hand-picked value. Appearance data is a + * parameter so that bundlers can drop the appearance a consumer never imports. + */ +export function createFluentTheme( + appearance: AppearanceOptions, + aliasColors: Required<AliasColorTokens>, + shadows: BaseShadowAliasTokens, +): Theme { + const spacing: Spacing = { + s2: `${size40}px`, + s1: `${size80}px`, + m: `${size160}px`, + l1: `${size200}px`, + l2: `${size320}px`, + }; + + return { + colors: { ...aliasColors, ...legacyPaletteFromAliasColors(aliasColors) }, + typography: { + // Fluent 2 defines no serif or cursive family, so those slots use the base family + families: { + primary: fontFamilyBase, + secondary: fontFamilyBase, + cursive: fontFamilyBase, + monospace: fontFamilyMonospace, + numeric: fontFamilyNumeric, + sansSerif: fontFamilyBase, + serif: fontFamilyBase, + }, + sizes: { + caption: fontSize100, + secondary: fontSize200, + body: fontSize300, + subheader: fontSize400, + header: fontSize500, + hero: fontSize700, + heroLarge: fontSize900, + }, + weights: { + regular: fontWeightRegular, + semiBold: fontWeightSemibold, + }, + variants: fontAliasTokens, + }, + components: {}, + shadows: { ...shadows }, + spacing, + host: { appearance }, + }; +} diff --git a/packages/agentic/design/src/themes/fluent/fluentDarkTheme.ts b/packages/agentic/design/src/themes/fluent/fluentDarkTheme.ts new file mode 100644 index 00000000000..6d997fc4855 --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/fluentDarkTheme.ts @@ -0,0 +1,8 @@ +import { darkAliasColors, darkShadows } from '../../fluent/defaults/fluentTokens.generated'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { createFluentTheme } from './createFluentTheme'; + +/** + * The Fluent dark theme, built from Fluent 2 alias and global tokens. + */ +export const fluentDarkTheme: Theme = /* @__PURE__ */ createFluentTheme('dark', darkAliasColors, darkShadows); diff --git a/packages/agentic/design/src/themes/fluent/fluentHcDarkTheme.ts b/packages/agentic/design/src/themes/fluent/fluentHcDarkTheme.ts new file mode 100644 index 00000000000..888d396b0fc --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/fluentHcDarkTheme.ts @@ -0,0 +1,8 @@ +import { hcDarkAliasColors, hcDarkShadows } from '../../fluent/defaults/fluentTokens.generated'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { createFluentTheme } from './createFluentTheme'; + +/** + * The Fluent high-contrast dark theme, built from Fluent 2 alias and global tokens. + */ +export const fluentHcDarkTheme: Theme = /* @__PURE__ */ createFluentTheme('highContrast', hcDarkAliasColors, hcDarkShadows); diff --git a/packages/agentic/design/src/themes/fluent/fluentHcLightTheme.ts b/packages/agentic/design/src/themes/fluent/fluentHcLightTheme.ts new file mode 100644 index 00000000000..7e8fe4488b3 --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/fluentHcLightTheme.ts @@ -0,0 +1,8 @@ +import { hcLightAliasColors, hcLightShadows } from '../../fluent/defaults/fluentTokens.generated'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { createFluentTheme } from './createFluentTheme'; + +/** + * The Fluent high-contrast light theme, built from Fluent 2 alias and global tokens. + */ +export const fluentHcLightTheme: Theme = /* @__PURE__ */ createFluentTheme('highContrast', hcLightAliasColors, hcLightShadows); diff --git a/packages/agentic/design/src/themes/fluent/fluentHcTheme.ts b/packages/agentic/design/src/themes/fluent/fluentHcTheme.ts new file mode 100644 index 00000000000..c339a73cf8e --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/fluentHcTheme.ts @@ -0,0 +1,15 @@ +import { ThemeReference } from '../../fluent/themeReference'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { fluentHcDarkTheme } from './fluentHcDarkTheme'; +import { fluentHcLightTheme } from './fluentHcLightTheme'; + +/** + * Theme source holding the Fluent high-contrast themes. It always resolves high contrast and follows the system color + * scheme reported by the React Native `Appearance` module; a `ThemeProvider` or `ThemedRoot` `appearance` prop + * overrides the color scheme. + */ +export const fluentHcTheme: ThemeReference = /* @__PURE__ */ new ThemeReference({ + base: {} as Theme, + appearance: { colorScheme: 'system', contrast: 'highContrast', interfaceLevel: 'system' }, + recipes: [(_parent, appearance) => (appearance?.colorScheme === 'dark' ? fluentHcDarkTheme : fluentHcLightTheme)], +}); diff --git a/packages/agentic/design/src/themes/fluent/fluentLightTheme.ts b/packages/agentic/design/src/themes/fluent/fluentLightTheme.ts new file mode 100644 index 00000000000..3ffb1bef34c --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/fluentLightTheme.ts @@ -0,0 +1,8 @@ +import { lightAliasColors, lightShadows } from '../../fluent/defaults/fluentTokens.generated'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { createFluentTheme } from './createFluentTheme'; + +/** + * The Fluent light theme, built from Fluent 2 alias and global tokens. + */ +export const fluentLightTheme: Theme = /* @__PURE__ */ createFluentTheme('light', lightAliasColors, lightShadows); diff --git a/packages/agentic/design/src/themes/fluent/fluentTheme.ts b/packages/agentic/design/src/themes/fluent/fluentTheme.ts new file mode 100644 index 00000000000..a66262bcbdf --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/fluentTheme.ts @@ -0,0 +1,15 @@ +import { ThemeReference } from '../../fluent/themeReference'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { selectFluentTheme } from './selectFluentTheme'; + +/** + * Theme source holding every Fluent theme. It follows the system appearance reported by the React Native `Appearance` + * module, and a `ThemeProvider` or `ThemedRoot` `appearance` prop overrides it. High contrast selects the + * high-contrast theme for the color scheme; elevated system settings resolve by color scheme until those Fluent themes + * exist. + */ +export const fluentTheme: ThemeReference = /* @__PURE__ */ new ThemeReference({ + base: {} as Theme, + appearance: { colorScheme: 'system', contrast: 'system', interfaceLevel: 'system' }, + recipes: [(_parent, appearance) => selectFluentTheme(appearance)], +}); diff --git a/packages/agentic/design/src/themes/fluent/fluentThemes.test.tsx b/packages/agentic/design/src/themes/fluent/fluentThemes.test.tsx new file mode 100644 index 00000000000..e27a0ec3626 --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/fluentThemes.test.tsx @@ -0,0 +1,203 @@ +import { isDeepStrictEqual } from 'node:util'; + +import { Appearance } from 'react-native'; + +import { act, create } from 'react-test-renderer'; + +import { + darkAliasColors, + darkShadows, + fontAliasTokens, + hcDarkAliasColors, + hcDarkShadows, + hcLightAliasColors, + hcLightShadows, + lightAliasColors, + lightShadows, +} from '../../fluent/defaults/fluentTokens.generated'; +import type { Theme } from '../../fluent/types/Theme.types'; +import { useTheme } from '../../fluent/useTheme'; +import { useThemeState } from '../../flex/useThemeState'; +import { ThemedRoot } from '../../theming/ThemedRoot'; +import { ThemeProvider } from '../../theming/ThemeProvider'; +import type { ResolvedThemeAppearance, ThemeAppearanceSource, ThemeAppearanceSourceSnapshot } from '../../types/appearance.types'; +import { fluentDarkTheme, fluentHcTheme, fluentLightTheme, fluentTheme } from '../index'; +import { fluentHcDarkTheme } from './fluentHcDarkTheme'; +import { fluentHcLightTheme } from './fluentHcLightTheme'; +import { selectFluentTheme } from './selectFluentTheme'; + +const standardLight = { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base' } as const; +const standardDark = { colorScheme: 'dark', contrast: 'standard', interfaceLevel: 'base' } as const; +const hcLight = { colorScheme: 'light', contrast: 'highContrast', interfaceLevel: 'base' } as const; +const hcDark = { colorScheme: 'dark', contrast: 'highContrast', interfaceLevel: 'base' } as const; + +const themes = [ + ['light', fluentLightTheme, lightAliasColors, lightShadows, 'light', standardLight], + ['dark', fluentDarkTheme, darkAliasColors, darkShadows, 'dark', standardDark], + ['high-contrast light', fluentHcLightTheme, hcLightAliasColors, hcLightShadows, 'highContrast', hcLight], + ['high-contrast dark', fluentHcDarkTheme, hcDarkAliasColors, hcDarkShadows, 'highContrast', hcDark], +] as const; + +function undefinedPaths(value: unknown, path = 'theme'): string[] { + if (value === undefined) { + return [path]; + } + if (typeof value !== 'object' || value === null) { + return []; + } + return Object.entries(value).flatMap(([key, child]) => undefinedPaths(child, `${path}.${key}`)); +} + +function createAppearanceSource(initial: ThemeAppearanceSourceSnapshot) { + let snapshot = initial; + const listeners = new Set<() => void>(); + return { + source: { + getSnapshot: () => snapshot, + subscribe: (listener) => { + listeners.add(listener); + return () => listeners.delete(listener); + }, + } satisfies ThemeAppearanceSource, + update(next: ThemeAppearanceSourceSnapshot) { + snapshot = next; + listeners.forEach((listener) => listener()); + }, + }; +} + +function ThemeProbe({ themes: seen }: { themes: Theme[] }) { + seen.push(useTheme()); + return null; +} + +describe.each(themes)('Fluent %s theme', (_name, theme, aliasColors, shadows, hostAppearance, appearance) => { + it('carries every Fluent 2 alias color unchanged for its host appearance', () => { + expect(theme.host.appearance).toBe(hostAppearance); + for (const [name, color] of Object.entries(aliasColors)) { + expect(theme.colors[name]).toBe(color); + } + }); + + it('draws every legacy palette color from the alias colors', () => { + const aliasValues = Object.values(aliasColors); + const invented = Object.entries(theme.colors) + .filter(([name]) => !(name in aliasColors)) + .filter(([, color]) => !aliasValues.some((alias) => isDeepStrictEqual(alias, color))) + .map(([name]) => name); + + expect(invented).toEqual([]); + }); + + it('takes shadows, font variants and spacing from Fluent 2 and global tokens', () => { + expect(theme.shadows).toEqual(shadows); + expect(theme.typography.variants).toBe(fontAliasTokens); + expect(theme.spacing).toEqual({ s2: '4px', s1: '8px', m: '16px', l1: '20px', l2: '32px' }); + }); + + it('defines no undefined values', () => { + expect(undefinedPaths(theme)).toEqual([]); + }); + + it('is the Fluent theme selected for its appearance', () => { + expect(selectFluentTheme(appearance)).toBe(theme); + expect(selectFluentTheme({ ...appearance, interfaceLevel: 'elevated' })).toBe(theme); + }); +}); + +describe('fluentTheme', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it.each([ + [standardLight, fluentLightTheme], + [standardDark, fluentDarkTheme], + [{ ...standardDark, interfaceLevel: 'elevated' }, fluentDarkTheme], + [hcLight, fluentHcLightTheme], + [hcDark, fluentHcDarkTheme], + [{ ...hcDark, interfaceLevel: 'elevated' }, fluentHcDarkTheme], + ] as [ResolvedThemeAppearance, Theme][])('resolves %o by contrast and color scheme', (appearance, theme) => { + expect(fluentTheme.resolveTheme(appearance).colors).toBe(theme.colors); + }); + + it('follows the system color scheme from the Appearance module', () => { + const colorScheme = jest.spyOn(Appearance, 'getColorScheme'); + + colorScheme.mockReturnValue('dark'); + expect(fluentTheme.theme).toBe(fluentDarkTheme); + colorScheme.mockReturnValue('light'); + expect(fluentTheme.theme).toBe(fluentLightTheme); + }); + + it('drives a ThemeProvider from the system appearance until an appearance prop overrides it', () => { + const appearance = createAppearanceSource({ colorScheme: 'light' }); + const seen: Theme[] = []; + const render = (appearanceProp?: { colorScheme: 'light' | 'dark' }) => ( + <ThemeProvider theme={fluentTheme} appearanceSource={appearance.source} appearance={appearanceProp}> + <ThemeProbe themes={seen} /> + </ThemeProvider> + ); + let component!: ReturnType<typeof create>; + + act(() => { + component = create(render()); + }); + expect(seen.at(-1)?.colors).toBe(fluentLightTheme.colors); + + act(() => appearance.update({ colorScheme: 'dark' })); + expect(seen.at(-1)?.colors).toBe(fluentDarkTheme.colors); + + act(() => appearance.update({ colorScheme: 'dark', contrast: 'highContrast' })); + expect(seen.at(-1)?.colors).toBe(fluentHcDarkTheme.colors); + + act(() => component.update(render({ colorScheme: 'light' }))); + expect(seen.at(-1)?.colors).toBe(fluentHcLightTheme.colors); + + act(() => component.unmount()); + }); + + it('feeds Flex consumers under a ThemedRoot from its alias colors', () => { + const appearance = createAppearanceSource({ colorScheme: 'dark' }); + const seen: unknown[] = []; + const Probe = () => { + seen.push(useThemeState().tokens.color.foregroundNeutralPrimary.rest); + return null; + }; + let component!: ReturnType<typeof create>; + + act(() => { + component = create( + <ThemedRoot theme={fluentTheme} appearanceSource={appearance.source}> + <Probe /> + </ThemedRoot>, + ); + }); + expect(seen.at(-1)).toBe(darkAliasColors.neutralForeground1); + + act(() => appearance.update({ colorScheme: 'light' })); + expect(seen.at(-1)).toBe(lightAliasColors.neutralForeground1); + + act(() => component.unmount()); + }); +}); + +describe('fluentHcTheme', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('resolves the high-contrast theme for the color scheme, whatever contrast is requested', () => { + expect(fluentHcTheme.resolveTheme(standardLight).colors).toBe(fluentHcLightTheme.colors); + expect(fluentHcTheme.resolveTheme(hcDark).colors).toBe(fluentHcDarkTheme.colors); + }); + + it('follows the system color scheme from the Appearance module', () => { + const colorScheme = jest.spyOn(Appearance, 'getColorScheme'); + + colorScheme.mockReturnValue('dark'); + expect(fluentHcTheme.theme).toBe(fluentHcDarkTheme); + colorScheme.mockReturnValue('light'); + expect(fluentHcTheme.theme).toBe(fluentHcLightTheme); + }); +}); diff --git a/packages/agentic/design/src/themes/fluent/legacyPalette.ts b/packages/agentic/design/src/themes/fluent/legacyPalette.ts new file mode 100644 index 00000000000..95ff24b9a47 --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/legacyPalette.ts @@ -0,0 +1,154 @@ +import type { AliasColorTokens, ControlColorTokens, PaletteBackgroundColors, PaletteTextColors } from '../../fluent/types/Color.types'; + +/** + * The legacy palette keys that every legacy `Theme` must define. + */ +export type LegacyPalette = PaletteTextColors & PaletteBackgroundColors & ControlColorTokens; + +/** + * Derive the legacy palette from Fluent 2 alias colors. Each legacy name points at the alias token the Fluent 2 + * components use for the same role, so the palette adds no color values of its own. The result is typed as complete, + * so a legacy key without a mapping fails to compile. + */ +export function legacyPaletteFromAliasColors(a: Required<AliasColorTokens>): LegacyPalette { + return { + // Text + bodyText: a.neutralForeground1, + bodyTextChecked: a.neutralForeground1Selected, + subText: a.neutralForeground2, + actionLink: a.neutralForeground1, + link: a.brandForegroundLink, + linkHovered: a.brandForegroundLinkHover, + linkPressed: a.brandForegroundLinkPressed, + disabledText: a.neutralForegroundDisabled, + disabledBodyText: a.neutralForegroundDisabled, + errorText: a.dangerForeground1, + inputText: a.neutralForeground1, + inputPlaceholderText: a.neutralForeground4, + buttonText: a.neutralForeground1, + buttonTextHovered: a.neutralForeground1Hover, + buttonTextChecked: a.neutralForeground1Selected, + buttonTextPressed: a.neutralForeground1Pressed, + buttonTextDisabled: a.neutralForegroundDisabled, + primaryButtonText: a.neutralForegroundOnBrand, + primaryButtonTextHovered: a.neutralForegroundOnBrandHover, + primaryButtonTextPressed: a.neutralForegroundOnBrandPressed, + primaryButtonTextDisabled: a.neutralForegroundDisabled, + + // Backgrounds, borders and dividers + background: a.neutralBackground1, + bodyStandoutBackground: a.neutralBackground2, + bodyFrameBackground: a.neutralBackground1, + bodyFrameDivider: a.neutralStroke2, + bodyDivider: a.neutralStroke2, + disabledBackground: a.neutralBackgroundDisabled, + focusBorder: a.strokeFocus2, + variantBorder: a.neutralStroke2, + inputBorder: a.neutralStroke1, + inputBackground: a.neutralBackground1, + inputFocusBorderAlt: a.compoundBrandStroke1, + buttonBackground: a.neutralBackground1, + buttonBackgroundChecked: a.neutralBackground1Selected, + buttonBackgroundHovered: a.neutralBackground1Hover, + buttonBackgroundDisabled: a.neutralBackgroundDisabled, + buttonBackgroundPressed: a.neutralBackground1Pressed, + buttonBorder: a.neutralStroke1, + buttonBorderFocused: a.strokeFocus2, + buttonBorderDisabled: a.neutralStrokeDisabled, + primaryButtonBackground: a.brandBackground, + primaryButtonBackgroundHovered: a.brandBackgroundHover, + primaryButtonBackgroundPressed: a.brandBackgroundPressed, + primaryButtonBackgroundDisabled: a.neutralBackgroundDisabled, + primaryButtonBorder: a.transparentStroke, + primaryButtonBorderFocused: a.strokeFocus2, + accentButtonBackground: a.brandBackground, + menuBackground: a.neutralBackground1, + menuDivider: a.neutralStroke2, + menuIcon: a.neutralForeground2, + menuItemBackgroundHovered: a.neutralBackground1Hover, + menuItemBackgroundPressed: a.neutralBackground1Pressed, + menuItemText: a.neutralForeground1, + menuItemTextHovered: a.neutralForeground1Hover, + listHeaderBackgroundHovered: a.neutralBackground1Hover, + listHeaderBackgroundPressed: a.neutralBackground1Pressed, + + // Default control. Focus keeps the hover fill and content with the focus stroke, as the Fluent 2 Button does. + defaultBackground: a.neutralBackground1, + defaultBorder: a.neutralStroke1, + defaultContent: a.neutralForeground1, + defaultIcon: a.neutralForeground1, + defaultHoveredBackground: a.neutralBackground1Hover, + defaultHoveredBorder: a.neutralStroke1Hover, + defaultHoveredContent: a.neutralForeground1Hover, + defaultHoveredIcon: a.neutralForeground1Hover, + defaultFocusedBackground: a.neutralBackground1Hover, + defaultFocusedBorder: a.strokeFocus2, + defaultFocusedContent: a.neutralForeground1Hover, + defaultFocusedIcon: a.neutralForeground1Hover, + defaultPressedBackground: a.neutralBackground1Pressed, + defaultPressedBorder: a.neutralStroke1Pressed, + defaultPressedContent: a.neutralForeground1Pressed, + defaultPressedIcon: a.neutralForeground1Pressed, + defaultDisabledBackground: a.neutralBackgroundDisabled, + defaultDisabledBorder: a.neutralStrokeDisabled, + defaultDisabledContent: a.neutralForegroundDisabled, + defaultDisabledIcon: a.neutralForegroundDisabled, + + // Ghost control, the Fluent 2 subtle appearance + ghostBackground: a.subtleBackground, + ghostBorder: a.transparentStroke, + ghostContent: a.neutralForeground1, + ghostIcon: a.neutralForeground1, + ghostHoveredBackground: a.subtleBackgroundHover, + ghostHoveredBorder: a.transparentStroke, + ghostHoveredContent: a.neutralForeground1Hover, + ghostHoveredIcon: a.neutralForeground1Hover, + ghostFocusedBackground: a.subtleBackgroundHover, + ghostFocusedBorder: a.strokeFocus2, + ghostFocusedContent: a.neutralForeground1Hover, + ghostFocusedIcon: a.neutralForeground1Hover, + ghostPressedBackground: a.subtleBackgroundPressed, + ghostPressedBorder: a.transparentStroke, + ghostPressedContent: a.neutralForeground1Pressed, + ghostPressedIcon: a.neutralForeground1Pressed, + ghostDisabledBackground: a.subtleBackground, + ghostDisabledBorder: a.transparentStrokeDisabled, + ghostDisabledContent: a.neutralForegroundDisabled, + ghostDisabledIcon: a.neutralForegroundDisabled, + + // Branded control + brandedBackground: a.brandBackground, + brandedDisabledBorder: a.transparentStrokeDisabled, + brandedSecondaryContent: a.neutralForegroundOnBrand, + brandedFocusedSecondaryContent: a.neutralForegroundOnBrandHover, + brandedHoveredSecondaryContent: a.neutralForegroundOnBrandHover, + brandedPressedSecondaryContent: a.neutralForegroundOnBrandPressed, + + // Checked control + defaultCheckedBackground: a.neutralBackground1Selected, + defaultCheckedContent: a.neutralForeground1Selected, + defaultCheckedHoveredBackground: a.neutralBackground1Hover, + defaultCheckedHoveredContent: a.neutralForeground1Hover, + ghostCheckedBackground: a.subtleBackgroundSelected, + ghostCheckedContent: a.neutralForeground2Selected, + ghostCheckedHoveredBackground: a.subtleBackgroundHover, + ghostCheckedHoveredContent: a.neutralForeground2Hover, + ghostCheckedHoveredBorder: a.transparentStroke, + + // Secondary content + ghostSecondaryContent: a.neutralForeground3, + ghostFocusedSecondaryContent: a.neutralForeground3, + ghostHoveredSecondaryContent: a.neutralForeground3Hover, + ghostPressedSecondaryContent: a.neutralForeground3Pressed, + defaultHoveredSecondaryContent: a.neutralForeground3Hover, + defaultPressedSecondaryContent: a.neutralForeground3Pressed, + + // Checkbox and persona + checkboxBackground: a.compoundBrandBackground1, + checkboxBackgroundDisabled: a.neutralBackgroundDisabled, + checkmarkColor: a.neutralForegroundOnBrand, + checkboxBorderColor: a.neutralStrokeAccessible, + personaActivityRing: a.neutralBackground1, + personaActivityGlow: a.brandBackground, + }; +} diff --git a/packages/agentic/design/src/themes/fluent/selectFluentTheme.ts b/packages/agentic/design/src/themes/fluent/selectFluentTheme.ts new file mode 100644 index 00000000000..e0d3662c11a --- /dev/null +++ b/packages/agentic/design/src/themes/fluent/selectFluentTheme.ts @@ -0,0 +1,18 @@ +import type { Theme } from '../../fluent/types/Theme.types'; +import type { ResolvedThemeAppearance } from '../../types/appearance.types'; +import { fluentDarkTheme } from './fluentDarkTheme'; +import { fluentHcDarkTheme } from './fluentHcDarkTheme'; +import { fluentHcLightTheme } from './fluentHcLightTheme'; +import { fluentLightTheme } from './fluentLightTheme'; + +/** + * Select the Fluent theme for a resolved appearance. High contrast selects the high-contrast theme for the color + * scheme; elevated appearances resolve by color scheme until those Fluent themes exist. + */ +export function selectFluentTheme(appearance: ResolvedThemeAppearance | undefined): Theme { + const dark = appearance?.colorScheme === 'dark'; + if (appearance?.contrast === 'highContrast') { + return dark ? fluentHcDarkTheme : fluentHcLightTheme; + } + return dark ? fluentDarkTheme : fluentLightTheme; +} diff --git a/packages/agentic/design/src/themes/index.ts b/packages/agentic/design/src/themes/index.ts new file mode 100644 index 00000000000..20b80200f73 --- /dev/null +++ b/packages/agentic/design/src/themes/index.ts @@ -0,0 +1,6 @@ +export { flexTheme } from './flex/flexTheme'; +export { flexWarmTheme } from './flex/flexWarmTheme'; +export { fluentDarkTheme } from './fluent/fluentDarkTheme'; +export { fluentHcTheme } from './fluent/fluentHcTheme'; +export { fluentLightTheme } from './fluent/fluentLightTheme'; +export { fluentTheme } from './fluent/fluentTheme'; diff --git a/packages/agentic/design/src/theming/ThemeProvider.tsx b/packages/agentic/design/src/theming/ThemeProvider.tsx index 4cb1670a95e..a56c70ad0b5 100644 --- a/packages/agentic/design/src/theming/ThemeProvider.tsx +++ b/packages/agentic/design/src/theming/ThemeProvider.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { resolveThemeAppearance } from './appearance'; -import type { ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceSource } from './appearance.types'; +import type { ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceSource } from '../types/appearance.types'; import { ThemeContext, ThemeSourceContext } from './context'; import { platformAppearance } from './platformAppearance'; import type { ThemeSource } from './themeSource'; diff --git a/packages/agentic/design/src/theming/ThemedRoot.test.tsx b/packages/agentic/design/src/theming/ThemedRoot.test.tsx index 506f5312bda..01da79d1bd4 100644 --- a/packages/agentic/design/src/theming/ThemedRoot.test.tsx +++ b/packages/agentic/design/src/theming/ThemedRoot.test.tsx @@ -4,13 +4,13 @@ import { Platform, View } from 'react-native'; import { act, create } from 'react-test-renderer'; import type { ReactTestRenderer } from 'react-test-renderer'; -import { mockTheme } from '../testing/mockTheme'; -import { defaultFlexTokens } from '../tokens/defaultTokens'; -import { useThemeState } from '../useThemeState'; -import type { ThemeState } from '../useThemeState'; -import type { ResolvedThemeAppearance, ThemeAppearanceSource, ThemeAppearanceSourceSnapshot } from './appearance.types'; +import { mockTheme } from '../test/fixtures/mockTheme'; +import { defaultFlexTokens } from '../flex/defaults/defaultTokens'; +import { useThemeState } from '../flex/useThemeState'; +import type { ThemeState } from '../flex/themeState.types'; +import type { ResolvedThemeAppearance, ThemeAppearanceSource, ThemeAppearanceSourceSnapshot } from '../types/appearance.types'; import { ThemeContext } from './context'; -import { FlexThemeReference } from './flexThemeReference'; +import { FlexThemeReference } from '../flex/flexThemeReference'; import { useRootSettings } from './rootContext'; import type { RootSettings } from './rootContext'; import { ThemedRoot } from './ThemedRoot'; @@ -264,8 +264,13 @@ describe('ThemedRoot', () => { </ThemedRoot> </ThemeProvider>, ); - expect(nestedThemes[0].tokens.color.backgroundBrandHeavy).toBe('#111111'); - expect(nestedThemes[0].appearance).toEqual({ colorScheme: 'dark', contrast: 'highContrast', interfaceLevel: 'elevated' }); + expect(nestedThemes[0].tokens.color.backgroundBrandHeavy.rest).toBe('#111111'); + expect(nestedThemes[0].appearance).toEqual({ + colorScheme: 'dark', + contrast: 'highContrast', + interfaceLevel: 'elevated', + colorTone: 'cool', + }); expect(parentThemes[0].appearance.interfaceLevel).toBe('base'); act(() => theme.update({ spacing: { componentBase100: 21 } })); expect(nestedThemes[nestedThemes.length - 1].tokens.spacing.componentBase100).toBe(21); @@ -287,13 +292,84 @@ describe('ThemedRoot', () => { </ThemedRoot> </ThemeProvider>, ); - expect(themes[0].appearance).toEqual({ colorScheme: 'dark', contrast: 'highContrast', interfaceLevel: 'elevated' }); + expect(themes[0].appearance).toEqual({ colorScheme: 'dark', contrast: 'highContrast', interfaceLevel: 'elevated', colorTone: 'cool' }); act(() => appearance.update({ colorScheme: 'light', contrast: 'standard' })); - expect(themes[themes.length - 1].appearance).toEqual({ colorScheme: 'light', contrast: 'standard', interfaceLevel: 'elevated' }); + expect(themes[themes.length - 1].appearance).toEqual({ + colorScheme: 'light', + contrast: 'standard', + interfaceLevel: 'elevated', + colorTone: 'cool', + }); act(() => component!.unmount()); expect(appearance.listeners.size).toBe(0); }); + it('inherits an explicit color tone through nested roots', () => { + const outer: ThemeState[] = []; + const inherited: ThemeState[] = []; + const overridden: ThemeState[] = []; + render( + <ThemeProvider theme={new FlexThemeReference()} appearance={{ colorTone: 'warm' }}> + <ThemedRoot> + <Probe themes={outer} /> + <ThemedRoot appearance={{ colorScheme: 'dark' }}> + <Probe themes={inherited} /> + <ThemedRoot appearance={{ colorTone: 'cool' }}> + <Probe themes={overridden} /> + </ThemedRoot> + </ThemedRoot> + </ThemedRoot> + </ThemeProvider>, + ); + expect(outer[0].appearance.colorTone).toBe('warm'); + expect(inherited[0].appearance).toMatchObject({ colorScheme: 'dark', colorTone: 'warm' }); + expect(overridden[0].appearance).toMatchObject({ colorScheme: 'dark', colorTone: 'cool' }); + }); + + it('resolves tone from the provider, then the source, then the fallback, then cool', () => { + const fromProvider: ThemeState[] = []; + const fromSource: ThemeState[] = []; + const fromFallback: ThemeState[] = []; + const fromRootFallback: ThemeState[] = []; + const fromDefault: ThemeState[] = []; + const sourceWarm = new FlexThemeReference({ appearance: { colorTone: 'warm' }, fallbackAppearance: { colorTone: 'cool' } }); + const fallbackWarm = new FlexThemeReference({ fallbackAppearance: { colorTone: 'warm' } }); + render( + <> + <ThemeProvider theme={sourceWarm} appearance={{ colorTone: 'cool' }}> + <ThemedRoot> + <Probe themes={fromProvider} /> + </ThemedRoot> + </ThemeProvider> + <ThemeProvider theme={sourceWarm}> + <ThemedRoot> + <Probe themes={fromSource} /> + </ThemedRoot> + </ThemeProvider> + <ThemeProvider theme={fallbackWarm}> + <ThemedRoot> + <Probe themes={fromFallback} /> + </ThemedRoot> + </ThemeProvider> + <ThemedRoot theme={new FlexThemeReference()} fallbackAppearance={{ colorTone: 'warm' }}> + <ThemedRoot> + <Probe themes={fromRootFallback} /> + </ThemedRoot> + </ThemedRoot> + <ThemeProvider theme={new FlexThemeReference()}> + <ThemedRoot> + <Probe themes={fromDefault} /> + </ThemedRoot> + </ThemeProvider> + </>, + ); + expect(fromProvider[0].appearance.colorTone).toBe('cool'); + expect(fromSource[0].appearance.colorTone).toBe('warm'); + expect(fromFallback[0].appearance.colorTone).toBe('warm'); + expect(fromRootFallback[0].appearance.colorTone).toBe('warm'); + expect(fromDefault[0].appearance.colorTone).toBe('cool'); + }); + it('can opt an inherited fixed appearance back into the inherited system source', () => { const appearance = createAppearanceSource({ colorScheme: 'light' }); const themes: ThemeState[] = []; @@ -377,7 +453,7 @@ describe('ThemedRoot', () => { host: { ...mockTheme.host, appearance: 'dark' as const }, }; render( - <ThemedRoot> + <ThemedRoot appearance={{ colorTone: 'warm' }}> <ThemeContext.Provider value={legacyTheme}> <ThemedRoot> <Probe themes={themes} /> @@ -385,8 +461,9 @@ describe('ThemedRoot', () => { </ThemeContext.Provider> </ThemedRoot>, ); - expect(themes[0].tokens.color.backgroundNeutralSubtle).toBe('#123456'); + expect(themes[0].tokens.color.backgroundNeutralSubtle.rest).toBe('#123456'); expect(themes[0].appearance.colorScheme).toBe('dark'); + expect(themes[0].appearance.colorTone).toBe('cool'); }); it('reports a missing scene root instead of returning an untracked modality', () => { diff --git a/packages/agentic/design/src/theming/ThemedRoot.tsx b/packages/agentic/design/src/theming/ThemedRoot.tsx index a5c8dee4532..085cfa81469 100644 --- a/packages/agentic/design/src/theming/ThemedRoot.tsx +++ b/packages/agentic/design/src/theming/ThemedRoot.tsx @@ -4,7 +4,7 @@ import { View } from 'react-native'; import type { IViewProps } from '@fluentui-react-native/adapters'; import { useThemeBoundary } from './context'; -import { FlexThemeReference } from './flexThemeReference'; +import { FlexThemeReference } from '../flex/flexThemeReference'; import { RootContext } from './rootContext'; import { createRootInputController, RootInputContext } from './rootInputController'; import { useRootInputProps } from './useRootInputProps'; diff --git a/packages/agentic/design/src/theming/appearance.test.ts b/packages/agentic/design/src/theming/appearance.test.ts index 20171f4a5cd..81533ff6fd6 100644 --- a/packages/agentic/design/src/theming/appearance.test.ts +++ b/packages/agentic/design/src/theming/appearance.test.ts @@ -1,8 +1,11 @@ import { appearanceOptionFromResolved, appearanceOptionsFromLegacy, + internResolvedThemeAppearance, + legacyThemeAppearanceKey, normalizeThemeAppearanceRequest, resolveThemeAppearance, + themeAppearanceKey, } from './appearance'; describe('structured theme appearance', () => { @@ -21,6 +24,7 @@ describe('structured theme appearance', () => { colorScheme: 'dark', contrast: 'highContrast', interfaceLevel: 'elevated', + colorTone: 'cool', }); }); @@ -46,5 +50,63 @@ describe('structured theme appearance', () => { it('maps structured appearance back to the legacy compatibility union', () => { expect(appearanceOptionFromResolved({ colorScheme: 'dark', contrast: 'standard', interfaceLevel: 'elevated' })).toBe('darkElevated'); expect(appearanceOptionFromResolved({ colorScheme: 'dark', contrast: 'highContrast', interfaceLevel: 'base' })).toBe('highContrast'); + expect(appearanceOptionFromResolved({ colorScheme: 'dark', contrast: 'standard', interfaceLevel: 'base', colorTone: 'warm' })).toBe( + 'dark', + ); + }); +}); + +describe('color tone', () => { + const base = { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base' } as const; + + it('keeps the historical key for omitted and cool tones and suffixes warm', () => { + expect(themeAppearanceKey(base)).toBe('light|standard|base'); + expect(themeAppearanceKey({ ...base, colorTone: 'cool' })).toBe('light|standard|base'); + expect(themeAppearanceKey({ ...base, colorTone: 'warm' })).toBe('light|standard|base|warm'); + expect(legacyThemeAppearanceKey({ ...base, colorTone: 'warm' })).toBe('light|standard|base'); + }); + + it('interns omitted and cool tones to one normalized identity', () => { + const omitted = internResolvedThemeAppearance(base); + + expect(omitted).toEqual({ ...base, colorTone: 'cool' }); + expect(internResolvedThemeAppearance({ ...base, colorTone: 'cool' })).toBe(omitted); + expect(internResolvedThemeAppearance({ ...base, colorTone: 'warm' })).toEqual({ ...base, colorTone: 'warm' }); + expect(Object.isFrozen(omitted)).toBe(true); + }); + + it('records an explicit tone request without changing omitted requests', () => { + expect(normalizeThemeAppearanceRequest({ colorScheme: 'dark' })).not.toHaveProperty('colorTone'); + expect(normalizeThemeAppearanceRequest({ colorTone: 'cool' })).toMatchObject({ colorTone: 'cool' }); + }); + + it('distinguishes omitted from explicit cool requests while sharing the resolved identity', () => { + const omitted = resolveThemeAppearance({ colorScheme: 'light' }); + const cool = resolveThemeAppearance({ colorScheme: 'light', colorTone: 'cool' }); + + expect(omitted).not.toBe(cool); + expect(omitted.requested).not.toHaveProperty('colorTone'); + expect(cool.requested.colorTone).toBe('cool'); + expect(omitted.resolved).toBe(cool.resolved); + }); + + it('resolves the requested tone before the fallback tone and then cool', () => { + const warmFallback = { ...base, colorTone: 'warm' } as const; + + expect(resolveThemeAppearance({ colorTone: 'cool' }, {}, warmFallback).resolved.colorTone).toBe('cool'); + expect(resolveThemeAppearance({}, {}, warmFallback).resolved.colorTone).toBe('warm'); + expect(resolveThemeAppearance({}, {}, base).resolved.colorTone).toBe('cool'); + expect(resolveThemeAppearance().resolved.colorTone).toBe('cool'); + }); + + it('ignores platform snapshots for tone', () => { + const snapshot = { colorScheme: 'dark', colorTone: 'warm' } as unknown as Parameters<typeof resolveThemeAppearance>[1]; + + expect(resolveThemeAppearance({ colorScheme: 'system' }, snapshot).resolved).toEqual({ + colorScheme: 'dark', + contrast: 'standard', + interfaceLevel: 'base', + colorTone: 'cool', + }); }); }); diff --git a/packages/agentic/design/src/theming/appearance.ts b/packages/agentic/design/src/theming/appearance.ts index 4abbabbd219..69f5e114b07 100644 --- a/packages/agentic/design/src/theming/appearance.ts +++ b/packages/agentic/design/src/theming/appearance.ts @@ -1,11 +1,13 @@ -import type { AppearanceOptions, Theme } from './types/Theme.types'; +import type { AppearanceOptions, Theme } from '../fluent/types/Theme.types'; import type { + ColorTone, + NormalizedThemeAppearance, ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceRequest, ThemeAppearanceSourceSnapshot, ThemeAppearanceState, -} from './appearance.types'; +} from '../types/appearance.types'; export const defaultThemeAppearanceRequest: Readonly<ThemeAppearanceRequest> = Object.freeze({ colorScheme: 'system', @@ -13,21 +15,38 @@ export const defaultThemeAppearanceRequest: Readonly<ThemeAppearanceRequest> = O interfaceLevel: 'system', }); -export const defaultResolvedThemeAppearance: Readonly<ResolvedThemeAppearance> = Object.freeze({ +export const defaultColorTone: ColorTone = 'cool'; + +export const defaultResolvedThemeAppearance: Readonly<NormalizedThemeAppearance> = Object.freeze({ colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base', + colorTone: defaultColorTone, }); -const resolvedAppearances = new Map<string, Readonly<ResolvedThemeAppearance>>([['light|standard|base', defaultResolvedThemeAppearance]]); +const resolvedAppearances = new Map<string, Readonly<NormalizedThemeAppearance>>([['light|standard|base', defaultResolvedThemeAppearance]]); const appearanceStates = new Map<string, Readonly<ThemeAppearanceState>>(); -export function themeAppearanceKey(appearance: ResolvedThemeAppearance): string { +/** + * Key for the scheme, contrast, and interface-level axes only. Legacy Fluent + * themes do not vary by tone. + */ +export function legacyThemeAppearanceKey(appearance: ResolvedThemeAppearance): string { return `${appearance.colorScheme}|${appearance.contrast}|${appearance.interfaceLevel}`; } +/** + * Identity key for a resolved appearance. Omitted and cool tones share the + * historical three-axis key; warm appends a suffix. + */ +export function themeAppearanceKey(appearance: ResolvedThemeAppearance): string { + const key = legacyThemeAppearanceKey(appearance); + return appearance.colorTone === 'warm' ? `${key}|warm` : key; +} + function themeAppearanceRequestKey(request: ThemeAppearanceRequest): string { - return `${request.colorScheme}|${request.contrast}|${request.interfaceLevel}`; + const key = `${request.colorScheme}|${request.contrast}|${request.interfaceLevel}`; + return request.colorTone === undefined ? key : `${key}|${request.colorTone}`; } export function normalizeThemeAppearanceRequest(options?: ThemeAppearanceOptions): Readonly<ThemeAppearanceRequest> { @@ -35,23 +54,42 @@ export function normalizeThemeAppearanceRequest(options?: ThemeAppearanceOptions return defaultThemeAppearanceRequest; } - return Object.freeze({ + const request: ThemeAppearanceRequest = { colorScheme: options.colorScheme ?? defaultThemeAppearanceRequest.colorScheme, contrast: options.contrast ?? defaultThemeAppearanceRequest.contrast, interfaceLevel: options.interfaceLevel ?? defaultThemeAppearanceRequest.interfaceLevel, - }); + }; + if (options.colorTone !== undefined) { + request.colorTone = options.colorTone; + } + return Object.freeze(request); } -export function internResolvedThemeAppearance(appearance: ResolvedThemeAppearance): Readonly<ResolvedThemeAppearance> { +/** + * Return the shared normalized identity for a concrete appearance. A missing + * tone resolves to cool, so three-field values and explicit cool converge. + */ +export function internResolvedThemeAppearance(appearance: ResolvedThemeAppearance): Readonly<NormalizedThemeAppearance> { const key = themeAppearanceKey(appearance); let interned = resolvedAppearances.get(key); if (!interned) { - interned = Object.freeze({ ...appearance }); + interned = Object.freeze({ + colorScheme: appearance.colorScheme, + contrast: appearance.contrast, + interfaceLevel: appearance.interfaceLevel, + colorTone: appearance.colorTone === 'warm' ? 'warm' : defaultColorTone, + }); resolvedAppearances.set(key, interned); } return interned; } +/** + * Resolve requested appearance options. Scheme, contrast, and interface level + * fall back from the request to the platform snapshot and then the fallback. + * Tone has no platform source: it falls back from the request to the fallback + * and then cool. + */ export function resolveThemeAppearance( options?: ThemeAppearanceOptions, snapshot: ThemeAppearanceSourceSnapshot = {}, @@ -71,6 +109,7 @@ export function resolveThemeAppearance( requested.interfaceLevel === 'system' ? (snapshot.interfaceLevel ?? fallback.interfaceLevel ?? defaultResolvedThemeAppearance.interfaceLevel) : requested.interfaceLevel, + colorTone: requested.colorTone ?? fallback.colorTone ?? defaultColorTone, }); const key = `${themeAppearanceRequestKey(requested)}>${themeAppearanceKey(resolved)}`; let state = appearanceStates.get(key); @@ -97,6 +136,10 @@ export function appearanceOptionsFromLegacy(appearance: Theme['host']['appearanc } } +/** + * Project a resolved appearance onto the legacy appearance union. Tone has no + * legacy representation and is intentionally dropped. + */ export function appearanceOptionFromResolved(appearance: ResolvedThemeAppearance): AppearanceOptions { if (appearance.contrast === 'highContrast') { return 'highContrast'; diff --git a/packages/agentic/design/src/theming/appearanceSource.ts b/packages/agentic/design/src/theming/appearanceSource.ts index 228aa204363..2d0186fb50a 100644 --- a/packages/agentic/design/src/theming/appearanceSource.ts +++ b/packages/agentic/design/src/theming/appearanceSource.ts @@ -1,4 +1,4 @@ -import type { ThemeAppearanceSourceSnapshot, ThemeAppearanceStore } from './appearance.types'; +import type { ThemeAppearanceSourceSnapshot, ThemeAppearanceStore } from '../types/appearance.types'; type NativeSubscribe = (listener: () => void) => () => void; diff --git a/packages/agentic/design/src/theming/compat/__tests__/defaultLegacyTheme.test.ios.ts b/packages/agentic/design/src/theming/compat/__tests__/defaultLegacyTheme.test.ios.ts deleted file mode 100644 index b534a9cdf37..00000000000 --- a/packages/agentic/design/src/theming/compat/__tests__/defaultLegacyTheme.test.ios.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getDefaultLegacyTheme } from '../defaultLegacyTheme'; - -const dark = { - colorScheme: 'dark', - contrast: 'standard', - interfaceLevel: 'base', -} as const; -const darkElevated = { - colorScheme: 'dark', - contrast: 'standard', - interfaceLevel: 'elevated', -} as const; - -it('uses elevated-dark iOS aliases for the legacy compatibility base', () => { - const darkTheme = getDefaultLegacyTheme(dark); - const elevatedTheme = getDefaultLegacyTheme(darkElevated); - - expect(elevatedTheme.colors.neutralBackground4).toBe('#424242'); - expect(elevatedTheme.colors.neutralBackground4).not.toBe(darkTheme.colors.neutralBackground4); -}); diff --git a/packages/agentic/design/src/theming/compat/createLegacyAliasTokens.ts b/packages/agentic/design/src/theming/compat/createLegacyAliasTokens.ts deleted file mode 100644 index 810b77bbdaa..00000000000 --- a/packages/agentic/design/src/theming/compat/createLegacyAliasTokens.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { memoize } from '@fluentui-react-native/framework-base'; - -import { getAliasTokens, getShadowTokens } from '../../tokens/legacy'; -import { mapPipelineToShadow } from '../mapPipelineToShadow'; -import { mapPipelineToTheme } from '../mapPipelineToTheme'; -import type { AliasColorTokens } from '../types/Color.types'; -import type { ThemeShadowDefinition } from '../types/Shadow.types'; -import type { AppearanceOptions } from '../types/Theme.types'; - -function createLegacyColorAliasTokensWorker(mode: AppearanceOptions): AliasColorTokens { - return mapPipelineToTheme(getAliasTokens(mode)); -} - -export const createLegacyColorAliasTokens = memoize(createLegacyColorAliasTokensWorker); - -function createLegacyShadowAliasTokensWorker(mode: AppearanceOptions): ThemeShadowDefinition { - return mapPipelineToShadow(getShadowTokens(mode)); -} - -export const createLegacyShadowAliasTokens = memoize(createLegacyShadowAliasTokensWorker); diff --git a/packages/agentic/design/src/theming/compat/defaultLegacyColors.ts b/packages/agentic/design/src/theming/compat/defaultLegacyColors.ts deleted file mode 100644 index 458a9c56c35..00000000000 --- a/packages/agentic/design/src/theming/compat/defaultLegacyColors.ts +++ /dev/null @@ -1,315 +0,0 @@ -import type { FabricWebPalette, Palette, ThemeColorDefinition } from '../types/Color.types'; - -import { createLegacyColorAliasTokens } from './createLegacyAliasTokens'; - -export function paletteFromFabricColors(palette: FabricWebPalette, isInverted?: boolean): Palette { - return { - background: palette.white, - bodyStandoutBackground: palette.neutralLighterAlt, - bodyFrameBackground: palette.white, - bodyFrameDivider: palette.neutralLight, - bodyText: palette.neutralPrimary, - bodyTextChecked: palette.black, - subText: palette.neutralSecondary, - bodyDivider: palette.neutralLight, - - disabledBackground: isInverted ? palette.neutralQuaternaryAlt : palette.neutralLighter, - disabledText: palette.neutralTertiary, - disabledBodyText: palette.neutralTertiary, - - focusBorder: palette.neutralSecondary, - variantBorder: palette.neutralLight, - - errorText: !isInverted ? palette.redDark : '#ff5f5f', - inputBorder: palette.neutralTertiary, - inputBackground: palette.white, - inputFocusBorderAlt: palette.themePrimary, - inputText: palette.neutralPrimary, - inputPlaceholderText: palette.neutralSecondary, - - buttonBackground: palette.neutralLighter, - buttonBackgroundChecked: palette.neutralTertiaryAlt, - buttonBackgroundHovered: palette.neutralLight, - buttonBackgroundPressed: palette.neutralLight, - buttonBackgroundDisabled: palette.neutralLighter, - buttonBorder: palette.neutralSecondaryAlt, - buttonText: isInverted ? palette.black : palette.neutralPrimary, - buttonTextHovered: isInverted ? palette.neutralPrimary : palette.neutralDark, - buttonTextChecked: palette.neutralDark, - buttonTextPressed: palette.neutralDark, - buttonTextDisabled: palette.neutralTertiary, - buttonBorderDisabled: palette.neutralLighter, - buttonBorderFocused: palette.neutralSecondaryAlt, - - primaryButtonBackground: palette.themePrimary, - primaryButtonBackgroundHovered: palette.themeDarkAlt, - primaryButtonBackgroundPressed: palette.themeDark, - primaryButtonBackgroundDisabled: palette.neutralLighter, - primaryButtonBorder: 'transparent', - primaryButtonBorderFocused: 'transparent', - primaryButtonText: palette.white, - primaryButtonTextHovered: palette.white, - primaryButtonTextPressed: palette.white, - primaryButtonTextDisabled: palette.neutralQuaternary, - - accentButtonBackground: palette.accent, - - menuBackground: isInverted ? palette.neutralLighter : palette.white, - menuDivider: palette.neutralTertiaryAlt, - menuIcon: isInverted ? palette.themeDarkAlt : palette.themePrimary, - menuItemBackgroundHovered: isInverted ? palette.neutralQuaternaryAlt : palette.neutralLighter, - menuItemBackgroundPressed: isInverted ? palette.neutralQuaternary : palette.neutralLight, - menuItemText: palette.neutralPrimary, - menuItemTextHovered: palette.neutralDark, - - listHeaderBackgroundHovered: palette.neutralLighter, - listHeaderBackgroundPressed: palette.neutralLight, - - actionLink: palette.neutralPrimary, - link: palette.themePrimary, - linkHovered: palette.themeDarker, - linkPressed: palette.themeDark, - - defaultBackground: palette.neutralLighter, - defaultBorder: palette.neutralSecondaryAlt, - defaultContent: isInverted ? palette.black : palette.neutralPrimary, - defaultIcon: isInverted ? palette.black : palette.neutralPrimary, - - defaultHoveredBackground: palette.neutralLight, - defaultHoveredBorder: palette.neutralSecondaryAlt, - defaultHoveredContent: isInverted ? palette.neutralPrimary : palette.neutralDark, - defaultHoveredIcon: isInverted ? palette.neutralPrimary : palette.neutralDark, - - defaultFocusedBackground: palette.neutralLight, - defaultFocusedBorder: palette.neutralSecondaryAlt, - defaultFocusedContent: isInverted ? palette.neutralPrimary : palette.neutralDark, - defaultFocusedIcon: isInverted ? palette.neutralPrimary : palette.neutralDark, - - defaultPressedBackground: palette.neutralLight, - defaultPressedBorder: palette.neutralSecondaryAlt, - defaultPressedContent: palette.neutralDark, - defaultPressedIcon: palette.neutralDark, - - defaultDisabledBackground: palette.neutralLighter, - defaultDisabledBorder: palette.neutralLighter, - defaultDisabledContent: palette.neutralTertiary, - defaultDisabledIcon: palette.neutralTertiary, - - ghostBackground: palette.white, - ghostBorder: palette.white, - ghostContent: palette.neutralPrimary, - ghostIcon: palette.neutralPrimary, - - ghostHoveredBackground: palette.neutralLighter, - ghostHoveredBorder: palette.neutralLighter, - ghostHoveredContent: palette.neutralDark, - ghostHoveredIcon: palette.neutralDark, - - ghostFocusedBackground: palette.neutralLighter, - ghostFocusedBorder: palette.neutralSecondaryAlt, - ghostFocusedContent: palette.neutralDark, - ghostFocusedIcon: palette.neutralDark, - - ghostPressedBackground: palette.neutralLight, - ghostPressedBorder: palette.neutralLight, - ghostPressedContent: palette.neutralDark, - ghostPressedIcon: palette.neutralDark, - - ghostDisabledBackground: palette.white, - ghostDisabledBorder: palette.white, - ghostDisabledContent: palette.neutralTertiary, - ghostDisabledIcon: palette.neutralTertiary, - - brandedBackground: palette.themePrimary, - brandedDisabledBorder: palette.neutralLighter, - - defaultCheckedBackground: palette.neutralTertiaryAlt, - defaultCheckedContent: palette.neutralDark, - defaultCheckedHoveredBackground: palette.neutralLight, - defaultCheckedHoveredContent: isInverted ? palette.neutralPrimary : palette.neutralDark, - - ghostCheckedBackground: palette.neutralLight, - ghostCheckedContent: palette.black, - ghostCheckedHoveredBackground: palette.neutralLighter, - ghostCheckedHoveredContent: palette.neutralDark, - ghostCheckedHoveredBorder: palette.neutralDark, - - ghostSecondaryContent: palette.neutralSecondary, - ghostFocusedSecondaryContent: palette.neutralSecondary, - ghostHoveredSecondaryContent: palette.neutralSecondary, - ghostPressedSecondaryContent: palette.neutralSecondary, - - brandedSecondaryContent: palette.neutralLighterAlt, - brandedFocusedSecondaryContent: palette.neutralLighterAlt, - brandedHoveredSecondaryContent: palette.neutralLighterAlt, - brandedPressedSecondaryContent: palette.neutralLighterAlt, - - defaultHoveredSecondaryContent: palette.neutralTertiary, - defaultPressedSecondaryContent: palette.neutralTertiary, - - checkmarkColor: palette.white, - checkboxBackground: palette.themePrimary, - checkboxBackgroundDisabled: palette.neutralLighter, - checkboxBorderColor: palette.neutralSecondaryAlt, - - personaActivityRing: palette.white, - personaActivityGlow: palette.themePrimary, - }; -} - -export function getStockWebHighContrastPalette(): ThemeColorDefinition { - return { - background: '#000000', - bodyStandoutBackground: '#000000', - bodyFrameBackground: '#000000', - bodyFrameDivider: '#000000', - bodyText: '#ffffff', - bodyTextChecked: '#000000', - subText: '#ffffff', - bodyDivider: '#ffffff', - - disabledBackground: '#000000', - disabledText: '#3ff23f', - disabledBodyText: '#3ff23f', - - focusBorder: '#ffffff', - variantBorder: '#ffffff', - - errorText: '#ffffff', - - inputBorder: '#ffffff', - inputBackground: '#000000', - inputFocusBorderAlt: '#ffffff', - inputText: '#ffffff', - inputPlaceholderText: '#ffffff', - - buttonBackground: '#000000', - buttonBackgroundChecked: '#1aebff', - buttonBackgroundHovered: '#1aebff', - buttonBackgroundPressed: '#1aebff', - buttonBackgroundDisabled: '#000000', - buttonBorder: '#ffffff', - buttonText: '#ffffff', - buttonTextHovered: '#000000', - buttonTextChecked: '#000000', - buttonTextPressed: '#000000', - buttonTextDisabled: '#3ff23f', - buttonBorderDisabled: '#3ff23f', - buttonBorderFocused: '#ffffff', - - primaryButtonBackground: '#000000', - primaryButtonBackgroundHovered: '#1aebff', - primaryButtonBackgroundPressed: '#1aebff', - primaryButtonBackgroundDisabled: '#000000', - primaryButtonBorder: '#ffffff', - primaryButtonBorderFocused: '#ffffff', - primaryButtonText: '#ffffff', - primaryButtonTextHovered: '#000000', - primaryButtonTextPressed: '#000000', - primaryButtonTextDisabled: '#3ff23f', - - accentButtonBackground: '#000000', - - menuBackground: '#000000', - menuDivider: '#ffffff', - menuIcon: '#ffffff', - menuItemBackgroundHovered: '#1aebff', - menuItemBackgroundPressed: '#1aebff', - menuItemText: '#ffffff', - menuItemTextHovered: '#000000', - - listHeaderBackgroundHovered: '#1aebff', - listHeaderBackgroundPressed: '#1aebff', - - actionLink: '#ffff00', - link: '#ffff00', - linkHovered: '#ffffff', - linkPressed: '#ffffff', - - defaultBackground: '#000000', - defaultBorder: '#ffffff', - defaultContent: '#ffffff', - defaultIcon: '#ffffff', - - defaultHoveredBackground: '#1aebff', - defaultHoveredBorder: '#1aebff', - defaultHoveredContent: '#000000', - defaultHoveredIcon: '#000000', - - defaultFocusedBackground: '#000000', - defaultFocusedBorder: '#ffffff', - defaultFocusedContent: '#ffffff', - defaultFocusedIcon: '#ffffff', - - defaultPressedBackground: '#1aebff', - defaultPressedBorder: '#1aebff', - defaultPressedContent: '#000000', - defaultPressedIcon: '#000000', - - defaultDisabledBackground: '#000000', - defaultDisabledBorder: '#3ff23f', - defaultDisabledContent: '#3ff23f', - defaultDisabledIcon: '#3ff23f', - - ghostBackground: '#000000', - ghostBorder: '#000000', - ghostContent: '#ffffff', - ghostIcon: '#ffffff', - - ghostHoveredBackground: '#1aebff', - ghostHoveredBorder: '#1aebff', - ghostHoveredContent: '#000000', - ghostHoveredIcon: '#000000', - - ghostFocusedBackground: '#000000', - ghostFocusedBorder: '#ffffff', - ghostFocusedContent: '#ffffff', - ghostFocusedIcon: '#ffffff', - - ghostPressedBackground: '#1aebff', - ghostPressedBorder: '#1aebff', - ghostPressedContent: '#000000', - ghostPressedIcon: '#000000', - - ghostDisabledBackground: '#000000', - ghostDisabledBorder: '#000000', - ghostDisabledContent: '#3ff23f', - ghostDisabledIcon: '#3ff23f', - - brandedBackground: '#000000', - brandedDisabledBorder: '#3ff23f', - - defaultCheckedBackground: '#1aebff', - defaultCheckedContent: '#000000', - defaultCheckedHoveredBackground: '#1aebff', - defaultCheckedHoveredContent: '#000000', - - ghostCheckedBackground: '#1aebff', - ghostCheckedContent: '#000000', - ghostCheckedHoveredBackground: '#1aebff', - ghostCheckedHoveredContent: '#000000', - ghostCheckedHoveredBorder: '#000000', - - ghostSecondaryContent: '#ffffff', - ghostFocusedSecondaryContent: '#ffffff', - ghostHoveredSecondaryContent: '#000000', - ghostPressedSecondaryContent: '#000000', - - brandedSecondaryContent: '#ffffff', - brandedFocusedSecondaryContent: '#ffffff', - brandedHoveredSecondaryContent: '#000000', - brandedPressedSecondaryContent: '#000000', - - defaultHoveredSecondaryContent: '#000000', - defaultPressedSecondaryContent: '#000000', - - checkmarkColor: '#ffffff', - checkboxBackground: '#000000', - checkboxBackgroundDisabled: '#000000', - checkboxBorderColor: '#ffffff', - - personaActivityRing: '#ffffff', - personaActivityGlow: 'transparent', - ...createLegacyColorAliasTokens('highContrast'), - }; -} diff --git a/packages/agentic/design/src/theming/compat/defaultLegacyTheme.test.ts b/packages/agentic/design/src/theming/compat/defaultLegacyTheme.test.ts deleted file mode 100644 index 8a9170165f1..00000000000 --- a/packages/agentic/design/src/theming/compat/defaultLegacyTheme.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { getDefaultLegacyTheme } from './defaultLegacyTheme'; - -const light = { - colorScheme: 'light', - contrast: 'standard', - interfaceLevel: 'base', -} as const; -const dark = { - colorScheme: 'dark', - contrast: 'standard', - interfaceLevel: 'base', -} as const; -const darkElevated = { - colorScheme: 'dark', - contrast: 'standard', - interfaceLevel: 'elevated', -} as const; -const highContrast = { - colorScheme: 'dark', - contrast: 'highContrast', - interfaceLevel: 'base', -} as const; - -describe('getDefaultLegacyTheme', () => { - it('creates complete stable legacy bases lazily per resolved appearance', () => { - const lightTheme = getDefaultLegacyTheme(light); - const darkTheme = getDefaultLegacyTheme(dark); - - expect(getDefaultLegacyTheme(light)).toBe(lightTheme); - expect(getDefaultLegacyTheme(dark)).toBe(darkTheme); - expect(darkTheme).not.toBe(lightTheme); - - for (const theme of [lightTheme, darkTheme]) { - expect(theme.colors.background).toBeDefined(); - expect(theme.colors.bodyText).toBeDefined(); - expect(theme.colors.disabledText).toBeDefined(); - expect(theme.colors.inputBackground).toBeDefined(); - expect(theme.colors.buttonBackground).toBeDefined(); - expect(theme.colors.primaryButtonBackground).toBeDefined(); - expect(theme.colors.menuBackground).toBeDefined(); - expect(theme.colors.link).toBeDefined(); - expect(theme.typography.families.primary).toBeDefined(); - expect(theme.typography.sizes.body).toBeDefined(); - expect(theme.typography.weights.regular).toBeDefined(); - expect(theme.typography.variants.bodyStandard).toBeDefined(); - expect(theme.shadows.shadow2).toBeDefined(); - expect(theme.shadows.shadow64).toBeDefined(); - expect(theme.spacing.s1).toBeDefined(); - expect(theme.components).toEqual({}); - } - }); - - it('preserves elevated-dark and high-contrast compatibility appearances', () => { - const elevatedTheme = getDefaultLegacyTheme(darkElevated); - const highContrastTheme = getDefaultLegacyTheme(highContrast); - - expect(elevatedTheme.host.appearance).toBe('darkElevated'); - expect(elevatedTheme.colors.background).toBe(getDefaultLegacyTheme(dark).colors.background); - expect(highContrastTheme.host.appearance).toBe('highContrast'); - expect(highContrastTheme.colors.background).toBe('#000000'); - expect(highContrastTheme.colors.bodyText).toBe('#ffffff'); - }); -}); diff --git a/packages/agentic/design/src/theming/compat/defaultLegacyTheme.ts b/packages/agentic/design/src/theming/compat/defaultLegacyTheme.ts deleted file mode 100644 index cc560f18fb8..00000000000 --- a/packages/agentic/design/src/theming/compat/defaultLegacyTheme.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Platform } from 'react-native'; - -import { fontWeightRegular, fontWeightSemibold } from '../../tokens/global.generated'; -import globalTokens from '../../tokens/legacy/tokens-global'; -import { appearanceOptionFromResolved, themeAppearanceKey } from '../appearance'; -import type { ResolvedThemeAppearance } from '../appearance.types'; -import type { Theme, Spacing } from '../types/Theme.types'; -import type { FontSize, FontSizes, FontWeightValue, Typography, Variants } from '../types/Typography.types'; - -import { createLegacyShadowAliasTokens } from './createLegacyAliasTokens'; -import { getStockWebHighContrastPalette } from './defaultLegacyColors'; -import { getStockWebDarkPalette, getStockWebPalette } from './stockWebPalette'; - -let defaultTypography: Typography | undefined; -let defaultSpacing: Spacing | undefined; -const defaultThemes = new Map<string, Theme>(); - -function getDefaultTypography(): Typography { - if (defaultTypography) { - return defaultTypography; - } - - const typography = { - sizes: { - caption: globalTokens.font.size100 as FontSize, - secondary: globalTokens.font.size200 as FontSize, - body: globalTokens.font.size300 as FontSize, - subheader: globalTokens.font.size400 as FontSize, - header: globalTokens.font.size500 as FontSize, - hero: globalTokens.font.size700 as FontSize, - heroLarge: globalTokens.font.size900 as FontSize, - } as FontSizes, - weights: { - regular: fontWeightRegular as FontWeightValue, - semiBold: fontWeightSemibold as FontWeightValue, - }, - families: { - primary: 'Segoe UI', - secondary: 'Segoe UI', - cursive: 'System', - monospace: 'System', - numeric: 'System', - sansSerif: 'System', - serif: 'System', - }, - variants: { - captionStandard: { face: 'primary', size: 'caption', weight: 'regular' }, - secondaryStandard: { face: 'primary', size: 'secondary', weight: 'regular' }, - secondarySemibold: { face: 'primary', size: 'secondary', weight: 'semiBold' }, - bodyStandard: { face: 'primary', size: 'body', weight: 'regular' }, - bodySemibold: { face: 'primary', size: 'body', weight: 'semiBold' }, - subheaderStandard: { face: 'primary', size: 'subheader', weight: 'regular' }, - subheaderSemibold: { face: 'primary', size: 'subheader', weight: 'semiBold' }, - headerStandard: { face: 'primary', size: 'header', weight: 'regular' }, - headerSemibold: { face: 'primary', size: 'header', weight: 'semiBold' }, - heroStandard: { face: 'primary', size: 'hero', weight: 'regular' }, - heroSemibold: { face: 'primary', size: 'hero', weight: 'semiBold' }, - heroLargeStandard: { face: 'primary', size: 'heroLarge', weight: 'regular' }, - heroLargeSemibold: { face: 'primary', size: 'heroLarge', weight: 'semiBold' }, - caption1: { face: 'primary', size: 'caption', weight: 'regular' }, - caption1Strong: { face: 'primary', size: 'caption', weight: 'semiBold' }, - body1: { face: 'primary', size: 'secondary', weight: 'regular' }, - body1Strong: { face: 'primary', size: 'secondary', weight: 'semiBold' }, - body2: { face: 'primary', size: 'body', weight: 'regular' }, - body2Strong: { face: 'primary', size: 'body', weight: 'semiBold' }, - subtitle1: { face: 'primary', size: 'header', weight: 'regular' }, - subtitle1Strong: { face: 'primary', size: 'header', weight: 'semiBold' }, - subtitle2: { face: 'primary', size: 'subheader', weight: 'regular' }, - subtitle2Strong: { face: 'primary', size: 'subheader', weight: 'semiBold' }, - title1: { face: 'primary', size: 'hero', weight: 'regular' }, - title1Strong: { face: 'primary', size: 'hero', weight: 'semiBold' }, - largeTitle: { face: 'primary', size: 'heroLarge', weight: 'regular' }, - display: { face: 'primary', size: 'heroLarge', weight: 'semiBold' }, - } as Variants, - }; - - if (Platform.OS === 'macos' || Platform.OS === 'ios') { - typography.families = { - primary: 'System', - secondary: 'System', - cursive: 'System', - monospace: 'System', - numeric: 'System', - sansSerif: 'System', - serif: 'System', - }; - } - - defaultTypography = typography; - return typography; -} - -function getDefaultSpacing(): Spacing { - defaultSpacing ??= { - s2: '4px', - s1: '8px', - m: '16px', - l1: '20px', - l2: '32px', - }; - return defaultSpacing; -} - -/** - * Returns a complete legacy Theme without constructing any other appearance. - * The result is stable for one resolved appearance and safe to use as an - * immutable base for Flex-to-legacy projection. - */ -export function getDefaultLegacyTheme(appearance: ResolvedThemeAppearance): Theme { - const key = themeAppearanceKey(appearance); - const cached = defaultThemes.get(key); - if (cached) { - return cached; - } - - const highContrast = appearance.contrast === 'highContrast'; - const dark = appearance.colorScheme === 'dark'; - const darkAppearance = appearance.interfaceLevel === 'elevated' ? 'darkElevated' : 'dark'; - const colors = highContrast ? getStockWebHighContrastPalette() : dark ? getStockWebDarkPalette(darkAppearance) : getStockWebPalette(); - const tokenAppearance = highContrast ? 'highContrast' : dark ? 'dark' : 'light'; - const theme: Theme = { - colors, - typography: getDefaultTypography(), - spacing: getDefaultSpacing(), - shadows: createLegacyShadowAliasTokens(tokenAppearance), - components: {}, - host: { - appearance: appearanceOptionFromResolved(appearance), - }, - }; - - defaultThemes.set(key, theme); - return theme; -} diff --git a/packages/agentic/design/src/theming/compat/index.ts b/packages/agentic/design/src/theming/compat/index.ts deleted file mode 100644 index d64415b3b32..00000000000 --- a/packages/agentic/design/src/theming/compat/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { getDefaultLegacyTheme } from './defaultLegacyTheme'; -export { themeFromFlexTokens } from './themeFromFlexTokens'; -export type { ThemeFromFlexTokensOptions } from './themeFromFlexTokens'; diff --git a/packages/agentic/design/src/theming/compat/stockWebPalette.macos.ts b/packages/agentic/design/src/theming/compat/stockWebPalette.macos.ts deleted file mode 100644 index 59226a9e339..00000000000 --- a/packages/agentic/design/src/theming/compat/stockWebPalette.macos.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { colorBlack, colorBurgundyPrimary, colorRedPrimary, colorWhite } from '../../tokens/global.generated'; -import globalTokens from '../../tokens/legacy/tokens-global'; -import type { ThemeColorDefinition } from '../types/Color.types'; - -import { createLegacyColorAliasTokens } from './createLegacyAliasTokens'; -import { paletteFromFabricColors } from './defaultLegacyColors'; - -export function getStockWebPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors({ - black: colorBlack, - neutralDark: '#201f1e', - neutralPrimary: '#323130', - neutralPrimaryAlt: '#3b3a39', - neutralSecondary: '#605e5c', - neutralSecondaryAlt: '#8a8886', - neutralTertiary: '#a19f9d', - neutralTertiaryAlt: '#c8c6c4', - neutralQuaternary: '#d2d0ce', - neutralQuaternaryAlt: '#e1dfdd', - neutralLight: '#edebe9', - neutralLighter: '#f3f2f1', - neutralLighterAlt: '#faf9f8', - white: colorWhite, - red: colorRedPrimary, - redDark: colorBurgundyPrimary, - themeDarker: globalTokens.color.brand.shade40, - themeDark: globalTokens.color.brand.shade20, - themeDarkAlt: globalTokens.color.brand.shade10, - themePrimary: globalTokens.color.brand.primary, - themeSecondary: '#2b88d8', - themeTertiary: '#71afe5', - themeLight: globalTokens.color.brand.tint40, - themeLighter: globalTokens.color.brand.tint50, - themeLighterAlt: globalTokens.color.brand.tint60, - accent: globalTokens.color.brand.primary, - blackTranslucent40: 'rgba(0,0,0,.4)', - }), - ...createLegacyColorAliasTokens('light'), - }; -} - -export function getStockWebDarkPalette(appearance: 'dark' | 'darkElevated' = 'dark'): ThemeColorDefinition { - return { - ...paletteFromFabricColors( - { - themeDarker: '#82c7ff', - themeDark: globalTokens.color.brand.tint30, - themeDarkAlt: globalTokens.color.brand.tint20, - themePrimary: globalTokens.color.brand.tint10, - themeSecondary: globalTokens.color.brand.primary, - themeTertiary: '#235a85', - themeLight: globalTokens.color.brand.shade30, - themeLighter: globalTokens.color.brand.shade50, - themeLighterAlt: globalTokens.color.brand.shade60, - black: colorWhite, - neutralDark: '#faf9f8', - neutralPrimary: '#f3f2f1', - neutralPrimaryAlt: '#c8c6c4', - neutralSecondary: '#a19f9d', - neutralSecondaryAlt: '#979693', - neutralTertiary: '#797775', - neutralTertiaryAlt: '#484644', - neutralQuaternary: '#3b3a39', - neutralQuaternaryAlt: '#323130', - neutralLight: '#292827', - neutralLighter: '#252423', - neutralLighterAlt: '#201f1e', - white: '#1b1a19', - red: colorRedPrimary, - accent: globalTokens.color.brand.primary, - redDark: '#f1707b', - blackTranslucent40: 'rgba(0,0,0,.4)', - }, - true, - ), - ...createLegacyColorAliasTokens(appearance), - }; -} diff --git a/packages/agentic/design/src/theming/compat/stockWebPalette.ts b/packages/agentic/design/src/theming/compat/stockWebPalette.ts deleted file mode 100644 index d588e872fce..00000000000 --- a/packages/agentic/design/src/theming/compat/stockWebPalette.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -import { colorBlack, colorBurgundyPrimary, colorRedPrimary, colorWhite } from '../../tokens/global.generated'; -import globalTokens from '../../tokens/legacy/tokens-global'; -import type { ThemeColorDefinition } from '../types/Color.types'; - -import { createLegacyColorAliasTokens } from './createLegacyAliasTokens'; -import { paletteFromFabricColors } from './defaultLegacyColors'; - -export function getStockWebPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors({ - black: colorBlack, - neutralDark: '#201f1e', - neutralPrimary: '#323130', - neutralPrimaryAlt: '#3b3a39', - neutralSecondary: '#605e5c', - neutralSecondaryAlt: '#8a8886', - neutralTertiary: '#a19f9d', - neutralTertiaryAlt: '#c8c6c4', - neutralQuaternary: '#d2d0ce', - neutralQuaternaryAlt: '#e1dfdd', - neutralLight: '#edebe9', - neutralLighter: '#f3f2f1', - neutralLighterAlt: '#faf9f8', - white: colorWhite, - red: colorRedPrimary, - redDark: colorBurgundyPrimary, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - accent: globalTokens.color.brand80, - blackTranslucent40: 'rgba(0,0,0,.4)', - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeDarker: globalTokens.color.brand40, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeDark: globalTokens.color.brand60, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeDarkAlt: globalTokens.color.brand70, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themePrimary: globalTokens.color.brand80, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeSecondary: globalTokens.color.brand90, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeTertiary: globalTokens.color.brand120, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeLight: globalTokens.color.brand140, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeLighter: globalTokens.color.brand150, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeLighterAlt: globalTokens.color.brand160, - }), - ...createLegacyColorAliasTokens('light'), - }; -} - -export function getStockWebDarkPalette(appearance: 'dark' | 'darkElevated' = 'dark'): ThemeColorDefinition { - return { - ...paletteFromFabricColors( - { - black: colorWhite, - neutralDark: '#faf9f8', - neutralPrimary: '#f3f2f1', - neutralPrimaryAlt: '#c8c6c4', - neutralSecondary: '#a19f9d', - neutralSecondaryAlt: '#979693', - neutralTertiary: '#797775', - neutralTertiaryAlt: '#484644', - neutralQuaternary: '#3b3a39', - neutralQuaternaryAlt: '#323130', - neutralLight: '#292827', - neutralLighter: '#252423', - neutralLighterAlt: '#201f1e', - white: '#1b1a19', - red: colorRedPrimary, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - accent: globalTokens.color.brand40, - redDark: '#f1707b', - blackTranslucent40: 'rgba(0,0,0,.4)', - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeDarker: globalTokens.color.brand110, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeDark: globalTokens.color.brand100, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeDarkAlt: globalTokens.color.brand100, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themePrimary: globalTokens.color.brand90, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeSecondary: globalTokens.color.brand90, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeTertiary: globalTokens.color.brand60, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeLight: globalTokens.color.brand50, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeLighter: globalTokens.color.brand40, - // @ts-expect-error The mobile token payloads retain the legacy flat brand ramp. - themeLighterAlt: globalTokens.color.brand30, - }, - true, - ), - ...createLegacyColorAliasTokens(appearance), - }; -} diff --git a/packages/agentic/design/src/theming/compat/stockWebPalette.win32.ts b/packages/agentic/design/src/theming/compat/stockWebPalette.win32.ts deleted file mode 100644 index 59226a9e339..00000000000 --- a/packages/agentic/design/src/theming/compat/stockWebPalette.win32.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { colorBlack, colorBurgundyPrimary, colorRedPrimary, colorWhite } from '../../tokens/global.generated'; -import globalTokens from '../../tokens/legacy/tokens-global'; -import type { ThemeColorDefinition } from '../types/Color.types'; - -import { createLegacyColorAliasTokens } from './createLegacyAliasTokens'; -import { paletteFromFabricColors } from './defaultLegacyColors'; - -export function getStockWebPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors({ - black: colorBlack, - neutralDark: '#201f1e', - neutralPrimary: '#323130', - neutralPrimaryAlt: '#3b3a39', - neutralSecondary: '#605e5c', - neutralSecondaryAlt: '#8a8886', - neutralTertiary: '#a19f9d', - neutralTertiaryAlt: '#c8c6c4', - neutralQuaternary: '#d2d0ce', - neutralQuaternaryAlt: '#e1dfdd', - neutralLight: '#edebe9', - neutralLighter: '#f3f2f1', - neutralLighterAlt: '#faf9f8', - white: colorWhite, - red: colorRedPrimary, - redDark: colorBurgundyPrimary, - themeDarker: globalTokens.color.brand.shade40, - themeDark: globalTokens.color.brand.shade20, - themeDarkAlt: globalTokens.color.brand.shade10, - themePrimary: globalTokens.color.brand.primary, - themeSecondary: '#2b88d8', - themeTertiary: '#71afe5', - themeLight: globalTokens.color.brand.tint40, - themeLighter: globalTokens.color.brand.tint50, - themeLighterAlt: globalTokens.color.brand.tint60, - accent: globalTokens.color.brand.primary, - blackTranslucent40: 'rgba(0,0,0,.4)', - }), - ...createLegacyColorAliasTokens('light'), - }; -} - -export function getStockWebDarkPalette(appearance: 'dark' | 'darkElevated' = 'dark'): ThemeColorDefinition { - return { - ...paletteFromFabricColors( - { - themeDarker: '#82c7ff', - themeDark: globalTokens.color.brand.tint30, - themeDarkAlt: globalTokens.color.brand.tint20, - themePrimary: globalTokens.color.brand.tint10, - themeSecondary: globalTokens.color.brand.primary, - themeTertiary: '#235a85', - themeLight: globalTokens.color.brand.shade30, - themeLighter: globalTokens.color.brand.shade50, - themeLighterAlt: globalTokens.color.brand.shade60, - black: colorWhite, - neutralDark: '#faf9f8', - neutralPrimary: '#f3f2f1', - neutralPrimaryAlt: '#c8c6c4', - neutralSecondary: '#a19f9d', - neutralSecondaryAlt: '#979693', - neutralTertiary: '#797775', - neutralTertiaryAlt: '#484644', - neutralQuaternary: '#3b3a39', - neutralQuaternaryAlt: '#323130', - neutralLight: '#292827', - neutralLighter: '#252423', - neutralLighterAlt: '#201f1e', - white: '#1b1a19', - red: colorRedPrimary, - accent: globalTokens.color.brand.primary, - redDark: '#f1707b', - blackTranslucent40: 'rgba(0,0,0,.4)', - }, - true, - ), - ...createLegacyColorAliasTokens(appearance), - }; -} diff --git a/packages/agentic/design/src/theming/compat/themeFromFlexTokens.test.ts b/packages/agentic/design/src/theming/compat/themeFromFlexTokens.test.ts deleted file mode 100644 index 865b4183c30..00000000000 --- a/packages/agentic/design/src/theming/compat/themeFromFlexTokens.test.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { defaultFlexTokens } from '../../tokens/defaultTokens'; -import type { FlexTokens } from '../../tokens/flex.types'; -import type { PartialTheme } from '../types/Theme.types'; - -import { themeFromFlexTokens } from './themeFromFlexTokens'; - -const light = { - colorScheme: 'light', - contrast: 'standard', - interfaceLevel: 'base', -} as const; - -function createTokens(): FlexTokens { - const hover = { ...defaultFlexTokens.color.hover }; - delete hover.surfaceNeutralNear; - - return { - ...defaultFlexTokens, - color: { - ...defaultFlexTokens.color, - backgroundBrandSoft: '#111111', - backgroundBrandSubtle: '#222222', - backgroundNeutralSubtle: '#333333', - surfaceNeutralNear: '#444444', - fixedBlack: '#050505', - expressionAchromaticHeavy: '#060606', - hover, - }, - borderRadius: { - ...defaultFlexTokens.borderRadius, - base200: 12, - base300: 24, - }, - fontWeight: { - ...defaultFlexTokens.fontWeight, - functionalSemibold: '700', - contentBold: '900', - }, - }; -} - -describe('themeFromFlexTokens', () => { - it('merges the base, legacy fallback, mapped Flex values, and final appearance in order', () => { - const fallback = { - name: 'Host theme', - colors: { - brandBackground2: '#777777', - customLegacyColor: '#abcdef', - }, - components: { - Button: { - tokens: { - borderRadius: 2, - legacyOnlyMetric: 42, - }, - }, - }, - host: { - appearance: 'dynamic', - palette: { - Bkg: '#101010', - }, - colors: { - AppPrimary: '#202020', - }, - }, - } as PartialTheme; - - const theme = themeFromFlexTokens(createTokens(), light, { fallback }); - - expect(theme.name).toBe('Host theme'); - expect(theme.colors.customLegacyColor).toBe('#abcdef'); - expect(theme.colors.brandBackground2).toBe('#111111'); - expect(theme.colors.neutralBackground2).toBe('#444444'); - expect(theme.colors.neutralBackground2Hover).toBe('#444444'); - expect(theme.colors.black).toBe('#050505'); - expect(theme.components.Button.tokens).toMatchObject({ - borderRadius: 12, - legacyOnlyMetric: 42, - }); - expect(theme.host.palette?.Bkg).toBe('#101010'); - expect(theme.host.colors?.AppPrimary).toBe('#202020'); - expect(theme.host.appearance).toBe('light'); - expect(theme.typography.weights.semiBold).toBe('700'); - }); - - it('uses declared canonical sources when several Flex roles share one legacy path', () => { - const theme = themeFromFlexTokens(createTokens(), light); - - expect(theme.colors.brandBackground2).toBe('#111111'); - expect(theme.colors.neutralBackground2).toBe('#444444'); - expect(theme.colors.black).toBe('#050505'); - expect(theme.components.Button).toMatchObject({ - tokens: { - borderRadius: 12, - }, - }); - expect(theme.typography.weights.semiBold).toBe('700'); - }); - - it('does not mutate frozen author inputs and returns a fresh legacy root', () => { - const tokens = Object.freeze(createTokens()); - const fallback = Object.freeze({ - colors: Object.freeze({ - customLegacyColor: '#abcdef', - }), - }) as PartialTheme; - - const first = themeFromFlexTokens(tokens, light, { fallback }); - const second = themeFromFlexTokens(tokens, light, { fallback }); - - expect(first).not.toBe(second); - expect(first.colors.customLegacyColor).toBe('#abcdef'); - expect(tokens.color.surfaceNeutralNear).toBe('#444444'); - }); -}); diff --git a/packages/agentic/design/src/theming/compat/themeFromFlexTokens.ts b/packages/agentic/design/src/theming/compat/themeFromFlexTokens.ts deleted file mode 100644 index 85c89bc6628..00000000000 --- a/packages/agentic/design/src/theming/compat/themeFromFlexTokens.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { FlexTokens } from '../../tokens/flex.types'; -import reverseProjection from '../../tokens/mappings/theme-from-flex.json' with { type: 'json' }; -import { appearanceOptionFromResolved } from '../appearance'; -import type { ResolvedThemeAppearance } from '../appearance.types'; -import { mergeTheme } from '../mergeTheme'; -import type { PartialTheme, Theme } from '../types/Theme.types'; - -import { getDefaultLegacyTheme } from './defaultLegacyTheme'; - -type ReverseTransform = 'numberToPx'; - -type ReverseProjectionEntry = { - source: string; - fallback?: string; - transform?: ReverseTransform; -}; - -export interface ThemeFromFlexTokensOptions { - fallback?: Theme | PartialTheme; -} - -const unsafePathSegments = new Set(['__proto__', 'constructor', 'prototype']); - -function getPathSegments(path: string): string[] { - const segments = path.split('.'); - if (segments.some((segment) => segment.length === 0 || unsafePathSegments.has(segment))) { - throw new Error(`Invalid generated theme projection path "${path}".`); - } - return segments; -} - -function isRecord(value: unknown): value is Record<string, unknown> { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -function getValueAtPath(source: object, path: string): unknown { - let value: unknown = source; - for (const segment of getPathSegments(path)) { - if (!isRecord(value) || !Object.prototype.hasOwnProperty.call(value, segment)) { - return undefined; - } - value = value[segment]; - } - return value; -} - -function setValueAtPath(destination: Record<string, unknown>, path: string, value: unknown): void { - const segments = getPathSegments(path); - let target = destination; - for (const segment of segments.slice(0, -1)) { - const existing = target[segment]; - if (existing === undefined) { - const nested: Record<string, unknown> = {}; - target[segment] = nested; - target = nested; - } else if (isRecord(existing)) { - target = existing; - } else { - throw new Error(`Cannot create generated theme projection path "${path}".`); - } - } - target[segments[segments.length - 1]] = value; -} - -function applyTransform(value: unknown, transform?: ReverseTransform): unknown { - if (!transform) { - return value; - } - if (transform === 'numberToPx') { - return typeof value === 'number' ? `${value}px` : value; - } - return value; -} - -function projectThemeValues(tokens: FlexTokens): PartialTheme { - const projected: Record<string, unknown> = {}; - for (const [themePath, descriptor] of Object.entries(reverseProjection as Record<string, ReverseProjectionEntry>)) { - let value = getValueAtPath(tokens, descriptor.source); - if (value === undefined && descriptor.fallback) { - value = getValueAtPath(tokens, descriptor.fallback); - } - if (value !== undefined) { - setValueAtPath(projected, themePath, applyTransform(value, descriptor.transform)); - } - } - return projected as PartialTheme; -} - -/** - * Project Flex tokens into a complete legacy Theme. - * - * The compatibility base fills legacy-only values, the optional fallback adds - * author or host metadata, mapped Flex values remain authoritative, and the - * final host appearance reflects the resolved structured appearance. - */ -export function themeFromFlexTokens( - tokens: FlexTokens, - appearance: ResolvedThemeAppearance, - options?: { fallback?: Theme | PartialTheme }, -): Theme { - let theme = getDefaultLegacyTheme(appearance); - if (options?.fallback) { - theme = mergeTheme(theme, options.fallback as PartialTheme); - } - theme = mergeTheme(theme, projectThemeValues(tokens)); - return mergeTheme(theme, { - host: { - appearance: appearanceOptionFromResolved(appearance), - }, - }); -} diff --git a/packages/agentic/design/src/theming/context.ts b/packages/agentic/design/src/theming/context.ts index 1e77b68f006..dbb6e1195c9 100644 --- a/packages/agentic/design/src/theming/context.ts +++ b/packages/agentic/design/src/theming/context.ts @@ -1,11 +1,11 @@ import * as React from 'react'; import { appearanceOptionsFromLegacy, resolveThemeAppearance } from './appearance'; -import type { ResolvedThemeAppearance, ThemeAppearanceSource, ThemeAppearanceState } from './appearance.types'; +import type { ResolvedThemeAppearance, ThemeAppearanceSource, ThemeAppearanceState } from '../types/appearance.types'; import { platformAppearance } from './platformAppearance'; import type { ThemeSource } from './themeSource'; import { legacyThemeSourceFromTheme } from './themeSource'; -import type { Theme } from './types/Theme.types'; +import type { Theme } from '../fluent/types/Theme.types'; export const ThemeContext = React.createContext<Theme>(undefined); diff --git a/packages/agentic/design/src/theming/flexThemeReference.test.ts b/packages/agentic/design/src/theming/flexThemeReference.test.ts deleted file mode 100644 index 288d62d8916..00000000000 --- a/packages/agentic/design/src/theming/flexThemeReference.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { defaultResolvedThemeAppearance } from './appearance'; -import { FlexThemeReference } from './flexThemeReference'; - -const darkAppearance = { - colorScheme: 'dark', - contrast: 'standard', - interfaceLevel: 'base', -} as const; - -describe('FlexThemeReference', () => { - it('resolves one stable token object per appearance', () => { - const reference = new FlexThemeReference({}, (_tokens, appearance) => ({ - color: { - backgroundBrandHeavy: appearance.colorScheme === 'dark' ? '#111111' : '#eeeeee', - }, - })); - - const light = reference.resolveFlexTokens(defaultResolvedThemeAppearance); - const lightAgain = reference.resolveFlexTokens(defaultResolvedThemeAppearance); - const dark = reference.resolveFlexTokens(darkAppearance); - - expect(lightAgain).toBe(light); - expect(dark).not.toBe(light); - expect(light.color.backgroundBrandHeavy).toBe('#eeeeee'); - expect(dark.color.backgroundBrandHeavy).toBe('#111111'); - }); - - it('replaces all appearance identities after invalidation', () => { - const reference = new FlexThemeReference(); - const before = reference.resolveFlexTokens(defaultResolvedThemeAppearance); - - reference.invalidate(); - - expect(reference.revision).toBe(1); - expect(reference.resolveFlexTokens(defaultResolvedThemeAppearance)).not.toBe(before); - }); - - it('updates recipes and notifies subscribed consumers', () => { - const reference = new FlexThemeReference(); - const listener = jest.fn(); - reference.addOnThemeChanged(listener); - - reference.update({ color: { backgroundBrandHeavy: '#123456' } }); - - expect(listener).toHaveBeenCalledTimes(1); - expect(reference.resolveFlexTokens(defaultResolvedThemeAppearance).color.backgroundBrandHeavy).toBe('#123456'); - }); - - it('inherits source configuration and composes legacy fallbacks from a parent reference', () => { - const appearanceSource = { - getSnapshot: () => defaultResolvedThemeAppearance, - subscribe: () => () => undefined, - }; - const parent = new FlexThemeReference({ - appearance: { colorScheme: 'dark' }, - fallbackAppearance: darkAppearance, - appearanceSource, - legacyFallback: { components: { ParentComponent: { tokens: { parent: true } } } }, - }); - const child = new FlexThemeReference({ - base: parent, - legacyFallback: { components: { ChildComponent: { tokens: { child: true } } } }, - }); - - expect(child.appearanceOptions).toBe(parent.appearanceOptions); - expect(child.fallbackAppearance).toBe(parent.fallbackAppearance); - expect(child.appearanceSource).toBe(appearanceSource); - expect(child.resolveLegacyFallback(darkAppearance)?.components).toEqual({ - ParentComponent: { tokens: { parent: true } }, - ChildComponent: { tokens: { child: true } }, - }); - }); - - it('synchronizes a parent invalidation before exposing its revision', () => { - const parent = new FlexThemeReference(); - const child = new FlexThemeReference({ base: parent }); - const initial = child.resolveFlexTokens(defaultResolvedThemeAppearance); - - parent.invalidate(); - - expect(child.revision).toBe(1); - expect(child.resolveFlexTokens(defaultResolvedThemeAppearance)).not.toBe(initial); - }); -}); diff --git a/packages/agentic/design/src/theming/flexThemeReference.ts b/packages/agentic/design/src/theming/flexThemeReference.ts deleted file mode 100644 index e0f468e9e6a..00000000000 --- a/packages/agentic/design/src/theming/flexThemeReference.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { immutableMerge } from '@fluentui-react-native/framework-base'; - -import { defaultFlexTokens } from '../tokens/defaultTokens'; -import type { - FlexTokens, - InteractiveColorOverrides, - SemanticBorderRadii, - SemanticColorTokenValues, - SemanticFontFamilies, - SemanticFontSizes, - SemanticFontWeights, - SemanticLineHeights, - SemanticShadows, - SemanticSpacing, - SemanticStrokeWidths, -} from '../tokens/flex.types'; -import { themeAppearanceKey } from './appearance'; -import type { ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceSource } from './appearance.types'; -import type { FlexThemeSource, OnThemeChange } from './themeSource'; -import type { PartialTheme, Theme } from './types/Theme.types'; - -export type PartialFlexTokens = { - color?: Partial<SemanticColorTokenValues> & { - hover?: Partial<InteractiveColorOverrides>; - pressed?: Partial<InteractiveColorOverrides>; - }; - shadow?: Partial<SemanticShadows>; - fontWeight?: Partial<SemanticFontWeights>; - fontFamily?: Partial<SemanticFontFamilies>; - fontSize?: Partial<SemanticFontSizes>; - lineHeight?: Partial<SemanticLineHeights>; - borderRadius?: Partial<SemanticBorderRadii>; - spacing?: Partial<SemanticSpacing>; - strokeWidth?: Partial<SemanticStrokeWidths>; -}; - -export type FlexThemeInput = FlexTokens | PartialFlexTokens | ((appearance: ResolvedThemeAppearance) => FlexTokens | PartialFlexTokens); - -export type FlexThemeRecipe = PartialFlexTokens | ((parent: FlexTokens, appearance: ResolvedThemeAppearance) => PartialFlexTokens); - -export type LegacyThemeFallback = Theme | PartialTheme | ((appearance: ResolvedThemeAppearance) => Theme | PartialTheme); - -export interface FlexThemeReferenceOptions { - base?: FlexThemeInput | FlexThemeReference; - appearance?: ThemeAppearanceOptions; - fallbackAppearance?: Partial<ResolvedThemeAppearance>; - appearanceSource?: ThemeAppearanceSource; - legacyFallback?: LegacyThemeFallback; -} - -export class FlexThemeReference implements FlexThemeSource { - public readonly kind = 'flex'; - public readonly appearanceOptions?: ThemeAppearanceOptions; - public readonly fallbackAppearance?: Partial<ResolvedThemeAppearance>; - public readonly appearanceSource?: ThemeAppearanceSource; - - private revisionValue = 0; - private readonly base?: FlexThemeInput | FlexThemeReference; - private readonly legacyFallback?: LegacyThemeFallback; - private recipes: FlexThemeRecipe[]; - private readonly listeners = new Set<OnThemeChange>(); - private readonly tokensByAppearance = new Map<string, FlexTokens>(); - private parentListener?: OnThemeChange; - private parentRevision?: number; - - public constructor(options: FlexThemeReferenceOptions = {}, ...recipes: FlexThemeRecipe[]) { - this.base = options.base; - const parent = options.base instanceof FlexThemeReference ? options.base : undefined; - this.appearanceOptions = options.appearance ?? parent?.appearanceOptions; - this.fallbackAppearance = options.fallbackAppearance ?? parent?.fallbackAppearance; - this.appearanceSource = options.appearanceSource ?? parent?.appearanceSource; - this.legacyFallback = options.legacyFallback; - this.recipes = recipes; - this.parentRevision = parent?.revision; - } - - public get revision(): number { - this.syncParentRevision(); - return this.revisionValue; - } - - public resolveFlexTokens(appearance: ResolvedThemeAppearance): FlexTokens { - this.syncParentRevision(); - const key = themeAppearanceKey(appearance); - const cached = this.tokensByAppearance.get(key); - if (cached) { - return cached; - } - - let tokens = this.resolveBase(appearance); - for (const recipe of this.recipes) { - tokens = immutableMerge(tokens, typeof recipe === 'function' ? recipe(tokens, appearance) : recipe); - } - tokens = { ...tokens }; - this.tokensByAppearance.set(key, tokens); - return tokens; - } - - public resolveLegacyFallback(appearance: ResolvedThemeAppearance): Theme | PartialTheme | undefined { - const parentFallback = this.base instanceof FlexThemeReference ? this.base.resolveLegacyFallback(appearance) : undefined; - const fallback = typeof this.legacyFallback === 'function' ? this.legacyFallback(appearance) : this.legacyFallback; - return parentFallback && fallback ? immutableMerge(parentFallback, fallback) : (fallback ?? parentFallback); - } - - public addOnThemeChanged(listener: OnThemeChange): void { - this.listeners.add(listener); - if (this.listeners.size === 1 && this.base instanceof FlexThemeReference) { - this.parentListener = () => { - this.parentRevision = this.base instanceof FlexThemeReference ? this.base.revision : undefined; - this.invalidate(); - }; - this.base.addOnThemeChanged(this.parentListener); - } - } - - public removeOnThemeChanged(listener: OnThemeChange): void { - this.listeners.delete(listener); - if (this.listeners.size === 0 && this.parentListener && this.base instanceof FlexThemeReference) { - this.base.removeOnThemeChanged(this.parentListener); - this.parentListener = undefined; - } - } - - public invalidate(): void { - this.revisionValue += 1; - this.tokensByAppearance.clear(); - for (const listener of this.listeners) { - listener(); - } - } - - public update(...recipes: FlexThemeRecipe[]): void { - this.recipes = recipes; - this.invalidate(); - } - - private resolveBase(appearance: ResolvedThemeAppearance): FlexTokens { - if (this.base instanceof FlexThemeReference) { - return this.base.resolveFlexTokens(appearance); - } - const base = typeof this.base === 'function' ? this.base(appearance) : this.base; - return base ? immutableMerge(defaultFlexTokens, base) : defaultFlexTokens; - } - - private syncParentRevision(): void { - if (this.base instanceof FlexThemeReference && this.parentRevision !== this.base.revision) { - this.parentRevision = this.base.revision; - this.invalidate(); - } - } -} diff --git a/packages/agentic/design/src/theming/index.ts b/packages/agentic/design/src/theming/index.ts index 5ac164bac49..57a81fabd2c 100644 --- a/packages/agentic/design/src/theming/index.ts +++ b/packages/agentic/design/src/theming/index.ts @@ -7,10 +7,18 @@ export type { PaletteTextColors, PartialPalette, ThemeColorDefinition, -} from './types/Color.types'; -export type { ShadowValue, ShadowToken, BaseShadowAliasTokens, ThemeShadowDefinition, PartialShadowDefinition } from './types/Shadow.types'; -export type { AppearanceOptions, PartialTheme, Spacing, Theme, ThemeOptions } from './types/Theme.types'; +} from '../fluent/types/Color.types'; export type { + ShadowValue, + ShadowToken, + BaseShadowAliasTokens, + ThemeShadowDefinition, + PartialShadowDefinition, +} from '../fluent/types/Shadow.types'; +export type { AppearanceOptions, PartialTheme, Spacing, Theme, ThemeOptions } from '../fluent/types/Theme.types'; +export type { + ColorTone, + NormalizedThemeAppearance, ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceRequest, @@ -21,7 +29,7 @@ export type { ThemeColorScheme, ThemeContrast, ThemeInterfaceLevel, -} from './appearance.types'; +} from '../types/appearance.types'; export { appearanceOptionFromResolved, appearanceOptionsFromLegacy, @@ -47,10 +55,10 @@ export type { Variant, VariantValue, Variants, -} from './types/Typography.types'; +} from '../fluent/types/Typography.types'; export { ThemeContext } from './context'; -export { useTheme } from './useTheme'; -export type { OfficePalette } from './types/palette.types'; +export { useTheme } from '../fluent/useTheme'; +export type { OfficePalette } from '../fluent/types/palette.types'; export { ThemeProvider } from './ThemeProvider'; export type { ThemeProviderProps } from './ThemeProvider'; export { ThemedRoot } from './ThemedRoot'; @@ -59,17 +67,14 @@ export { RootContext, useRootSettings } from './rootContext'; export { RootInputBoundary } from './RootInputBoundary'; export { useRootInputModality } from './useRootInputModality'; export type { InputModality, RootSettings } from './rootContext'; -export { FlexThemeReference } from './flexThemeReference'; -export type { - FlexThemeInput, - FlexThemeRecipe, - FlexThemeReferenceOptions, - LegacyThemeFallback, - PartialFlexTokens, -} from './flexThemeReference'; -export { ThemeReference } from './themeReference'; -export type { OnThemeChange, ThemeRecipe, ThemeReferenceOptions, ThemeTransform } from './themeReference'; +export { FlexThemeReference } from '../flex/flexThemeReference'; +export type { FlexThemeInput, FlexThemeRecipe, FlexThemeReferenceOptions, LegacyThemeFallback } from '../flex/flexThemeReference'; +export type { FlexThemeDescription } from '../flex/themeState.types'; +export { flexColor, selectColorEntry } from '../flex/colors/flexColor'; +export type { ColorSchemeSelector } from '../flex/colors/flexColor'; +export { selectShadowEntry } from '../flex/flexShadow'; +export type { FlexTokenDescription, PartialFlexTokens } from '../flex/tokens.types'; +export { ThemeReference } from '../fluent/themeReference'; +export type { OnThemeChange, ThemeRecipe, ThemeReferenceOptions, ThemeTransform } from '../fluent/themeReference'; export type { FlexThemeSource, LegacyThemeSource, ThemeSource, ThemeSourceBase } from './themeSource'; -export { getCurrentAppearance, isHighContrast, setIsHighContrast } from './platformUtils'; -export { mapFontPipelineToTheme, mapPipelineToTheme } from './mapPipelineToTheme'; -export { mapPipelineToShadow } from './mapPipelineToShadow'; +export { getCurrentAppearance, isHighContrast, setIsHighContrast } from '../fluent/platformUtils'; diff --git a/packages/agentic/design/src/theming/modern.ts b/packages/agentic/design/src/theming/modern.ts index 1e831974177..5d96fc6e135 100644 --- a/packages/agentic/design/src/theming/modern.ts +++ b/packages/agentic/design/src/theming/modern.ts @@ -1,4 +1,6 @@ export type { + ColorTone, + NormalizedThemeAppearance, ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceRequest, @@ -9,7 +11,7 @@ export type { ThemeColorScheme, ThemeContrast, ThemeInterfaceLevel, -} from './appearance.types'; +} from '../types/appearance.types'; export { appearanceOptionFromResolved, appearanceOptionsFromLegacy, @@ -18,14 +20,13 @@ export { themeAppearanceKey, } from './appearance'; export { createThemeAppearanceSource } from './appearanceSource'; -export { FlexThemeReference } from './flexThemeReference'; -export type { - FlexThemeInput, - FlexThemeRecipe, - FlexThemeReferenceOptions, - LegacyThemeFallback, - PartialFlexTokens, -} from './flexThemeReference'; +export { FlexThemeReference } from '../flex/flexThemeReference'; +export type { FlexThemeInput, FlexThemeRecipe, FlexThemeReferenceOptions, LegacyThemeFallback } from '../flex/flexThemeReference'; +export type { FlexThemeDescription } from '../flex/themeState.types'; +export { flexColor, selectColorEntry } from '../flex/colors/flexColor'; +export type { ColorSchemeSelector } from '../flex/colors/flexColor'; +export { selectShadowEntry } from '../flex/flexShadow'; +export type { FlexTokenDescription, PartialFlexTokens } from '../flex/tokens.types'; export { ThemeProvider } from './ThemeProvider'; export type { ThemeProviderProps } from './ThemeProvider'; export { ThemedRoot } from './ThemedRoot'; diff --git a/packages/agentic/design/src/theming/themeRuntime.ts b/packages/agentic/design/src/theming/themeRuntime.ts index 0c6264fd826..684eb46176c 100644 --- a/packages/agentic/design/src/theming/themeRuntime.ts +++ b/packages/agentic/design/src/theming/themeRuntime.ts @@ -1,39 +1,29 @@ -import { defaultFlexTokens } from '../tokens/defaultTokens'; -import type { FlexTokens } from '../tokens/flex.types'; -import { flexTokensFromTheme } from '../tokens/flexTokensFromTheme'; -import { defaultResolvedThemeAppearance, themeAppearanceKey } from './appearance'; -import type { ResolvedThemeAppearance } from './appearance.types'; -import type { ThemeSource } from './themeSource'; - -export type ThemeStyleRegistry = Record<symbol, unknown>; - -export interface RuntimeThemeState { - readonly tokens: FlexTokens; - readonly appearance: Readonly<ResolvedThemeAppearance>; - readonly highContrast: boolean; - readonly themeStyles: ThemeStyleRegistry; -} - -type AppearanceCache = { +import { themeAppearanceKey } from './appearance'; +import type { FlexTokens } from '../flex/tokens.types'; +import type { ResolvedThemeAppearance } from '../types/appearance.types'; +import type { ThemeState } from '../flex/themeState.types'; +import type { FlexThemeSource, ThemeSource } from './themeSource'; + +/** + * Values derived from one source revision and one resolved appearance. + */ +export type ThemeAppearanceCache = { flexTokens?: FlexTokens; - themeState?: RuntimeThemeState; + themeState?: ThemeState; }; type SourceCache = { revision: number; - byAppearance: Map<string, AppearanceCache>; + byAppearance: Map<string, ThemeAppearanceCache>; }; const sourceCaches = new WeakMap<ThemeSource, SourceCache>(); -export const defaultThemeState: RuntimeThemeState = { - tokens: defaultFlexTokens, - appearance: defaultResolvedThemeAppearance, - highContrast: false, - themeStyles: {}, -}; - -function getAppearanceCache(source: ThemeSource, appearance: ResolvedThemeAppearance): AppearanceCache { +/** + * Return the revision-scoped cache for one source and appearance. A source + * revision change replaces every entry for that source. + */ +export function getThemeAppearanceCache(source: ThemeSource, appearance: ResolvedThemeAppearance): ThemeAppearanceCache { let sourceCache = sourceCaches.get(source); if (!sourceCache || sourceCache.revision !== source.revision) { sourceCache = { revision: source.revision, byAppearance: new Map() }; @@ -49,23 +39,14 @@ function getAppearanceCache(source: ThemeSource, appearance: ResolvedThemeAppear return appearanceCache; } -export function getFlexTokens(source: ThemeSource, appearance: ResolvedThemeAppearance): FlexTokens { - const cache = getAppearanceCache(source, appearance); +/** + * Resolve Flex tokens from a Flex-authored source. This shared helper never + * reaches the legacy forward adapter, so legacy-only graphs stay free of it. + */ +export function getFlexSourceTokens(source: FlexThemeSource, appearance: ResolvedThemeAppearance): FlexTokens { + const cache = getThemeAppearanceCache(source, appearance); if (!cache.flexTokens) { - cache.flexTokens = source.kind === 'flex' ? source.resolveFlexTokens(appearance) : flexTokensFromTheme(source.resolveTheme(appearance)); + cache.flexTokens = source.resolveFlexTokens(appearance); } return cache.flexTokens; } - -export function getThemeState(source: ThemeSource, appearance: ResolvedThemeAppearance): RuntimeThemeState { - const cache = getAppearanceCache(source, appearance); - if (!cache.themeState) { - cache.themeState = { - tokens: getFlexTokens(source, appearance), - appearance, - highContrast: appearance.contrast === 'highContrast', - themeStyles: {}, - }; - } - return cache.themeState; -} diff --git a/packages/agentic/design/src/theming/themeSource.ts b/packages/agentic/design/src/theming/themeSource.ts index 21d2a914807..bc02da2c699 100644 --- a/packages/agentic/design/src/theming/themeSource.ts +++ b/packages/agentic/design/src/theming/themeSource.ts @@ -1,6 +1,6 @@ -import type { FlexTokens } from '../tokens/flex.types'; -import type { ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceSource } from './appearance.types'; -import type { PartialTheme, Theme } from './types/Theme.types'; +import type { FlexTokens } from '../flex/tokens.types'; +import type { ResolvedThemeAppearance, ThemeAppearanceOptions, ThemeAppearanceSource } from '../types/appearance.types'; +import type { PartialTheme, Theme } from '../fluent/types/Theme.types'; export type OnThemeChange = () => void; diff --git a/packages/agentic/design/src/tokens/defaultTokens.ts b/packages/agentic/design/src/tokens/defaultTokens.ts deleted file mode 100644 index 10e0575d1ac..00000000000 --- a/packages/agentic/design/src/tokens/defaultTokens.ts +++ /dev/null @@ -1,473 +0,0 @@ -import { - cornerRadius120, - cornerRadius20, - cornerRadius40, - cornerRadius60, - cornerRadius80, - cornerRadiusCircular, - fontFamilyBase, - fontFamilyMonospace, - fontLineHeight100, - fontLineHeight200, - fontLineHeight300, - fontLineHeight400, - fontLineHeight500, - fontLineHeight600, - fontLineHeight800, - fontLineHeight900, - fontLineHeight1000, - fontSize100, - fontSize200, - fontSize300, - fontSize400, - fontSize500, - fontSize600, - fontSize700, - fontSize800, - fontSize900, - fontSize1000, - fontWeightBold, - fontWeightMedium, - fontWeightRegular, - fontWeightSemibold, - size20, - size40, - size60, - size80, - size100, - size120, - size160, - size200, - size240, - size280, - size320, - size360, - size400, - size480, - size560, - size640, - size800, - strokeWidth10, - strokeWidth20, - strokeWidth30, - strokeWidth40, -} from './global.generated'; -import type { FlexTokens, InteractiveColorOverrides, SemanticColorTokenValues } from './flex.types'; - -type NonFluentFlexTokens = { - [Group in Exclude<keyof FlexTokens, 'color'>]?: Partial<FlexTokens[Group]>; -} & { - color?: Partial<SemanticColorTokenValues> & { - hover?: Partial<InteractiveColorOverrides>; - pressed?: Partial<InteractiveColorOverrides>; - }; -}; - -/** - * Default values for Flex tokens that cannot be populated from a FURN Theme. - */ -export const nonFluentFlexTokens = { - color: { - surfaceNeutralTranslucent: '#ffffff80', - backgroundNeutralSoft: '#0000001a', - backgroundNeutralTranslucent: '#ffffff80', - expressionAccentHeavy: '#242424', - expressionAccentLoud: '#707070', - expressionAccentSoft: '#0000001a', - expressionAccentSubtle: '#0000000d', - expressionGrayHeavy: '#474747', - expressionGrayLoud: '#949494', - expressionGraySoft: '#e0e0e0', - expressionGraySubtle: '#f5f5f5', - expressionNavyHeavy: '#001e89', - expressionNavyLoud: '#546fd2', - expressionNavySoft: '#ccd5f3', - expressionNavySubtle: '#f2f4fc', - expressionBlueHeavy: '#004377', - expressionBlueLoud: '#3595de', - expressionBlueSoft: '#d0e7f8', - expressionBlueSubtle: '#f3f9fd', - expressionGreenHeavy: '#0c5e0c', - expressionGreenLoud: '#54b054', - expressionGreenSoft: '#c9eac9', - expressionGreenSubtle: '#f1faf1', - expressionLimeHeavy: '#405f14', - expressionLimeLoud: '#689920', - expressionLimeSoft: '#cfe5af', - expressionLimeSubtle: '#e5f1d3', - expressionYellowHeavy: '#4c4400', - expressionYellowLoud: '#fde300', - expressionYellowSoft: '#feee66', - expressionYellowSubtle: '#fef7b2', - expressionPumpkinHeavy: '#712d09', - expressionPumpkinLoud: '#df8e64', - expressionPumpkinSoft: '#f7dfd2', - expressionPumpkinSubtle: '#fdf7f4', - expressionRedHeavy: '#751d1f', - expressionRedLoud: '#dc5e62', - expressionRedSoft: '#f8dadb', - expressionRedSubtle: '#fdf6f6', - expressionPinkHeavy: '#80215d', - expressionPinkLoud: '#e750b0', - expressionPinkSoft: '#f7c0e3', - expressionPinkSubtle: '#fef6fb', - expressionPurpleHeavy: '#532982', - expressionPurpleLoud: '#9470bd', - expressionPurpleSoft: '#e0d3ed', - expressionPurpleSubtle: '#f7f4fb', - overlayNeutralTranslucent: '#ffffff80', - materialBackgroundThick: '#ffffffe6', - materialBackgroundRegular: '#ffffffcc', - materialBackgroundThin: '#ffffff80', - hover: { - surfaceNeutralTranslucent: '#ffffff80', - backgroundNeutralSoft: '#0000001a', - backgroundNeutralTranslucent: '#ffffff80', - }, - pressed: { - surfaceNeutralTranslucent: '#ffffff80', - backgroundNeutralSoft: '#0000001a', - backgroundNeutralTranslucent: '#ffffff80', - }, - }, - lineHeight: { - functionalDisplay: fontLineHeight1000, - functionalPagetitle: fontLineHeight900, - functionalTitleLarge: fontLineHeight800, - functionalTitleMedium: fontLineHeight600, - functionalTitleSmall: fontLineHeight500, - functionalSubtitle: fontLineHeight500, - functionalBodyLarge: fontLineHeight400, - functionalBodyMedium: fontLineHeight300, - functionalBodySmall: fontLineHeight200, - functionalCaption: fontLineHeight100, - contentStatement: fontLineHeight900, - contentExpressiveLarge: fontLineHeight900, - contentExpressiveMedium: fontLineHeight800, - contentExpressiveSmall: fontLineHeight600, - contentH1: fontLineHeight800, - contentH2: fontLineHeight800, - contentH3: fontLineHeight600, - contentH4: fontLineHeight500, - contentH5: fontLineHeight400, - contentSubheadline: fontLineHeight400, - contentParagraphLarge: fontLineHeight600, - contentParagraphMedium: fontLineHeight500, - contentParagraphSmall: fontLineHeight300, - contentSubtext: fontLineHeight100, - contentTable: fontLineHeight400, - contentCode: fontLineHeight400, - }, - borderRadius: { - base100: cornerRadius20, - base400: cornerRadius60, - base600: cornerRadius80, - base700: cornerRadius120, - circular: cornerRadiusCircular, - }, - spacing: { - componentBase50: size20, - componentBase100: size40, - componentBase150: size60, - componentBase200: size80, - componentBase250: size100, - componentBase300: size120, - componentBase400: size160, - componentBase500: size200, - componentBase600: size240, - componentBase700: size280, - layoutBase100: size80, - layoutBase200: size160, - layoutBase300: size240, - layoutBase400: size320, - layoutBase450: size360, - layoutBase500: size400, - layoutBase600: size480, - layoutBase700: size560, - layoutBase800: size640, - layoutBase1000: size800, - layoutBase1200: size800, - }, - strokeWidth: { - thin: strokeWidth10, - thick: strokeWidth20, - thicker: strokeWidth30, - thickest: strokeWidth40, - }, -} satisfies NonFluentFlexTokens; - -/** - * Default grouped Flex token values. Theme-backed values use the current native - * defaults, layered over values that have no FURN Theme source. - */ -export const defaultFlexTokens: FlexTokens = { - ...nonFluentFlexTokens, - color: { - ...nonFluentFlexTokens.color, - surfaceNeutralFarther: '#ebebeb', - surfaceNeutralFar: '#f5f5f5', - surfaceNeutralNear: '#fafafa', - surfaceNeutralNearer: '#ffffff', - backgroundNeutralHeavy: '#616161', - backgroundNeutralLoud: '#616161', - backgroundNeutralSubtle: '#fafafa', - backgroundNeutralTransparent: '#00000000', - backgroundBrandHeavy: '#185abd', - backgroundBrandLoud: '#185abd', - backgroundBrandSoft: '#d2e0f4', - backgroundBrandSubtle: '#d2e0f4', - backgroundBrandTransparent: '#00000000', - backgroundDangerLoud: '#d13438', - backgroundDangerSoft: '#f1bbbc', - backgroundDangerSubtle: '#fdf6f6', - backgroundWarningLoud: '#fde300', - backgroundWarningSoft: '#fef7b2', - backgroundWarningSubtle: '#fffef5', - backgroundSuccessLoud: '#107c10', - backgroundSuccessSoft: '#9fd89f', - backgroundSuccessSubtle: '#f1faf1', - strokeNeutralHeavy: '#616161', - strokeNeutralLoud: '#d1d1d1', - strokeNeutralSoft: '#d1d1d1', - strokeNeutralSubtle: '#e0e0e0', - strokeNeutralTransparent: '#00000000', - strokeNeutralOnloud: '#ffffff', - strokeBrandLoud: '#185abd', - strokeBrandSoft: '#185abd', - strokeBrandSubtle: '#6794d7', - strokeBrandOnloud: '#ffffff', - strokeDangerLoud: '#d13438', - strokeDangerSoft: '#f1bbbc', - strokeDangerSubtle: '#f1bbbc', - strokeDangerOnloud: '#ffffff', - strokeWarningLoud: '#fde300', - strokeWarningSoft: '#fef7b2', - strokeWarningSubtle: '#fef7b2', - strokeWarningOnloud: '#ffffff', - strokeSuccessLoud: '#107c10', - strokeSuccessSoft: '#9fd89f', - strokeSuccessSubtle: '#9fd89f', - strokeSuccessOnloud: '#ffffff', - foregroundNeutralPrimary: '#242424', - foregroundNeutralSecondary: '#424242', - foregroundNeutralTertiary: '#616161', - foregroundNeutralOnloud: '#ffffff', - foregroundBrandPrimary: '#185abd', - foregroundBrandOnloud: '#ffffff', - foregroundDangerPrimary: '#bc2f32', - foregroundDangerOnloud: '#ffffff', - foregroundWarningPrimary: '#817400', - foregroundWarningOnloud: '#ffffff', - foregroundSuccessPrimary: '#0e700e', - foregroundSuccessOnloud: '#ffffff', - fixedWhite: '#ffffff', - fixedBlack: '#000000', - expressionAchromaticHeavy: '#000000', - expressionAchromaticSubtle: '#ffffff', - backgroundNeutralDisabled: '#f0f0f0', - backgroundNeutralHeavyDisabled: '#f0f0f0', - backgroundNeutralSubtleDisabled: '#f0f0f0', - strokeNeutralDisabled: '#e0e0e0', - foregroundNeutralDisabled: '#bdbdbd', - strokeFocusInner: '#ffffff', - strokeFocusOuter: '#000000', - shadow: '#000000', - hover: { - ...nonFluentFlexTokens.color.hover, - surfaceNeutralFarther: '#f5f5f5', - surfaceNeutralFar: '#ebebeb', - surfaceNeutralNear: '#f0f0f0', - surfaceNeutralNearer: '#f5f5f5', - backgroundNeutralHeavy: '#616161', - backgroundNeutralLoud: '#616161', - backgroundNeutralSubtle: '#f0f0f0', - backgroundNeutralTransparent: '#00000000', - backgroundBrandHeavy: '#1651aa', - backgroundBrandLoud: '#1651aa', - backgroundBrandSoft: '#d2e0f4', - backgroundBrandSubtle: '#d2e0f4', - backgroundBrandTransparent: '#00000000', - backgroundDangerLoud: '#d13438', - backgroundDangerSoft: '#f1bbbc', - backgroundDangerSubtle: '#fdf6f6', - backgroundWarningLoud: '#fde300', - backgroundWarningSoft: '#fef7b2', - backgroundWarningSubtle: '#fffef5', - backgroundSuccessLoud: '#107c10', - backgroundSuccessSoft: '#9fd89f', - backgroundSuccessSubtle: '#f1faf1', - strokeNeutralHeavy: '#575757', - strokeNeutralLoud: '#c7c7c7', - strokeNeutralSoft: '#c7c7c7', - strokeNeutralSubtle: '#e0e0e0', - strokeNeutralTransparent: '#00000000', - strokeNeutralOnloud: '#ffffff', - strokeBrandLoud: '#185abd', - strokeBrandSoft: '#185abd', - strokeBrandSubtle: '#6794d7', - strokeBrandOnloud: '#ffffff', - strokeDangerLoud: '#d13438', - strokeDangerSoft: '#f1bbbc', - strokeDangerSubtle: '#f1bbbc', - strokeDangerOnloud: '#ffffff', - strokeWarningLoud: '#fde300', - strokeWarningSoft: '#fef7b2', - strokeWarningSubtle: '#fef7b2', - strokeWarningOnloud: '#ffffff', - strokeSuccessLoud: '#107c10', - strokeSuccessSoft: '#9fd89f', - strokeSuccessSubtle: '#9fd89f', - strokeSuccessOnloud: '#ffffff', - foregroundNeutralPrimary: '#242424', - foregroundNeutralSecondary: '#242424', - foregroundNeutralTertiary: '#424242', - foregroundNeutralOnloud: '#ffffff', - foregroundBrandPrimary: '#185abd', - foregroundBrandOnloud: '#ffffff', - foregroundDangerPrimary: '#bc2f32', - foregroundDangerOnloud: '#ffffff', - foregroundWarningPrimary: '#817400', - foregroundWarningOnloud: '#ffffff', - foregroundSuccessPrimary: '#0e700e', - foregroundSuccessOnloud: '#ffffff', - }, - pressed: { - ...nonFluentFlexTokens.color.pressed, - surfaceNeutralFarther: '#f0f0f0', - surfaceNeutralFar: '#d6d6d6', - surfaceNeutralNear: '#dbdbdb', - surfaceNeutralNearer: '#e0e0e0', - backgroundNeutralHeavy: '#616161', - backgroundNeutralLoud: '#616161', - backgroundNeutralSubtle: '#dbdbdb', - backgroundNeutralTransparent: '#00000000', - backgroundBrandHeavy: '#0e336a', - backgroundBrandLoud: '#0e336a', - backgroundBrandSoft: '#d2e0f4', - backgroundBrandSubtle: '#d2e0f4', - backgroundBrandTransparent: '#00000000', - backgroundDangerLoud: '#d13438', - backgroundDangerSoft: '#f1bbbc', - backgroundDangerSubtle: '#fdf6f6', - backgroundWarningLoud: '#fde300', - backgroundWarningSoft: '#fef7b2', - backgroundWarningSubtle: '#fffef5', - backgroundSuccessLoud: '#107c10', - backgroundSuccessSoft: '#9fd89f', - backgroundSuccessSubtle: '#f1faf1', - strokeNeutralHeavy: '#4d4d4d', - strokeNeutralLoud: '#b3b3b3', - strokeNeutralSoft: '#b3b3b3', - strokeNeutralSubtle: '#e0e0e0', - strokeNeutralTransparent: '#00000000', - strokeNeutralOnloud: '#ffffff', - strokeBrandLoud: '#185abd', - strokeBrandSoft: '#185abd', - strokeBrandSubtle: '#6794d7', - strokeBrandOnloud: '#ffffff', - strokeDangerLoud: '#d13438', - strokeDangerSoft: '#f1bbbc', - strokeDangerSubtle: '#f1bbbc', - strokeDangerOnloud: '#ffffff', - strokeWarningLoud: '#fde300', - strokeWarningSoft: '#fef7b2', - strokeWarningSubtle: '#fef7b2', - strokeWarningOnloud: '#ffffff', - strokeSuccessLoud: '#107c10', - strokeSuccessSoft: '#9fd89f', - strokeSuccessSubtle: '#9fd89f', - strokeSuccessOnloud: '#ffffff', - foregroundNeutralPrimary: '#242424', - foregroundNeutralSecondary: '#242424', - foregroundNeutralTertiary: '#424242', - foregroundNeutralOnloud: '#ffffff', - foregroundBrandPrimary: '#185abd', - foregroundBrandOnloud: '#ffffff', - foregroundDangerPrimary: '#bc2f32', - foregroundDangerOnloud: '#ffffff', - foregroundWarningPrimary: '#817400', - foregroundWarningOnloud: '#ffffff', - foregroundSuccessPrimary: '#0e700e', - foregroundSuccessOnloud: '#ffffff', - }, - }, - shadow: { - lowest: { - ambient: { color: '#0000001f', x: 0, y: 0, blur: 2 }, - key: { color: '#00000024', x: 0, y: 1, blur: 2 }, - }, - lower: { - ambient: { color: '#0000001f', x: 0, y: 0, blur: 2 }, - key: { color: '#00000024', x: 0, y: 2, blur: 4 }, - }, - low: { - ambient: { color: '#0000001f', x: 0, y: 0, blur: 2 }, - key: { color: '#00000024', x: 0, y: 4, blur: 8 }, - }, - high: { - ambient: { color: '#0000001f', x: 0, y: 0, blur: 2 }, - key: { color: '#00000024', x: 0, y: 8, blur: 16 }, - }, - higher: { - ambient: { color: '#00000033', x: 0, y: 0, blur: 8 }, - key: { color: '#0000003d', x: 0, y: 14, blur: 28 }, - }, - highest: { - ambient: { color: '#00000033', x: 0, y: 0, blur: 8 }, - key: { color: '#0000003d', x: 0, y: 32, blur: 64 }, - }, - }, - fontWeight: { - functionalRegular: fontWeightRegular, - functionalMedium: fontWeightMedium, - functionalSemibold: fontWeightSemibold, - functionalBold: fontWeightBold, - contentRegular: fontWeightRegular, - contentMedium: fontWeightMedium, - contentSemibold: fontWeightSemibold, - contentBold: fontWeightBold, - contentEditorialRegular: fontWeightRegular, - contentEditorialMedium: fontWeightMedium, - contentEditorialSemibold: fontWeightSemibold, - contentEditorialBold: fontWeightBold, - }, - fontFamily: { - functional: fontFamilyBase, - content: fontFamilyBase, - contentEditorial: fontFamilyBase, - contentCode: fontFamilyMonospace, - }, - fontSize: { - functionalDisplay: fontSize1000, - functionalPagetitle: fontSize900, - functionalTitleLarge: fontSize800, - functionalTitleMedium: fontSize700, - functionalTitleSmall: fontSize600, - functionalSubtitle: fontSize500, - functionalBodyLarge: fontSize400, - functionalBodyMedium: fontSize300, - functionalBodySmall: fontSize200, - functionalCaption: fontSize100, - contentStatement: fontSize1000, - contentExpressiveLarge: fontSize900, - contentExpressiveMedium: fontSize800, - contentExpressiveSmall: fontSize700, - contentH1: fontSize800, - contentH2: fontSize800, - contentH3: fontSize700, - contentH4: fontSize600, - contentH5: fontSize500, - contentSubheadline: fontSize400, - contentParagraphLarge: fontSize500, - contentParagraphMedium: fontSize400, - contentParagraphSmall: fontSize200, - contentSubtext: fontSize100, - contentTable: fontSize400, - contentCode: fontSize400, - }, - borderRadius: { - ...nonFluentFlexTokens.borderRadius, - base200: cornerRadius40, - base300: cornerRadius40, - }, -}; diff --git a/packages/agentic/design/src/tokens/flex.test.ts b/packages/agentic/design/src/tokens/flex.test.ts deleted file mode 100644 index dffebf4efd7..00000000000 --- a/packages/agentic/design/src/tokens/flex.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { defaultFlexTokens, nonFluentFlexTokens } from './defaultTokens'; -import type { FlexTokens, SemanticColorTokenValues } from './flex.types'; - -const colorTokens: SemanticColorTokenValues = defaultFlexTokens.color; -const flexTokens: FlexTokens = defaultFlexTokens; -const flexFromTheme = jest.requireActual<Record<string, string>>('./mappings/flex-from-theme.json'); - -function getTokenPaths(tokens: object, color: { hover: object; pressed: object }): string[] { - const colorPaths = Object.keys(color) - .filter((name) => name !== 'hover' && name !== 'pressed') - .map((name) => `color.${name}`); - const interactiveColorPaths = ['hover', 'pressed'].flatMap((state) => Object.keys(color[state]).map((name) => `color.${state}.${name}`)); - const groupPaths = Object.entries(tokens) - .filter(([group]) => group !== 'color') - .flatMap(([group, values]) => Object.keys(values).map((name) => `${group}.${name}`)); - - return [...colorPaths, ...interactiveColorPaths, ...groupPaths].sort(); -} - -describe('FlexTokens', () => { - it('groups tokens and removes category prefixes from their names', () => { - expect(flexTokens.color.surfaceNeutralFarther).toBe('#ebebeb'); - expect(flexTokens.color.hover.surfaceNeutralFarther).toBe('#f5f5f5'); - expect(flexTokens.color.pressed.surfaceNeutralFarther).toBe('#f0f0f0'); - expect(flexTokens.shadow.lowest.key.blur).toBe(2); - expect(flexTokens.fontWeight.functionalRegular).toBe('400'); - expect(flexTokens.fontFamily.functional).toBeTruthy(); - expect(flexTokens.fontSize.functionalBodyMedium).toBeGreaterThan(0); - expect(flexTokens.lineHeight.functionalBodyMedium).toBeGreaterThan(0); - expect(flexTokens.borderRadius.base100).toBeGreaterThan(0); - expect(flexTokens.spacing.componentBase100).toBeGreaterThan(0); - expect(flexTokens.strokeWidth.thin).toBeGreaterThan(0); - expect(colorTokens.backgroundBrandHeavy).toBe('#185abd'); - }); - - it('does not expose the previous flat token names', () => { - expect('colorSurfaceNeutralFarther' in flexTokens).toBe(false); - expect('shadowLowest' in flexTokens).toBe(false); - expect('fontWeightFunctionalRegular' in flexTokens).toBe(false); - }); - - it('builds defaults from values without FURN Theme sources', () => { - const themeBackedPaths = new Set(Object.keys(flexFromTheme)); - const expectedNonFluentPaths = getTokenPaths(defaultFlexTokens, defaultFlexTokens.color).filter((path) => { - if (themeBackedPaths.has(path)) { - return false; - } - - const interactiveColor = path.match(/^color\.(?:hover|pressed)\.(.+)$/); - return !interactiveColor || !themeBackedPaths.has(`color.${interactiveColor[1]}`); - }); - - expect(getTokenPaths(nonFluentFlexTokens, nonFluentFlexTokens.color)).toEqual(expectedNonFluentPaths); - expect(Object.keys(nonFluentFlexTokens)).toEqual(['color', 'lineHeight', 'borderRadius', 'spacing', 'strokeWidth']); - expect(nonFluentFlexTokens.color.backgroundNeutralSoft).toBe('#0000001a'); - expect(nonFluentFlexTokens.color.hover.backgroundNeutralSoft).toBe('#0000001a'); - expect(nonFluentFlexTokens.borderRadius.base100).toBe(2); - expect('backgroundBrandHeavy' in nonFluentFlexTokens.color).toBe(false); - expect('backgroundBrandSoft' in nonFluentFlexTokens.color.hover).toBe(false); - expect('surfaceNeutralFarther' in nonFluentFlexTokens.color.hover).toBe(false); - expect('base200' in nonFluentFlexTokens.borderRadius).toBe(false); - expect(defaultFlexTokens.lineHeight).toBe(nonFluentFlexTokens.lineHeight); - expect(defaultFlexTokens.color.backgroundNeutralSoft).toBe(nonFluentFlexTokens.color.backgroundNeutralSoft); - expect(defaultFlexTokens.color.backgroundBrandHeavy).toBe('#185abd'); - expect(defaultFlexTokens.color.hover.backgroundBrandSoft).toBe('#d2e0f4'); - }); -}); diff --git a/packages/agentic/design/src/tokens/flex.types.ts b/packages/agentic/design/src/tokens/flex.types.ts deleted file mode 100644 index 8ba74f26150..00000000000 --- a/packages/agentic/design/src/tokens/flex.types.ts +++ /dev/null @@ -1,470 +0,0 @@ -import type { ColorValue, TextStyle, ViewStyle, DimensionValue } from 'react-native'; -import type { ShadowToken } from '../theming/types/Shadow.types'; - -type FontWeight = TextStyle['fontWeight']; -type FontSize = TextStyle['fontSize']; -type BorderRadius = ViewStyle['borderRadius']; -type StrokeWidth = ViewStyle['borderWidth']; - -/** - * Every semantic color token's rest value. Interactive tokens carry only their - * rest value here; their `hover`/`pressed` states live in `SemanticColors`. - */ -export type SemanticColorTokenValues = { - // surface / neutral - surfaceNeutralFarther: ColorValue; - surfaceNeutralFar: ColorValue; - surfaceNeutralNear: ColorValue; - surfaceNeutralNearer: ColorValue; - surfaceNeutralTranslucent: ColorValue; - - // background / neutral - backgroundNeutralHeavy: ColorValue; - backgroundNeutralLoud: ColorValue; - backgroundNeutralSoft: ColorValue; - backgroundNeutralSubtle: ColorValue; - backgroundNeutralTransparent: ColorValue; - backgroundNeutralTranslucent: ColorValue; - - // background / brand - backgroundBrandHeavy: ColorValue; - backgroundBrandLoud: ColorValue; - backgroundBrandSoft: ColorValue; - backgroundBrandSubtle: ColorValue; - backgroundBrandTransparent: ColorValue; - - // background / danger - backgroundDangerLoud: ColorValue; - backgroundDangerSoft: ColorValue; - backgroundDangerSubtle: ColorValue; - - // background / warning - backgroundWarningLoud: ColorValue; - backgroundWarningSoft: ColorValue; - backgroundWarningSubtle: ColorValue; - - // background / success - backgroundSuccessLoud: ColorValue; - backgroundSuccessSoft: ColorValue; - backgroundSuccessSubtle: ColorValue; - - // stroke / neutral - strokeNeutralHeavy: ColorValue; - strokeNeutralLoud: ColorValue; - strokeNeutralSoft: ColorValue; - strokeNeutralSubtle: ColorValue; - strokeNeutralTransparent: ColorValue; - strokeNeutralOnloud: ColorValue; - - // stroke / brand - strokeBrandLoud: ColorValue; - strokeBrandSoft: ColorValue; - strokeBrandSubtle: ColorValue; - strokeBrandOnloud: ColorValue; - - // stroke / danger - strokeDangerLoud: ColorValue; - strokeDangerSoft: ColorValue; - strokeDangerSubtle: ColorValue; - strokeDangerOnloud: ColorValue; - - // stroke / warning - strokeWarningLoud: ColorValue; - strokeWarningSoft: ColorValue; - strokeWarningSubtle: ColorValue; - strokeWarningOnloud: ColorValue; - - // stroke / success - strokeSuccessLoud: ColorValue; - strokeSuccessSoft: ColorValue; - strokeSuccessSubtle: ColorValue; - strokeSuccessOnloud: ColorValue; - - // foreground / neutral - foregroundNeutralPrimary: ColorValue; - foregroundNeutralSecondary: ColorValue; - foregroundNeutralTertiary: ColorValue; - foregroundNeutralOnloud: ColorValue; - - // foreground / brand - foregroundBrandPrimary: ColorValue; - foregroundBrandOnloud: ColorValue; - - // foreground / danger - foregroundDangerPrimary: ColorValue; - foregroundDangerOnloud: ColorValue; - - // foreground / warning - foregroundWarningPrimary: ColorValue; - foregroundWarningOnloud: ColorValue; - - // foreground / success - foregroundSuccessPrimary: ColorValue; - foregroundSuccessOnloud: ColorValue; - - // fixed - fixedWhite: ColorValue; - fixedBlack: ColorValue; - - // expression / accent - expressionAccentHeavy: ColorValue; - expressionAccentLoud: ColorValue; - expressionAccentSoft: ColorValue; - expressionAccentSubtle: ColorValue; - - // expression / achromatic - expressionAchromaticHeavy: ColorValue; - expressionAchromaticSubtle: ColorValue; - - // expression / gray - expressionGrayHeavy: ColorValue; - expressionGrayLoud: ColorValue; - expressionGraySoft: ColorValue; - expressionGraySubtle: ColorValue; - - // expression / navy - expressionNavyHeavy: ColorValue; - expressionNavyLoud: ColorValue; - expressionNavySoft: ColorValue; - expressionNavySubtle: ColorValue; - - // expression / blue - expressionBlueHeavy: ColorValue; - expressionBlueLoud: ColorValue; - expressionBlueSoft: ColorValue; - expressionBlueSubtle: ColorValue; - - // expression / green - expressionGreenHeavy: ColorValue; - expressionGreenLoud: ColorValue; - expressionGreenSoft: ColorValue; - expressionGreenSubtle: ColorValue; - - // expression / lime - expressionLimeHeavy: ColorValue; - expressionLimeLoud: ColorValue; - expressionLimeSoft: ColorValue; - expressionLimeSubtle: ColorValue; - - // expression / yellow - expressionYellowHeavy: ColorValue; - expressionYellowLoud: ColorValue; - expressionYellowSoft: ColorValue; - expressionYellowSubtle: ColorValue; - - // expression / pumpkin - expressionPumpkinHeavy: ColorValue; - expressionPumpkinLoud: ColorValue; - expressionPumpkinSoft: ColorValue; - expressionPumpkinSubtle: ColorValue; - - // expression / red - expressionRedHeavy: ColorValue; - expressionRedLoud: ColorValue; - expressionRedSoft: ColorValue; - expressionRedSubtle: ColorValue; - - // expression / pink - expressionPinkHeavy: ColorValue; - expressionPinkLoud: ColorValue; - expressionPinkSoft: ColorValue; - expressionPinkSubtle: ColorValue; - - // expression / purple - expressionPurpleHeavy: ColorValue; - expressionPurpleLoud: ColorValue; - expressionPurpleSoft: ColorValue; - expressionPurpleSubtle: ColorValue; - - // overlay - overlayNeutralTranslucent: ColorValue; - - // material / background - materialBackgroundThick: ColorValue; - materialBackgroundRegular: ColorValue; - materialBackgroundThin: ColorValue; - - // disabled - backgroundNeutralDisabled: ColorValue; - backgroundNeutralHeavyDisabled: ColorValue; - backgroundNeutralSubtleDisabled: ColorValue; - strokeNeutralDisabled: ColorValue; - foregroundNeutralDisabled: ColorValue; - - // focus strokes - strokeFocusInner: ColorValue; - strokeFocusOuter: ColorValue; - - // shadow - shadow: ColorValue; -}; - -/** - * The subset of `SemanticColorTokenValues` that has interaction states. Used to - * shape the `hover` and `pressed` override maps on `SemanticColors`. - * - * Source of truth: `dev/web/flex-themes/css/interaction-fallback.css`. - */ -export type InteractiveColorOverrides = Partial< - Pick< - SemanticColorTokenValues, - | 'surfaceNeutralFarther' - | 'surfaceNeutralFar' - | 'surfaceNeutralNear' - | 'surfaceNeutralNearer' - | 'surfaceNeutralTranslucent' - | 'backgroundNeutralHeavy' - | 'backgroundNeutralLoud' - | 'backgroundNeutralSoft' - | 'backgroundNeutralSubtle' - | 'backgroundNeutralTransparent' - | 'backgroundNeutralTranslucent' - | 'backgroundBrandHeavy' - | 'backgroundBrandLoud' - | 'backgroundBrandSoft' - | 'backgroundBrandSubtle' - | 'backgroundBrandTransparent' - | 'backgroundDangerLoud' - | 'backgroundDangerSoft' - | 'backgroundDangerSubtle' - | 'backgroundWarningLoud' - | 'backgroundWarningSoft' - | 'backgroundWarningSubtle' - | 'backgroundSuccessLoud' - | 'backgroundSuccessSoft' - | 'backgroundSuccessSubtle' - | 'strokeNeutralHeavy' - | 'strokeNeutralLoud' - | 'strokeNeutralSoft' - | 'strokeNeutralSubtle' - | 'strokeNeutralTransparent' - | 'strokeNeutralOnloud' - | 'strokeBrandLoud' - | 'strokeBrandSoft' - | 'strokeBrandSubtle' - | 'strokeBrandOnloud' - | 'strokeDangerLoud' - | 'strokeDangerSoft' - | 'strokeDangerSubtle' - | 'strokeDangerOnloud' - | 'strokeWarningLoud' - | 'strokeWarningSoft' - | 'strokeWarningSubtle' - | 'strokeWarningOnloud' - | 'strokeSuccessLoud' - | 'strokeSuccessSoft' - | 'strokeSuccessSubtle' - | 'strokeSuccessOnloud' - | 'foregroundNeutralPrimary' - | 'foregroundNeutralSecondary' - | 'foregroundNeutralTertiary' - | 'foregroundNeutralOnloud' - | 'foregroundBrandPrimary' - | 'foregroundBrandOnloud' - | 'foregroundDangerPrimary' - | 'foregroundDangerOnloud' - | 'foregroundWarningPrimary' - | 'foregroundWarningOnloud' - | 'foregroundSuccessPrimary' - | 'foregroundSuccessOnloud' - > ->; - -/** - * The full semantic color token set: every token's rest value, plus `hover` and - * `pressed` maps that override only the interactive tokens. - */ -export type SemanticColors = SemanticColorTokenValues & { - hover: InteractiveColorOverrides; - pressed: InteractiveColorOverrides; -}; - -/** - * The semantic shadow token set - */ -export type SemanticShadows = { - lowest: ShadowToken; - lower: ShadowToken; - low: ShadowToken; - high: ShadowToken; - higher: ShadowToken; - highest: ShadowToken; -}; - -/** - * Semantic font weight tokens. - * - * Source of truth: `dev/web/flex-themes/css/semantic.css`. - */ -export type SemanticFontWeights = { - functionalRegular: FontWeight; - functionalMedium: FontWeight; - functionalSemibold: FontWeight; - functionalBold: FontWeight; - contentRegular: FontWeight; - contentMedium: FontWeight; - contentSemibold: FontWeight; - contentBold: FontWeight; - contentEditorialRegular: FontWeight; - contentEditorialMedium: FontWeight; - contentEditorialSemibold: FontWeight; - contentEditorialBold: FontWeight; -}; - -export type SemanticFontFamilies = { - functional: string; - content: string; - contentEditorial: string; - contentCode: string; -}; - -export type SemanticFontSizes = { - functionalDisplay: FontSize; - functionalPagetitle: FontSize; - functionalTitleLarge: FontSize; - functionalTitleMedium: FontSize; - functionalTitleSmall: FontSize; - functionalSubtitle: FontSize; - functionalBodyLarge: FontSize; - functionalBodyMedium: FontSize; - functionalBodySmall: FontSize; - functionalCaption: FontSize; - contentStatement: FontSize; - contentExpressiveLarge: FontSize; - contentExpressiveMedium: FontSize; - contentExpressiveSmall: FontSize; - contentH1: FontSize; - contentH2: FontSize; - contentH3: FontSize; - contentH4: FontSize; - contentH5: FontSize; - contentSubheadline: FontSize; - contentParagraphLarge: FontSize; - contentParagraphMedium: FontSize; - contentParagraphSmall: FontSize; - contentSubtext: FontSize; - contentTable: FontSize; - contentCode: FontSize; -}; - -export type SemanticLineHeights = { - functionalDisplay: number; - functionalPagetitle: number; - functionalTitleLarge: number; - functionalTitleMedium: number; - functionalTitleSmall: number; - functionalSubtitle: number; - functionalBodyLarge: number; - functionalBodyMedium: number; - functionalBodySmall: number; - functionalCaption: number; - contentStatement: number; - contentExpressiveLarge: number; - contentExpressiveMedium: number; - contentExpressiveSmall: number; - contentH1: number; - contentH2: number; - contentH3: number; - contentH4: number; - contentH5: number; - contentSubheadline: number; - contentParagraphLarge: number; - contentParagraphMedium: number; - contentParagraphSmall: number; - contentSubtext: number; - contentTable: number; - contentCode: number; -}; - -export type SemanticBorderRadii = { - base100: BorderRadius; - base200: BorderRadius; - base300: BorderRadius; - base400: BorderRadius; - base600: BorderRadius; - base700: BorderRadius; - circular: BorderRadius; -}; - -export type SemanticSpacing = { - componentBase50: DimensionValue; - componentBase100: DimensionValue; - componentBase150: DimensionValue; - componentBase200: DimensionValue; - componentBase250: DimensionValue; - componentBase300: DimensionValue; - componentBase400: DimensionValue; - componentBase500: DimensionValue; - componentBase600: DimensionValue; - componentBase700: DimensionValue; - layoutBase100: DimensionValue; - layoutBase200: DimensionValue; - layoutBase300: DimensionValue; - layoutBase400: DimensionValue; - layoutBase450: DimensionValue; - layoutBase500: DimensionValue; - layoutBase600: DimensionValue; - layoutBase700: DimensionValue; - layoutBase800: DimensionValue; - layoutBase1000: DimensionValue; - layoutBase1200: DimensionValue; -}; - -export type SemanticStrokeWidths = { - thin: StrokeWidth; - thick: StrokeWidth; - thicker: StrokeWidth; - thickest: StrokeWidth; -}; - -/** - * The complete, grouped Flex token set. Category prefixes are represented by - * sub-objects and removed from the token names inside each category. - */ -export type FlexTokens = { - color: SemanticColors; - shadow: SemanticShadows; - fontWeight: SemanticFontWeights; - fontFamily: SemanticFontFamilies; - fontSize: SemanticFontSizes; - lineHeight: SemanticLineHeights; - borderRadius: SemanticBorderRadii; - spacing: SemanticSpacing; - strokeWidth: SemanticStrokeWidths; -}; - -export type SemanticTokens = FlexTokens; - -/** - * These are flex tokens from web that are not supported on native. - */ -export type UnsupportedFlexTokens = { - letterSpacing: { - functionalDisplay: string; - functionalPagetitle: string; - functionalTitleLarge: string; - functionalTitleMedium: string; - functionalTitleSmall: string; - functionalSubtitle: string; - functionalBodyLarge: string; - functionalBodyMedium: string; - functionalBodySmall: string; - functionalCaption: string; - contentStatement: string; - contentExpressiveLarge: string; - contentExpressiveMedium: string; - contentExpressiveSmall: string; - contentH1: string; - contentH2: string; - contentH3: string; - contentH4: string; - contentH5: string; - contentSubheadline: string; - contentParagraphLarge: string; - contentParagraphMedium: string; - contentParagraphSmall: string; - contentSubtext: string; - contentTable: string; - contentCode: string; - }; -}; diff --git a/packages/agentic/design/src/tokens/flexTokensFromTheme.test.ts b/packages/agentic/design/src/tokens/flexTokensFromTheme.test.ts deleted file mode 100644 index 7c4c7e01a06..00000000000 --- a/packages/agentic/design/src/tokens/flexTokensFromTheme.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { Theme } from '../theming'; -import { mockTheme } from '../testing/mockTheme'; -import { flexTokensFromTheme } from './flexTokensFromTheme'; - -function createTheme(): Theme { - return { - ...mockTheme, - colors: { - ...mockTheme.colors, - brandBackground2: '#112233', - neutralBackground2: '#223344', - neutralBackground2Hover: '#334455', - neutralBackground2Pressed: '#445566', - }, - components: { - Button: { - tokens: { - borderRadius: 10, - }, - }, - }, - }; -} - -describe('flexTokensFromTheme', () => { - it('merges mapped Theme values over non-Fluent defaults', () => { - const theme = createTheme(); - const tokens = flexTokensFromTheme(theme); - - expect(tokens.color.backgroundNeutralSubtle).toBe('#223344'); - expect(tokens.color.hover.backgroundNeutralSubtle).toBe('#334455'); - expect(tokens.color.pressed.backgroundNeutralSubtle).toBe('#445566'); - expect(tokens.color.backgroundBrandSoft).toBe('#112233'); - expect(tokens.color.hover.backgroundBrandSoft).toBeUndefined(); - expect(tokens.color.pressed.backgroundBrandSoft).toBeUndefined(); - expect(tokens.color.backgroundNeutralSoft).toBe('#0000001a'); - expect(tokens.color.hover.backgroundNeutralSoft).toBe('#0000001a'); - expect(tokens.borderRadius.base100).toBe(2); - expect(tokens.borderRadius.base200).toBe(10); - expect(tokens.borderRadius.base300).toBe(10); - expect(tokens.borderRadius.base400).toBe(6); - expect(tokens.fontWeight.functionalMedium).toBe(theme.typography.weights.semiBold); - }); - - it('uses native defaults when an optional mapped Theme path is absent', () => { - const tokens = flexTokensFromTheme({ ...createTheme(), components: {} }); - - expect(tokens.borderRadius.base200).toBe(4); - expect(tokens.borderRadius.base300).toBe(4); - expect(tokens.color.backgroundBrandHeavy).toBe('#185abd'); - }); -}); diff --git a/packages/agentic/design/src/tokens/flexTokensFromTheme.ts b/packages/agentic/design/src/tokens/flexTokensFromTheme.ts deleted file mode 100644 index 0b30f13369e..00000000000 --- a/packages/agentic/design/src/tokens/flexTokensFromTheme.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { immutableMerge } from '@fluentui-react-native/framework-base'; - -import type { Theme } from '../theming'; -import { mapObjectFromObject } from '../utilities/objects'; -import { defaultFlexTokens, nonFluentFlexTokens } from './defaultTokens'; -import type { FlexTokens } from './flex.types'; -import flexFromTheme from './mappings/flex-from-theme.json' with { type: 'json' }; - -const defaultMappedFlexTokens = mapObjectFromObject<FlexTokens>( - defaultFlexTokens, - Object.fromEntries(Object.keys(flexFromTheme).map((destinationPath) => [destinationPath, destinationPath])), -); - -/** - * Build Flex tokens from the values exposed by a FURN Theme. - */ -export function flexTokensFromTheme(theme: Theme): FlexTokens { - const mappedThemeTokens = immutableMerge(defaultMappedFlexTokens, mapObjectFromObject<FlexTokens>(theme, flexFromTheme)); - return immutableMerge(nonFluentFlexTokens, mappedThemeTokens); -} diff --git a/packages/agentic/design/src/tokens/legacy/index.ts b/packages/agentic/design/src/tokens/legacy/index.ts deleted file mode 100644 index cc73c61e274..00000000000 --- a/packages/agentic/design/src/tokens/legacy/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as globalTokens } from './tokens-global'; -export { getAliasTokens, getShadowTokens } from './getTokens'; -export { hcAliasTokens } from './highContrast/tokens-alias'; diff --git a/packages/agentic/design/src/tokens/mappings/flex-from-theme.json b/packages/agentic/design/src/tokens/mappings/flex-from-theme.json index 4e9a0a3760d..e6683e6bc3a 100644 --- a/packages/agentic/design/src/tokens/mappings/flex-from-theme.json +++ b/packages/agentic/design/src/tokens/mappings/flex-from-theme.json @@ -1,125 +1,125 @@ { "borderRadius.base200": "components.Button.tokens.borderRadius", "borderRadius.base300": "components.Button.tokens.borderRadius", - "color.backgroundBrandHeavy": "colors.brandBackground", - "color.backgroundBrandLoud": "colors.compoundBrandBackground1", - "color.backgroundBrandSoft": "colors.brandBackground2", - "color.backgroundBrandSubtle": "colors.brandBackground2", - "color.backgroundBrandTransparent": "colors.transparentBackground", - "color.backgroundDangerLoud": "colors.dangerBackground3", - "color.backgroundDangerSoft": "colors.dangerBackground2", - "color.backgroundDangerSubtle": "colors.dangerBackground1", - "color.backgroundNeutralDisabled": "colors.neutralBackgroundDisabled", - "color.backgroundNeutralHeavy": "colors.neutralBackgroundInverted", - "color.backgroundNeutralHeavyDisabled": "colors.neutralBackgroundDisabled", - "color.backgroundNeutralLoud": "colors.neutralBackgroundInverted", - "color.backgroundNeutralSubtle": "colors.neutralBackground2", - "color.backgroundNeutralSubtleDisabled": "colors.neutralBackgroundDisabled", - "color.backgroundNeutralTransparent": "colors.transparentBackground", - "color.backgroundSuccessLoud": "colors.successBackground3", - "color.backgroundSuccessSoft": "colors.successBackground2", - "color.backgroundSuccessSubtle": "colors.successBackground1", - "color.backgroundWarningLoud": "colors.warningBackground3", - "color.backgroundWarningSoft": "colors.warningBackground2", - "color.backgroundWarningSubtle": "colors.warningBackground1", - "color.expressionAchromaticHeavy": "colors.black", - "color.expressionAchromaticSubtle": "colors.white", - "color.fixedBlack": "colors.black", - "color.fixedWhite": "colors.white", - "color.foregroundBrandOnloud": "colors.neutralForegroundOnBrand", - "color.foregroundBrandPrimary": "colors.brandForeground1", - "color.foregroundDangerOnloud": "colors.neutralForegroundOnBrand", - "color.foregroundDangerPrimary": "colors.dangerForeground1", - "color.foregroundNeutralDisabled": "colors.neutralForegroundDisabled", - "color.foregroundNeutralOnloud": "colors.neutralForegroundOnBrand", - "color.foregroundNeutralPrimary": "colors.neutralForeground1", - "color.foregroundNeutralSecondary": "colors.neutralForeground2", - "color.foregroundNeutralTertiary": "colors.neutralForeground3", - "color.foregroundSuccessOnloud": "colors.neutralForegroundOnBrand", - "color.foregroundSuccessPrimary": "colors.successForeground1", - "color.foregroundWarningOnloud": "colors.neutralForegroundOnBrand", - "color.foregroundWarningPrimary": "colors.warningForeground1", - "color.hover.backgroundBrandHeavy": "colors.brandBackgroundHover", - "color.hover.backgroundBrandLoud": "colors.compoundBrandBackground1Hover", - "color.hover.backgroundBrandTransparent": "colors.transparentBackgroundHover", - "color.hover.backgroundNeutralSubtle": "colors.neutralBackground2Hover", - "color.hover.backgroundNeutralTransparent": "colors.transparentBackgroundHover", - "color.hover.foregroundBrandOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.foregroundDangerOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.foregroundNeutralOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.foregroundNeutralPrimary": "colors.neutralForeground1Hover", - "color.hover.foregroundNeutralSecondary": "colors.neutralForeground2Hover", - "color.hover.foregroundNeutralTertiary": "colors.neutralForeground3Hover", - "color.hover.foregroundSuccessOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.foregroundWarningOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.strokeBrandOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.strokeDangerOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.strokeNeutralHeavy": "colors.neutralStrokeAccessibleHover", - "color.hover.strokeNeutralLoud": "colors.neutralStroke1Hover", - "color.hover.strokeNeutralOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.strokeNeutralSoft": "colors.neutralStroke1Hover", - "color.hover.strokeNeutralTransparent": "colors.transparentStrokeInteractive", - "color.hover.strokeSuccessOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.strokeWarningOnloud": "colors.neutralForegroundOnBrandHover", - "color.hover.surfaceNeutralFar": "colors.neutralBackground3Hover", - "color.hover.surfaceNeutralFarther": "colors.neutralBackground5Hover", - "color.hover.surfaceNeutralNear": "colors.neutralBackground2Hover", - "color.hover.surfaceNeutralNearer": "colors.neutralBackground1Hover", - "color.pressed.backgroundBrandHeavy": "colors.brandBackgroundPressed", - "color.pressed.backgroundBrandLoud": "colors.compoundBrandBackground1Pressed", - "color.pressed.backgroundBrandTransparent": "colors.transparentBackgroundPressed", - "color.pressed.backgroundNeutralSubtle": "colors.neutralBackground2Pressed", - "color.pressed.backgroundNeutralTransparent": "colors.transparentBackgroundPressed", - "color.pressed.foregroundBrandOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.foregroundDangerOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.foregroundNeutralOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.foregroundNeutralPrimary": "colors.neutralForeground1Pressed", - "color.pressed.foregroundNeutralSecondary": "colors.neutralForeground2Pressed", - "color.pressed.foregroundNeutralTertiary": "colors.neutralForeground3Pressed", - "color.pressed.foregroundSuccessOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.foregroundWarningOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.strokeBrandOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.strokeDangerOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.strokeNeutralHeavy": "colors.neutralStrokeAccessiblePressed", - "color.pressed.strokeNeutralLoud": "colors.neutralStroke1Pressed", - "color.pressed.strokeNeutralOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.strokeNeutralSoft": "colors.neutralStroke1Pressed", - "color.pressed.strokeSuccessOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.strokeWarningOnloud": "colors.neutralForegroundOnBrandPressed", - "color.pressed.surfaceNeutralFar": "colors.neutralBackground3Pressed", - "color.pressed.surfaceNeutralFarther": "colors.neutralBackground5Pressed", - "color.pressed.surfaceNeutralNear": "colors.neutralBackground2Pressed", - "color.pressed.surfaceNeutralNearer": "colors.neutralBackground1Pressed", - "color.shadow": "colors.black", - "color.strokeBrandLoud": "colors.brandStroke1", - "color.strokeBrandOnloud": "colors.neutralForegroundOnBrand", - "color.strokeBrandSoft": "colors.brandStroke1", - "color.strokeBrandSubtle": "colors.brandStroke2", - "color.strokeDangerLoud": "colors.dangerBorder2", - "color.strokeDangerOnloud": "colors.neutralForegroundOnBrand", - "color.strokeDangerSoft": "colors.dangerBorder1", - "color.strokeDangerSubtle": "colors.dangerBorder1", - "color.strokeFocusInner": "colors.strokeFocus1", - "color.strokeFocusOuter": "colors.strokeFocus2", - "color.strokeNeutralDisabled": "colors.neutralStrokeDisabled", - "color.strokeNeutralHeavy": "colors.neutralStrokeAccessible", - "color.strokeNeutralLoud": "colors.neutralStroke1", - "color.strokeNeutralOnloud": "colors.neutralForegroundOnBrand", - "color.strokeNeutralSoft": "colors.neutralStroke1", - "color.strokeNeutralSubtle": "colors.neutralStroke2", - "color.strokeNeutralTransparent": "colors.transparentStroke", - "color.strokeSuccessLoud": "colors.successBorder2", - "color.strokeSuccessOnloud": "colors.neutralForegroundOnBrand", - "color.strokeSuccessSoft": "colors.successBorder1", - "color.strokeSuccessSubtle": "colors.successBorder1", - "color.strokeWarningLoud": "colors.warningBorder2", - "color.strokeWarningOnloud": "colors.neutralForegroundOnBrand", - "color.strokeWarningSoft": "colors.warningBorder1", - "color.strokeWarningSubtle": "colors.warningBorder1", - "color.surfaceNeutralFar": "colors.neutralBackground3", - "color.surfaceNeutralFarther": "colors.neutralBackground5", - "color.surfaceNeutralNear": "colors.neutralBackground2", - "color.surfaceNeutralNearer": "colors.neutralBackground1", + "color.backgroundBrandHeavy.hover": "colors.brandBackgroundHover", + "color.backgroundBrandHeavy.pressed": "colors.brandBackgroundPressed", + "color.backgroundBrandHeavy.rest": "colors.brandBackground", + "color.backgroundBrandLoud.hover": "colors.compoundBrandBackground1Hover", + "color.backgroundBrandLoud.pressed": "colors.compoundBrandBackground1Pressed", + "color.backgroundBrandLoud.rest": "colors.compoundBrandBackground1", + "color.backgroundBrandSoft.rest": "colors.brandBackground2", + "color.backgroundBrandSubtle.rest": "colors.brandBackground2", + "color.backgroundBrandTransparent.hover": "colors.transparentBackgroundHover", + "color.backgroundBrandTransparent.pressed": "colors.transparentBackgroundPressed", + "color.backgroundBrandTransparent.rest": "colors.transparentBackground", + "color.backgroundDangerLoud.rest": "colors.dangerBackground3", + "color.backgroundDangerSoft.rest": "colors.dangerBackground2", + "color.backgroundDangerSubtle.rest": "colors.dangerBackground1", + "color.backgroundNeutralDisabled.rest": "colors.neutralBackgroundDisabled", + "color.backgroundNeutralHeavy.rest": "colors.neutralBackgroundInverted", + "color.backgroundNeutralHeavyDisabled.rest": "colors.neutralBackgroundDisabled", + "color.backgroundNeutralLoud.rest": "colors.neutralBackgroundInverted", + "color.backgroundNeutralSubtle.hover": "colors.neutralBackground2Hover", + "color.backgroundNeutralSubtle.pressed": "colors.neutralBackground2Pressed", + "color.backgroundNeutralSubtle.rest": "colors.neutralBackground2", + "color.backgroundNeutralSubtleDisabled.rest": "colors.neutralBackgroundDisabled", + "color.backgroundNeutralTransparent.hover": "colors.transparentBackgroundHover", + "color.backgroundNeutralTransparent.pressed": "colors.transparentBackgroundPressed", + "color.backgroundNeutralTransparent.rest": "colors.transparentBackground", + "color.backgroundSuccessLoud.rest": "colors.successBackground3", + "color.backgroundSuccessSoft.rest": "colors.successBackground2", + "color.backgroundSuccessSubtle.rest": "colors.successBackground1", + "color.backgroundWarningLoud.rest": "colors.warningBackground3", + "color.backgroundWarningSoft.rest": "colors.warningBackground2", + "color.backgroundWarningSubtle.rest": "colors.warningBackground1", + "color.expressionAchromaticHeavy.rest": "colors.black", + "color.expressionAchromaticSubtle.rest": "colors.white", + "color.fixedBlack.rest": "colors.black", + "color.fixedWhite.rest": "colors.white", + "color.foregroundBrandOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.foregroundBrandOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.foregroundBrandOnloud.rest": "colors.neutralForegroundOnBrand", + "color.foregroundBrandPrimary.rest": "colors.brandForeground1", + "color.foregroundDangerOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.foregroundDangerOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.foregroundDangerOnloud.rest": "colors.neutralForegroundOnBrand", + "color.foregroundDangerPrimary.rest": "colors.dangerForeground1", + "color.foregroundNeutralDisabled.rest": "colors.neutralForegroundDisabled", + "color.foregroundNeutralOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.foregroundNeutralOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.foregroundNeutralOnloud.rest": "colors.neutralForegroundOnBrand", + "color.foregroundNeutralPrimary.hover": "colors.neutralForeground1Hover", + "color.foregroundNeutralPrimary.pressed": "colors.neutralForeground1Pressed", + "color.foregroundNeutralPrimary.rest": "colors.neutralForeground1", + "color.foregroundNeutralSecondary.hover": "colors.neutralForeground2Hover", + "color.foregroundNeutralSecondary.pressed": "colors.neutralForeground2Pressed", + "color.foregroundNeutralSecondary.rest": "colors.neutralForeground2", + "color.foregroundNeutralTertiary.hover": "colors.neutralForeground3Hover", + "color.foregroundNeutralTertiary.pressed": "colors.neutralForeground3Pressed", + "color.foregroundNeutralTertiary.rest": "colors.neutralForeground3", + "color.foregroundSuccessOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.foregroundSuccessOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.foregroundSuccessOnloud.rest": "colors.neutralForegroundOnBrand", + "color.foregroundSuccessPrimary.rest": "colors.successForeground1", + "color.foregroundWarningOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.foregroundWarningOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.foregroundWarningOnloud.rest": "colors.neutralForegroundOnBrand", + "color.foregroundWarningPrimary.rest": "colors.warningForeground1", + "color.shadow.rest": "colors.black", + "color.strokeBrandLoud.rest": "colors.brandStroke1", + "color.strokeBrandOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.strokeBrandOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.strokeBrandOnloud.rest": "colors.neutralForegroundOnBrand", + "color.strokeBrandSoft.rest": "colors.brandStroke1", + "color.strokeBrandSubtle.rest": "colors.brandStroke2", + "color.strokeDangerLoud.rest": "colors.dangerBorder2", + "color.strokeDangerOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.strokeDangerOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.strokeDangerOnloud.rest": "colors.neutralForegroundOnBrand", + "color.strokeDangerSoft.rest": "colors.dangerBorder1", + "color.strokeDangerSubtle.rest": "colors.dangerBorder1", + "color.strokeFocusInner.rest": "colors.strokeFocus1", + "color.strokeFocusOuter.rest": "colors.strokeFocus2", + "color.strokeNeutralDisabled.rest": "colors.neutralStrokeDisabled", + "color.strokeNeutralHeavy.hover": "colors.neutralStrokeAccessibleHover", + "color.strokeNeutralHeavy.pressed": "colors.neutralStrokeAccessiblePressed", + "color.strokeNeutralHeavy.rest": "colors.neutralStrokeAccessible", + "color.strokeNeutralLoud.hover": "colors.neutralStroke1Hover", + "color.strokeNeutralLoud.pressed": "colors.neutralStroke1Pressed", + "color.strokeNeutralLoud.rest": "colors.neutralStroke1", + "color.strokeNeutralOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.strokeNeutralOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.strokeNeutralOnloud.rest": "colors.neutralForegroundOnBrand", + "color.strokeNeutralSoft.hover": "colors.neutralStroke1Hover", + "color.strokeNeutralSoft.pressed": "colors.neutralStroke1Pressed", + "color.strokeNeutralSoft.rest": "colors.neutralStroke1", + "color.strokeNeutralSubtle.rest": "colors.neutralStroke2", + "color.strokeNeutralTransparent.hover": "colors.transparentStrokeInteractive", + "color.strokeNeutralTransparent.rest": "colors.transparentStroke", + "color.strokeSuccessLoud.rest": "colors.successBorder2", + "color.strokeSuccessOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.strokeSuccessOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.strokeSuccessOnloud.rest": "colors.neutralForegroundOnBrand", + "color.strokeSuccessSoft.rest": "colors.successBorder1", + "color.strokeSuccessSubtle.rest": "colors.successBorder1", + "color.strokeWarningLoud.rest": "colors.warningBorder2", + "color.strokeWarningOnloud.hover": "colors.neutralForegroundOnBrandHover", + "color.strokeWarningOnloud.pressed": "colors.neutralForegroundOnBrandPressed", + "color.strokeWarningOnloud.rest": "colors.neutralForegroundOnBrand", + "color.strokeWarningSoft.rest": "colors.warningBorder1", + "color.strokeWarningSubtle.rest": "colors.warningBorder1", + "color.surfaceNeutralFar.hover": "colors.neutralBackground3Hover", + "color.surfaceNeutralFar.pressed": "colors.neutralBackground3Pressed", + "color.surfaceNeutralFar.rest": "colors.neutralBackground3", + "color.surfaceNeutralFarther.hover": "colors.neutralBackground5Hover", + "color.surfaceNeutralFarther.pressed": "colors.neutralBackground5Pressed", + "color.surfaceNeutralFarther.rest": "colors.neutralBackground5", + "color.surfaceNeutralNear.hover": "colors.neutralBackground2Hover", + "color.surfaceNeutralNear.pressed": "colors.neutralBackground2Pressed", + "color.surfaceNeutralNear.rest": "colors.neutralBackground2", + "color.surfaceNeutralNearer.hover": "colors.neutralBackground1Hover", + "color.surfaceNeutralNearer.pressed": "colors.neutralBackground1Pressed", + "color.surfaceNeutralNearer.rest": "colors.neutralBackground1", "fontFamily.content": "typography.families.primary", "fontFamily.contentCode": "typography.families.monospace", "fontFamily.contentEditorial": "typography.families.serif", diff --git a/packages/agentic/design/src/tokens/mappings/flex-token-map.yaml b/packages/agentic/design/src/tokens/mappings/flex-token-map.yaml index f5fe940758b..17af8afc204 100644 --- a/packages/agentic/design/src/tokens/mappings/flex-token-map.yaml +++ b/packages/agentic/design/src/tokens/mappings/flex-token-map.yaml @@ -5,14 +5,16 @@ target: types: supported: FlexTokens unsupported: UnsupportedFlexTokens - definition: '../flex.types.ts' + definition: '../../flex/tokens.types.ts' direction: flex token path <- authoring source token sources: generic: - description: Generic Flex CSS custom properties. + description: Generic Flex CSS custom properties. Cool and warm tones share names. locations: - dev/web/flex-themes/css/semantic.css - dev/web/flex-themes/css/interaction-fallback.css + - dev/web/flex-themes/css/warm/semantic.css + - dev/web/flex-themes/css/warm/interaction-fallback.css fluent: description: Fluent UI React Native / Fluent 2 tokens used for native defaults. package: '@fluentui-react-native/design-tokens-win32/colorful' @@ -23,16 +25,16 @@ sources: furn-theme: description: Dot path to the corresponding value in the Fluent UI React Native Theme type. - definition: '../../theming/types/Theme.types.ts' + definition: '../../fluent/types/Theme.types.ts' projection: './flex-from-theme.json' reverseProjection: './theme-from-flex.json' rules: colorStates: shape: Each color has a required rest mapping and optional hover and pressed mappings. projection: - rest: color.<name> - hover: color.hover.<name> - pressed: color.pressed.<name> + rest: color.<name>.rest + hover: color.<name>.hover + pressed: color.<name>.pressed fluentAliases: Alias references identify explicit state leaves such as alias.brandBackground.rest, alias.brandBackground.hover, and alias.brandBackground.pressed. matching: @@ -44,6 +46,10 @@ rules: differ in value from Fluent (400/500/600/700). fontFamily: role match (base / monospace). notes: + - Every rest and non-color destination declares its generic source. scripts/flex-defaults/generate-defaults.mjs + reads those custom properties from the pinned cool and warm snapshots and emits + ../../flex/defaults/defaultTokens.generated.ts plus its coverage ledger; check-mappings.cjs enforces the + coverage. - global.* references are best-fit matches into the Fluent global palette; expression families map to the matching shared-color ramp step, gray to the grey ramp, alpha/translucent roles to the *Alpha ramps. @@ -55,16 +61,22 @@ rules: semantic.css. - letterSpacing* are null — Fluent global has no letter-spacing/tracking token. - fontFamily.contentEditorial is null — Fluent global has no serif family token. + - motion.* are null — Fluent global has no motion token, and Theme has no motion path. - furn-theme is omitted when Theme has no corresponding value path. - scripts/token-mappings/check-mappings.cjs enforces that flex-from-theme.json exactly matches the furn-theme mappings in this file. - - flexTokensFromTheme.ts consumes flex-from-theme.json and merges the projected - Theme values over nonFluentFlexTokens. - - The same check enforces that nonFluentFlexTokens in ../defaultTokens.ts covers - unmapped supported destinations. An unmapped hover or pressed fallback is + - ../../flex/adapters/flexTokensFromTheme.ts consumes flex-from-theme.json and merges the projected + Theme values over the Fluent-native fallbacks in ../../flex/adapters/fluentFallbackTokens.ts. + An interaction state the Theme does not map resolves to the Theme's rest value; the forward + adapter never runs the interaction algorithm. + - The same check enforces that nonFluentFlexTokens in ../../flex/adapters/fluentFallbackTokens.ts covers + unmapped supported destinations. An unmapped hover or pressed value is included only when its rest destination is also unmapped; otherwise the state - value remains only in defaultFlexTokens so a Theme-provided rest value does - not inherit a mismatched fallback interaction color. + value remains only in fluentFallbackFlexTokens so a Theme-provided rest value + does not inherit a mismatched fallback interaction color. + - Theme shadows are legacy { ambient, key } pairs. The forward adapter converts each to + [ambient, key] layers. The reverse shadowLayersToToken transform projects the first layer + to ambient and the last to key, so middle layers are dropped; this projection is lossy. - Button uses borderRadius.base200 / base300 / base400 for small / medium / large. The FURN Theme exposes its shared small/medium Button radius, but its large size-specific radius remains sourced from Fluent global tokens. @@ -74,138 +86,144 @@ rules: reverse: projection: ./theme-from-flex.json interactionFallback: rest - transforms: {} + transforms: + shadows.shadow16: shadowLayersToToken + shadows.shadow2: shadowLayersToToken + shadows.shadow28: shadowLayersToToken + shadows.shadow4: shadowLayersToToken + shadows.shadow64: shadowLayersToToken + shadows.shadow8: shadowLayersToToken canonical: colors.black: - source: color.fixedBlack + source: color.fixedBlack.rest omitted: - - color.expressionAchromaticHeavy - - color.shadow + - color.expressionAchromaticHeavy.rest + - color.shadow.rest reason: The fixed invariant is the canonical legacy black value; expression and shadow roles may diverge in Flex themes. colors.brandBackground2: - source: color.backgroundBrandSoft + source: color.backgroundBrandSoft.rest omitted: - - color.backgroundBrandSubtle + - color.backgroundBrandSubtle.rest reason: The soft brand background is the closest general-purpose match for legacy brandBackground2. colors.brandStroke1: - source: color.strokeBrandLoud + source: color.strokeBrandLoud.rest omitted: - - color.strokeBrandSoft + - color.strokeBrandSoft.rest reason: The loud brand stroke is the primary stroke role represented by legacy brandStroke1. colors.dangerBorder1: - source: color.strokeDangerSoft + source: color.strokeDangerSoft.rest omitted: - - color.strokeDangerSubtle + - color.strokeDangerSubtle.rest reason: The soft danger stroke is the closest general-purpose match for legacy dangerBorder1. colors.neutralBackground2: - source: color.surfaceNeutralNear + source: color.surfaceNeutralNear.rest omitted: - - color.backgroundNeutralSubtle + - color.backgroundNeutralSubtle.rest reason: The near neutral surface preserves the legacy neutralBackground2 surface progression. colors.neutralBackground2Hover: - source: color.hover.surfaceNeutralNear + source: color.surfaceNeutralNear.hover omitted: - - color.hover.backgroundNeutralSubtle + - color.backgroundNeutralSubtle.hover reason: Use the interaction state paired with the canonical near neutral surface. colors.neutralBackground2Pressed: - source: color.pressed.surfaceNeutralNear + source: color.surfaceNeutralNear.pressed omitted: - - color.pressed.backgroundNeutralSubtle + - color.backgroundNeutralSubtle.pressed reason: Use the interaction state paired with the canonical near neutral surface. colors.neutralBackgroundDisabled: - source: color.backgroundNeutralDisabled + source: color.backgroundNeutralDisabled.rest omitted: - - color.backgroundNeutralHeavyDisabled - - color.backgroundNeutralSubtleDisabled + - color.backgroundNeutralHeavyDisabled.rest + - color.backgroundNeutralSubtleDisabled.rest reason: The unqualified disabled background is the canonical general legacy disabled value. colors.neutralBackgroundInverted: - source: color.backgroundNeutralHeavy + source: color.backgroundNeutralHeavy.rest omitted: - - color.backgroundNeutralLoud + - color.backgroundNeutralLoud.rest reason: The heavy neutral background is the strongest general inverted background role. colors.neutralForegroundOnBrand: - source: color.foregroundNeutralOnloud + source: color.foregroundNeutralOnloud.rest omitted: - - color.foregroundBrandOnloud - - color.foregroundDangerOnloud - - color.foregroundSuccessOnloud - - color.foregroundWarningOnloud - - color.strokeBrandOnloud - - color.strokeDangerOnloud - - color.strokeNeutralOnloud - - color.strokeSuccessOnloud - - color.strokeWarningOnloud + - color.foregroundBrandOnloud.rest + - color.foregroundDangerOnloud.rest + - color.foregroundSuccessOnloud.rest + - color.foregroundWarningOnloud.rest + - color.strokeBrandOnloud.rest + - color.strokeDangerOnloud.rest + - color.strokeNeutralOnloud.rest + - color.strokeSuccessOnloud.rest + - color.strokeWarningOnloud.rest reason: The neutral on-loud foreground is the generic on-color legacy foreground role. colors.neutralForegroundOnBrandHover: - source: color.hover.foregroundNeutralOnloud + source: color.foregroundNeutralOnloud.hover omitted: - - color.hover.foregroundBrandOnloud - - color.hover.foregroundDangerOnloud - - color.hover.foregroundSuccessOnloud - - color.hover.foregroundWarningOnloud - - color.hover.strokeBrandOnloud - - color.hover.strokeDangerOnloud - - color.hover.strokeNeutralOnloud - - color.hover.strokeSuccessOnloud - - color.hover.strokeWarningOnloud + - color.foregroundBrandOnloud.hover + - color.foregroundDangerOnloud.hover + - color.foregroundSuccessOnloud.hover + - color.foregroundWarningOnloud.hover + - color.strokeBrandOnloud.hover + - color.strokeDangerOnloud.hover + - color.strokeNeutralOnloud.hover + - color.strokeSuccessOnloud.hover + - color.strokeWarningOnloud.hover reason: Use the interaction state paired with the canonical neutral on-loud foreground. colors.neutralForegroundOnBrandPressed: - source: color.pressed.foregroundNeutralOnloud + source: color.foregroundNeutralOnloud.pressed omitted: - - color.pressed.foregroundBrandOnloud - - color.pressed.foregroundDangerOnloud - - color.pressed.foregroundSuccessOnloud - - color.pressed.foregroundWarningOnloud - - color.pressed.strokeBrandOnloud - - color.pressed.strokeDangerOnloud - - color.pressed.strokeNeutralOnloud - - color.pressed.strokeSuccessOnloud - - color.pressed.strokeWarningOnloud + - color.foregroundBrandOnloud.pressed + - color.foregroundDangerOnloud.pressed + - color.foregroundSuccessOnloud.pressed + - color.foregroundWarningOnloud.pressed + - color.strokeBrandOnloud.pressed + - color.strokeDangerOnloud.pressed + - color.strokeNeutralOnloud.pressed + - color.strokeSuccessOnloud.pressed + - color.strokeWarningOnloud.pressed reason: Use the interaction state paired with the canonical neutral on-loud foreground. colors.neutralStroke1: - source: color.strokeNeutralLoud + source: color.strokeNeutralLoud.rest omitted: - - color.strokeNeutralSoft + - color.strokeNeutralSoft.rest reason: The loud neutral stroke is the primary stroke role represented by legacy neutralStroke1. colors.neutralStroke1Hover: - source: color.hover.strokeNeutralLoud + source: color.strokeNeutralLoud.hover omitted: - - color.hover.strokeNeutralSoft + - color.strokeNeutralSoft.hover reason: Use the interaction state paired with the canonical loud neutral stroke. colors.neutralStroke1Pressed: - source: color.pressed.strokeNeutralLoud + source: color.strokeNeutralLoud.pressed omitted: - - color.pressed.strokeNeutralSoft + - color.strokeNeutralSoft.pressed reason: Use the interaction state paired with the canonical loud neutral stroke. colors.successBorder1: - source: color.strokeSuccessSoft + source: color.strokeSuccessSoft.rest omitted: - - color.strokeSuccessSubtle + - color.strokeSuccessSubtle.rest reason: The soft success stroke is the closest general-purpose match for legacy successBorder1. colors.transparentBackground: - source: color.backgroundNeutralTransparent + source: color.backgroundNeutralTransparent.rest omitted: - - color.backgroundBrandTransparent + - color.backgroundBrandTransparent.rest reason: The neutral transparent background is the generic legacy transparent background role. colors.transparentBackgroundHover: - source: color.hover.backgroundNeutralTransparent + source: color.backgroundNeutralTransparent.hover omitted: - - color.hover.backgroundBrandTransparent + - color.backgroundBrandTransparent.hover reason: Use the interaction state paired with the canonical neutral transparent background. colors.transparentBackgroundPressed: - source: color.pressed.backgroundNeutralTransparent + source: color.backgroundNeutralTransparent.pressed omitted: - - color.pressed.backgroundBrandTransparent + - color.backgroundBrandTransparent.pressed reason: Use the interaction state paired with the canonical neutral transparent background. colors.warningBorder1: - source: color.strokeWarningSoft + source: color.strokeWarningSoft.rest omitted: - - color.strokeWarningSubtle + - color.strokeWarningSubtle.rest reason: The soft warning stroke is the closest general-purpose match for legacy warningBorder1. colors.white: - source: color.fixedWhite + source: color.fixedWhite.rest omitted: - - color.expressionAchromaticSubtle + - color.expressionAchromaticSubtle.rest reason: The fixed invariant is the canonical legacy white value; expression roles may diverge in Flex themes. components.Button.tokens.borderRadius: source: borderRadius.base200 @@ -1509,6 +1527,45 @@ tokens: lineHeight.functionalTitleSmall: generic: '--gnrc-line-height-functional-title-small' fluent: global.font.lineHeight500 + motion.durationBase100: + generic: '--gnrc-motion-duration-base-100' + fluent: + motion.durationBase1000: + generic: '--gnrc-motion-duration-base-1000' + fluent: + motion.durationBase200: + generic: '--gnrc-motion-duration-base-200' + fluent: + motion.durationBase300: + generic: '--gnrc-motion-duration-base-300' + fluent: + motion.durationBase50: + generic: '--gnrc-motion-duration-base-50' + fluent: + motion.durationBase500: + generic: '--gnrc-motion-duration-base-500' + fluent: + motion.easingExpressiveEnter: + generic: '--gnrc-motion-easing-expressive-enter' + fluent: + motion.easingExpressiveExit: + generic: '--gnrc-motion-easing-expressive-exit' + fluent: + motion.easingExpressiveTransition: + generic: '--gnrc-motion-easing-expressive-transition' + fluent: + motion.easingFunctionalEnter: + generic: '--gnrc-motion-easing-functional-enter' + fluent: + motion.easingFunctionalExit: + generic: '--gnrc-motion-easing-functional-exit' + fluent: + motion.easingFunctionalLinear: + generic: '--gnrc-motion-easing-functional-linear' + fluent: + motion.easingFunctionalTransition: + generic: '--gnrc-motion-easing-functional-transition' + fluent: shadow.high: generic: '--gnrc-shadow-high' fluent: shadow.shadow16 @@ -1563,6 +1620,9 @@ tokens: spacing.componentBase700: generic: '--gnrc-spacing-component-base-700' fluent: global.size280 + spacing.componentBase800: + generic: '--gnrc-spacing-component-base-800' + fluent: global.size320 spacing.layoutBase100: generic: '--gnrc-spacing-layout-base-100' fluent: global.size80 diff --git a/packages/agentic/design/src/tokens/mappings/flexTokenMappings.test.ts b/packages/agentic/design/src/tokens/mappings/flexTokenMappings.test.ts index 5e42afa849e..9d778825be6 100644 --- a/packages/agentic/design/src/tokens/mappings/flexTokenMappings.test.ts +++ b/packages/agentic/design/src/tokens/mappings/flexTokenMappings.test.ts @@ -109,12 +109,12 @@ describe('Flex token mapping consistency', () => { it('rejects interaction fallbacks when the rest destination is Theme-backed', () => { const changed = cloneInputs(inputs); - changed.nonFluentValues.set('color.hover.backgroundBrandSoft', "'#000000'"); + changed.nonFluentValues.set('color.backgroundBrandSoft.hover', "'#000000'"); expect(validateMappingInputs(changed)).toContainEqual({ rule: 'interaction-fallback', - path: 'color.hover.backgroundBrandSoft', - expected: 'color.backgroundBrandSoft to be absent from flex-from-theme.json', + path: 'color.backgroundBrandSoft.hover', + expected: 'color.backgroundBrandSoft.rest to be absent from flex-from-theme.json', actual: 'colors.brandBackground2', }); }); @@ -164,14 +164,14 @@ describe('Flex token mapping consistency', () => { expect(validateMappingInputs(changed)).toContainEqual({ rule: 'reverse-canonical', path: 'colors.black', - expected: 'one of ["color.expressionAchromaticHeavy","color.fixedBlack","color.shadow"]', + expected: 'one of ["color.expressionAchromaticHeavy.rest","color.fixedBlack.rest","color.shadow.rest"]', actual: 'color.notARealToken', }); }); it('requires every non-canonical candidate and an omission reason', () => { const changed = cloneInputs(inputs); - changed.mapping.reverse.canonical['colors.black'].omitted = ['color.expressionAchromaticHeavy']; + changed.mapping.reverse.canonical['colors.black'].omitted = ['color.expressionAchromaticHeavy.rest']; changed.mapping.reverse.canonical['colors.white'].reason = ''; const violations = validateMappingInputs(changed); @@ -179,8 +179,8 @@ describe('Flex token mapping consistency', () => { expect(violations).toContainEqual({ rule: 'reverse-omission', path: 'colors.black', - expected: ['color.expressionAchromaticHeavy', 'color.shadow'], - actual: ['color.expressionAchromaticHeavy'], + expected: ['color.expressionAchromaticHeavy.rest', 'color.shadow.rest'], + actual: ['color.expressionAchromaticHeavy.rest'], }); expect(violations).toContainEqual({ rule: 'reverse-omission', @@ -192,13 +192,13 @@ describe('Flex token mapping consistency', () => { it('validates generated interaction fallbacks against declared Flex paths', () => { const changed = cloneInputs(inputs); - changed.supportedTypePaths.delete('color.backgroundBrandHeavy'); + changed.supportedTypePaths.delete('color.backgroundBrandHeavy.rest'); expect(validateMappingInputs(changed)).toContainEqual({ rule: 'reverse-fallback', path: 'colors.brandBackgroundHover', expected: 'a declared Flex rest path', - actual: 'color.backgroundBrandHeavy', + actual: 'color.backgroundBrandHeavy.rest', }); }); @@ -209,11 +209,59 @@ describe('Flex token mapping consistency', () => { expect(validateMappingInputs(changed)).toContainEqual({ rule: 'reverse-transform', path: 'colors.black', - expected: ['identity', 'numberToPx'], + expected: ['identity', 'numberToPx', 'shadowLayersToToken'], actual: 'notARealTransform', }); }); + it('requires layered shadows to project through shadowLayersToToken', () => { + const changed = cloneInputs(inputs); + delete changed.mapping.reverse.transforms['shadows.shadow2']; + + expect(validateMappingInputs(changed)).toContainEqual({ + rule: 'reverse-transform', + path: 'shadows.shadow2', + expected: 'shadowLayersToToken', + actual: '<missing>', + }); + }); + + it('requires a YAML destination for every supported rest and non-color path', () => { + const changed = cloneInputs(inputs); + delete changed.mapping.tokens['spacing.componentBase800']; + + expect(validateMappingInputs(changed)).toContainEqual({ + rule: 'mapping-coverage', + path: 'spacing.componentBase800', + expected: 'a destination in flex-token-map.yaml', + actual: '<missing>', + }); + }); + + it('requires a generic source for every supported destination', () => { + const changed = cloneInputs(inputs); + delete (changed.mapping.tokens['motion.durationBase200'] as Record<string, unknown>).generic; + + expect(validateMappingInputs(changed)).toContainEqual({ + rule: 'generic-source', + path: 'motion.durationBase200', + expected: 'a generic custom property', + actual: '<missing>', + }); + }); + + it('rejects generic sources that are not --gnrc-* custom properties', () => { + const changed = cloneInputs(inputs); + (changed.mapping.tokens['motion.durationBase200'] as Record<string, unknown>).generic = '--fluent-duration'; + + expect(validateMappingInputs(changed)).toContainEqual({ + rule: 'schema', + path: 'motion.durationBase200', + expected: 'a --gnrc-* custom property name or no generic field', + actual: '--fluent-duration', + }); + }); + it('emits declared reverse transforms into the generated projection', () => { const changed = cloneInputs(inputs); changed.mapping.reverse.transforms['typography.sizes.body'] = 'numberToPx'; @@ -229,14 +277,30 @@ describe('Flex token mapping consistency', () => { it('reports drift in the checked-in reverse projection', () => { const changed = cloneInputs(inputs); - changed.reverseProjection['colors.black'] = { source: 'color.shadow' }; + changed.reverseProjection['colors.black'] = { source: 'color.shadow.rest' }; expect(validateMappingInputs(changed)).toContainEqual({ rule: 'reverse-projection', path: 'colors.black', - expected: { source: 'color.fixedBlack' }, - actual: { source: 'color.shadow' }, + expected: { source: 'color.fixedBlack.rest' }, + actual: { source: 'color.shadow.rest' }, + }); + }); + + it('projects color states to nested Flex paths', () => { + expect(inputs.themeProjection['color.backgroundBrandHeavy.rest']).toBe('colors.brandBackground'); + expect(inputs.themeProjection['color.backgroundBrandHeavy.hover']).toBe('colors.brandBackgroundHover'); + expect(inputs.reverseProjection['colors.brandBackgroundHover']).toEqual({ + source: 'color.backgroundBrandHeavy.hover', + fallback: 'color.backgroundBrandHeavy.rest', }); + expect(Object.keys(inputs.themeProjection).filter((path) => /^color\.(?:hover|pressed)\./.test(path))).toEqual([]); + }); + + it('reads non-Fluent colors as rest values and explicit interaction states', () => { + expect(inputs.nonFluentValues.get('color.expressionAccentHeavy.rest')).toBe("'#242424'"); + expect(inputs.nonFluentValues.get('color.backgroundNeutralSoft.hover')).toBe("'#0000001a'"); + expect(inputs.nonFluentValues.has('color.expressionAccentHeavy')).toBe(false); }); it('rejects unknown mapping schema versions', () => { diff --git a/packages/agentic/design/src/tokens/mappings/theme-from-flex.json b/packages/agentic/design/src/tokens/mappings/theme-from-flex.json index 7ce60c8a656..19793e39556 100644 --- a/packages/agentic/design/src/tokens/mappings/theme-from-flex.json +++ b/packages/agentic/design/src/tokens/mappings/theme-from-flex.json @@ -1,267 +1,273 @@ { "colors.black": { - "source": "color.fixedBlack" + "source": "color.fixedBlack.rest" }, "colors.brandBackground": { - "source": "color.backgroundBrandHeavy" + "source": "color.backgroundBrandHeavy.rest" }, "colors.brandBackground2": { - "source": "color.backgroundBrandSoft" + "source": "color.backgroundBrandSoft.rest" }, "colors.brandBackgroundHover": { - "source": "color.hover.backgroundBrandHeavy", - "fallback": "color.backgroundBrandHeavy" + "source": "color.backgroundBrandHeavy.hover", + "fallback": "color.backgroundBrandHeavy.rest" }, "colors.brandBackgroundPressed": { - "source": "color.pressed.backgroundBrandHeavy", - "fallback": "color.backgroundBrandHeavy" + "source": "color.backgroundBrandHeavy.pressed", + "fallback": "color.backgroundBrandHeavy.rest" }, "colors.brandForeground1": { - "source": "color.foregroundBrandPrimary" + "source": "color.foregroundBrandPrimary.rest" }, "colors.brandStroke1": { - "source": "color.strokeBrandLoud" + "source": "color.strokeBrandLoud.rest" }, "colors.brandStroke2": { - "source": "color.strokeBrandSubtle" + "source": "color.strokeBrandSubtle.rest" }, "colors.compoundBrandBackground1": { - "source": "color.backgroundBrandLoud" + "source": "color.backgroundBrandLoud.rest" }, "colors.compoundBrandBackground1Hover": { - "source": "color.hover.backgroundBrandLoud", - "fallback": "color.backgroundBrandLoud" + "source": "color.backgroundBrandLoud.hover", + "fallback": "color.backgroundBrandLoud.rest" }, "colors.compoundBrandBackground1Pressed": { - "source": "color.pressed.backgroundBrandLoud", - "fallback": "color.backgroundBrandLoud" + "source": "color.backgroundBrandLoud.pressed", + "fallback": "color.backgroundBrandLoud.rest" }, "colors.dangerBackground1": { - "source": "color.backgroundDangerSubtle" + "source": "color.backgroundDangerSubtle.rest" }, "colors.dangerBackground2": { - "source": "color.backgroundDangerSoft" + "source": "color.backgroundDangerSoft.rest" }, "colors.dangerBackground3": { - "source": "color.backgroundDangerLoud" + "source": "color.backgroundDangerLoud.rest" }, "colors.dangerBorder1": { - "source": "color.strokeDangerSoft" + "source": "color.strokeDangerSoft.rest" }, "colors.dangerBorder2": { - "source": "color.strokeDangerLoud" + "source": "color.strokeDangerLoud.rest" }, "colors.dangerForeground1": { - "source": "color.foregroundDangerPrimary" + "source": "color.foregroundDangerPrimary.rest" }, "colors.neutralBackground1": { - "source": "color.surfaceNeutralNearer" + "source": "color.surfaceNeutralNearer.rest" }, "colors.neutralBackground1Hover": { - "source": "color.hover.surfaceNeutralNearer", - "fallback": "color.surfaceNeutralNearer" + "source": "color.surfaceNeutralNearer.hover", + "fallback": "color.surfaceNeutralNearer.rest" }, "colors.neutralBackground1Pressed": { - "source": "color.pressed.surfaceNeutralNearer", - "fallback": "color.surfaceNeutralNearer" + "source": "color.surfaceNeutralNearer.pressed", + "fallback": "color.surfaceNeutralNearer.rest" }, "colors.neutralBackground2": { - "source": "color.surfaceNeutralNear" + "source": "color.surfaceNeutralNear.rest" }, "colors.neutralBackground2Hover": { - "source": "color.hover.surfaceNeutralNear", - "fallback": "color.surfaceNeutralNear" + "source": "color.surfaceNeutralNear.hover", + "fallback": "color.surfaceNeutralNear.rest" }, "colors.neutralBackground2Pressed": { - "source": "color.pressed.surfaceNeutralNear", - "fallback": "color.surfaceNeutralNear" + "source": "color.surfaceNeutralNear.pressed", + "fallback": "color.surfaceNeutralNear.rest" }, "colors.neutralBackground3": { - "source": "color.surfaceNeutralFar" + "source": "color.surfaceNeutralFar.rest" }, "colors.neutralBackground3Hover": { - "source": "color.hover.surfaceNeutralFar", - "fallback": "color.surfaceNeutralFar" + "source": "color.surfaceNeutralFar.hover", + "fallback": "color.surfaceNeutralFar.rest" }, "colors.neutralBackground3Pressed": { - "source": "color.pressed.surfaceNeutralFar", - "fallback": "color.surfaceNeutralFar" + "source": "color.surfaceNeutralFar.pressed", + "fallback": "color.surfaceNeutralFar.rest" }, "colors.neutralBackground5": { - "source": "color.surfaceNeutralFarther" + "source": "color.surfaceNeutralFarther.rest" }, "colors.neutralBackground5Hover": { - "source": "color.hover.surfaceNeutralFarther", - "fallback": "color.surfaceNeutralFarther" + "source": "color.surfaceNeutralFarther.hover", + "fallback": "color.surfaceNeutralFarther.rest" }, "colors.neutralBackground5Pressed": { - "source": "color.pressed.surfaceNeutralFarther", - "fallback": "color.surfaceNeutralFarther" + "source": "color.surfaceNeutralFarther.pressed", + "fallback": "color.surfaceNeutralFarther.rest" }, "colors.neutralBackgroundDisabled": { - "source": "color.backgroundNeutralDisabled" + "source": "color.backgroundNeutralDisabled.rest" }, "colors.neutralBackgroundInverted": { - "source": "color.backgroundNeutralHeavy" + "source": "color.backgroundNeutralHeavy.rest" }, "colors.neutralForeground1": { - "source": "color.foregroundNeutralPrimary" + "source": "color.foregroundNeutralPrimary.rest" }, "colors.neutralForeground1Hover": { - "source": "color.hover.foregroundNeutralPrimary", - "fallback": "color.foregroundNeutralPrimary" + "source": "color.foregroundNeutralPrimary.hover", + "fallback": "color.foregroundNeutralPrimary.rest" }, "colors.neutralForeground1Pressed": { - "source": "color.pressed.foregroundNeutralPrimary", - "fallback": "color.foregroundNeutralPrimary" + "source": "color.foregroundNeutralPrimary.pressed", + "fallback": "color.foregroundNeutralPrimary.rest" }, "colors.neutralForeground2": { - "source": "color.foregroundNeutralSecondary" + "source": "color.foregroundNeutralSecondary.rest" }, "colors.neutralForeground2Hover": { - "source": "color.hover.foregroundNeutralSecondary", - "fallback": "color.foregroundNeutralSecondary" + "source": "color.foregroundNeutralSecondary.hover", + "fallback": "color.foregroundNeutralSecondary.rest" }, "colors.neutralForeground2Pressed": { - "source": "color.pressed.foregroundNeutralSecondary", - "fallback": "color.foregroundNeutralSecondary" + "source": "color.foregroundNeutralSecondary.pressed", + "fallback": "color.foregroundNeutralSecondary.rest" }, "colors.neutralForeground3": { - "source": "color.foregroundNeutralTertiary" + "source": "color.foregroundNeutralTertiary.rest" }, "colors.neutralForeground3Hover": { - "source": "color.hover.foregroundNeutralTertiary", - "fallback": "color.foregroundNeutralTertiary" + "source": "color.foregroundNeutralTertiary.hover", + "fallback": "color.foregroundNeutralTertiary.rest" }, "colors.neutralForeground3Pressed": { - "source": "color.pressed.foregroundNeutralTertiary", - "fallback": "color.foregroundNeutralTertiary" + "source": "color.foregroundNeutralTertiary.pressed", + "fallback": "color.foregroundNeutralTertiary.rest" }, "colors.neutralForegroundDisabled": { - "source": "color.foregroundNeutralDisabled" + "source": "color.foregroundNeutralDisabled.rest" }, "colors.neutralForegroundOnBrand": { - "source": "color.foregroundNeutralOnloud" + "source": "color.foregroundNeutralOnloud.rest" }, "colors.neutralForegroundOnBrandHover": { - "source": "color.hover.foregroundNeutralOnloud", - "fallback": "color.foregroundNeutralOnloud" + "source": "color.foregroundNeutralOnloud.hover", + "fallback": "color.foregroundNeutralOnloud.rest" }, "colors.neutralForegroundOnBrandPressed": { - "source": "color.pressed.foregroundNeutralOnloud", - "fallback": "color.foregroundNeutralOnloud" + "source": "color.foregroundNeutralOnloud.pressed", + "fallback": "color.foregroundNeutralOnloud.rest" }, "colors.neutralStroke1": { - "source": "color.strokeNeutralLoud" + "source": "color.strokeNeutralLoud.rest" }, "colors.neutralStroke1Hover": { - "source": "color.hover.strokeNeutralLoud", - "fallback": "color.strokeNeutralLoud" + "source": "color.strokeNeutralLoud.hover", + "fallback": "color.strokeNeutralLoud.rest" }, "colors.neutralStroke1Pressed": { - "source": "color.pressed.strokeNeutralLoud", - "fallback": "color.strokeNeutralLoud" + "source": "color.strokeNeutralLoud.pressed", + "fallback": "color.strokeNeutralLoud.rest" }, "colors.neutralStroke2": { - "source": "color.strokeNeutralSubtle" + "source": "color.strokeNeutralSubtle.rest" }, "colors.neutralStrokeAccessible": { - "source": "color.strokeNeutralHeavy" + "source": "color.strokeNeutralHeavy.rest" }, "colors.neutralStrokeAccessibleHover": { - "source": "color.hover.strokeNeutralHeavy", - "fallback": "color.strokeNeutralHeavy" + "source": "color.strokeNeutralHeavy.hover", + "fallback": "color.strokeNeutralHeavy.rest" }, "colors.neutralStrokeAccessiblePressed": { - "source": "color.pressed.strokeNeutralHeavy", - "fallback": "color.strokeNeutralHeavy" + "source": "color.strokeNeutralHeavy.pressed", + "fallback": "color.strokeNeutralHeavy.rest" }, "colors.neutralStrokeDisabled": { - "source": "color.strokeNeutralDisabled" + "source": "color.strokeNeutralDisabled.rest" }, "colors.strokeFocus1": { - "source": "color.strokeFocusInner" + "source": "color.strokeFocusInner.rest" }, "colors.strokeFocus2": { - "source": "color.strokeFocusOuter" + "source": "color.strokeFocusOuter.rest" }, "colors.successBackground1": { - "source": "color.backgroundSuccessSubtle" + "source": "color.backgroundSuccessSubtle.rest" }, "colors.successBackground2": { - "source": "color.backgroundSuccessSoft" + "source": "color.backgroundSuccessSoft.rest" }, "colors.successBackground3": { - "source": "color.backgroundSuccessLoud" + "source": "color.backgroundSuccessLoud.rest" }, "colors.successBorder1": { - "source": "color.strokeSuccessSoft" + "source": "color.strokeSuccessSoft.rest" }, "colors.successBorder2": { - "source": "color.strokeSuccessLoud" + "source": "color.strokeSuccessLoud.rest" }, "colors.successForeground1": { - "source": "color.foregroundSuccessPrimary" + "source": "color.foregroundSuccessPrimary.rest" }, "colors.transparentBackground": { - "source": "color.backgroundNeutralTransparent" + "source": "color.backgroundNeutralTransparent.rest" }, "colors.transparentBackgroundHover": { - "source": "color.hover.backgroundNeutralTransparent", - "fallback": "color.backgroundNeutralTransparent" + "source": "color.backgroundNeutralTransparent.hover", + "fallback": "color.backgroundNeutralTransparent.rest" }, "colors.transparentBackgroundPressed": { - "source": "color.pressed.backgroundNeutralTransparent", - "fallback": "color.backgroundNeutralTransparent" + "source": "color.backgroundNeutralTransparent.pressed", + "fallback": "color.backgroundNeutralTransparent.rest" }, "colors.transparentStroke": { - "source": "color.strokeNeutralTransparent" + "source": "color.strokeNeutralTransparent.rest" }, "colors.transparentStrokeInteractive": { - "source": "color.hover.strokeNeutralTransparent", - "fallback": "color.strokeNeutralTransparent" + "source": "color.strokeNeutralTransparent.hover", + "fallback": "color.strokeNeutralTransparent.rest" }, "colors.warningBackground1": { - "source": "color.backgroundWarningSubtle" + "source": "color.backgroundWarningSubtle.rest" }, "colors.warningBackground2": { - "source": "color.backgroundWarningSoft" + "source": "color.backgroundWarningSoft.rest" }, "colors.warningBackground3": { - "source": "color.backgroundWarningLoud" + "source": "color.backgroundWarningLoud.rest" }, "colors.warningBorder1": { - "source": "color.strokeWarningSoft" + "source": "color.strokeWarningSoft.rest" }, "colors.warningBorder2": { - "source": "color.strokeWarningLoud" + "source": "color.strokeWarningLoud.rest" }, "colors.warningForeground1": { - "source": "color.foregroundWarningPrimary" + "source": "color.foregroundWarningPrimary.rest" }, "colors.white": { - "source": "color.fixedWhite" + "source": "color.fixedWhite.rest" }, "components.Button.tokens.borderRadius": { "source": "borderRadius.base200" }, "shadows.shadow16": { - "source": "shadow.high" + "source": "shadow.high", + "transform": "shadowLayersToToken" }, "shadows.shadow2": { - "source": "shadow.lowest" + "source": "shadow.lowest", + "transform": "shadowLayersToToken" }, "shadows.shadow28": { - "source": "shadow.higher" + "source": "shadow.higher", + "transform": "shadowLayersToToken" }, "shadows.shadow4": { - "source": "shadow.lower" + "source": "shadow.lower", + "transform": "shadowLayersToToken" }, "shadows.shadow64": { - "source": "shadow.highest" + "source": "shadow.highest", + "transform": "shadowLayersToToken" }, "shadows.shadow8": { - "source": "shadow.low" + "source": "shadow.low", + "transform": "shadowLayersToToken" }, "typography.families.monospace": { "source": "fontFamily.contentCode" diff --git a/packages/agentic/design/src/tokens/mappings/upstream-pin.json b/packages/agentic/design/src/tokens/mappings/upstream-pin.json index 93af2276229..1ebf950ef97 100644 --- a/packages/agentic/design/src/tokens/mappings/upstream-pin.json +++ b/packages/agentic/design/src/tokens/mappings/upstream-pin.json @@ -1,13 +1,25 @@ { "repository": "x3-design/fluent-design", - "commit": "d334acf5cbad813f2b7cd554da942b09a7ff8f10", - "verifiedDate": "2026-08-27", + "commit": "206e890b645fb450ad7c5df2ff981765349a2b58", + "verifiedDate": "2026-10-24", "files": [ { "id": "semanticCss", "upstreamPath": "dev/web/flex-themes/css/semantic.css", "snapshotPath": "scripts/token-mappings/__fixtures__/x3/semantic.css", - "blobSha": "6dac670ac83f3251898d40f07c0e90a2779a1915" + "blobSha": "4c9f3e0a70bdbb8b7183d2db15254d9427d8e6ab" + }, + { + "id": "semanticLightCss", + "upstreamPath": "dev/web/flex-themes/css/semantic-light.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/semantic-light.css", + "blobSha": "633b87a634be88bf37b018f287b3d1758a189707" + }, + { + "id": "semanticDarkCss", + "upstreamPath": "dev/web/flex-themes/css/semantic-dark.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/semantic-dark.css", + "blobSha": "d9ae7355fc3ed934a385bf6cd36244e2f5bba7b0" }, { "id": "interactionFallbackCss", @@ -15,11 +27,65 @@ "snapshotPath": "scripts/token-mappings/__fixtures__/x3/interaction-fallback.css", "blobSha": "c69ff3145f4f9b1228a694a3e7ba8b1a65d2c032" }, + { + "id": "interactionFallbackLightCss", + "upstreamPath": "dev/web/flex-themes/css/interaction-fallback-light.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/interaction-fallback-light.css", + "blobSha": "87f488d731babc06f457edf9ca4c358fa79b39b2" + }, + { + "id": "interactionFallbackDarkCss", + "upstreamPath": "dev/web/flex-themes/css/interaction-fallback-dark.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/interaction-fallback-dark.css", + "blobSha": "f4d6af7fdcd16a315f024f907c2a5b264366cda8" + }, + { + "id": "warmSemanticCss", + "upstreamPath": "dev/web/flex-themes/css/warm/semantic.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/warm/semantic.css", + "blobSha": "dfe8416dffb4b215777d0270c3fe40a5d631ee2c" + }, + { + "id": "warmSemanticLightCss", + "upstreamPath": "dev/web/flex-themes/css/warm/semantic-light.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/warm/semantic-light.css", + "blobSha": "0c155116e886e55f98b5b9212a96ed25efcf89ee" + }, + { + "id": "warmSemanticDarkCss", + "upstreamPath": "dev/web/flex-themes/css/warm/semantic-dark.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/warm/semantic-dark.css", + "blobSha": "cacec7d267fb11a44d6e42f943e3aa6ab5955e1f" + }, + { + "id": "warmInteractionFallbackCss", + "upstreamPath": "dev/web/flex-themes/css/warm/interaction-fallback.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback.css", + "blobSha": "6dbe4a963fd197cac7fabf35cf6c801f68aa1f4c" + }, + { + "id": "warmInteractionFallbackLightCss", + "upstreamPath": "dev/web/flex-themes/css/warm/interaction-fallback-light.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-light.css", + "blobSha": "ffb1ef7e3eda4a0c2428cbed75db707f14c0173f" + }, + { + "id": "warmInteractionFallbackDarkCss", + "upstreamPath": "dev/web/flex-themes/css/warm/interaction-fallback-dark.css", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/warm/interaction-fallback-dark.css", + "blobSha": "6d51a1eb182381eeb9dcd14d7c6b7a4ca0de7ed1" + }, { "id": "mappings", "upstreamPath": "dev/web/flex-tokens/mappings.json", "snapshotPath": "scripts/token-mappings/__fixtures__/x3/mappings.json", - "blobSha": "4b917a8c93a18591741482136ee0df2b05bdce2f" + "blobSha": "33c7a100a200d52d48f35faae5adf9f6282e462a" + }, + { + "id": "tokens", + "upstreamPath": "dev/web/flex-tokens/tokens.json", + "snapshotPath": "scripts/token-mappings/__fixtures__/x3/tokens.json", + "blobSha": "49bec466b835c0df87c879f399a29fc60db6b426" } ] } diff --git a/packages/agentic/design/src/concepts/textAttributes.ts b/packages/agentic/design/src/tokens/textAttributes.ts similarity index 98% rename from packages/agentic/design/src/concepts/textAttributes.ts rename to packages/agentic/design/src/tokens/textAttributes.ts index 6ab9bf50bab..ccffd27e4ab 100644 --- a/packages/agentic/design/src/concepts/textAttributes.ts +++ b/packages/agentic/design/src/tokens/textAttributes.ts @@ -13,7 +13,7 @@ import { fontWeightRegular, fontWeightMedium, fontWeightBold, -} from '../tokens/global.generated'; +} from './global.generated'; /** * Represents the available font sizes for this platform. Available via key lookup diff --git a/packages/agentic/design/src/theming/appearance.types.ts b/packages/agentic/design/src/types/appearance.types.ts similarity index 56% rename from packages/agentic/design/src/theming/appearance.types.ts rename to packages/agentic/design/src/types/appearance.types.ts index a2f5b13d78b..79153d1b209 100644 --- a/packages/agentic/design/src/theming/appearance.types.ts +++ b/packages/agentic/design/src/types/appearance.types.ts @@ -2,23 +2,47 @@ export type ThemeColorScheme = 'light' | 'dark'; export type ThemeContrast = 'standard' | 'highContrast'; export type ThemeInterfaceLevel = 'base' | 'elevated'; +/** + * Palette tone. It selects both the Flex palette and the interaction-color + * algorithm. Tone is configuration only; no platform source reports it. + */ +export type ColorTone = 'cool' | 'warm'; + export interface ThemeAppearanceRequest { colorScheme: ThemeColorScheme | 'system'; contrast: ThemeContrast | 'system'; interfaceLevel: ThemeInterfaceLevel | 'system'; + /** + * Explicit tone request. Omission is preserved until resolution, where the + * configured fallback tone and then cool apply. + */ + colorTone?: ColorTone; } export type ThemeAppearanceOptions = Partial<ThemeAppearanceRequest>; +/** + * A concrete appearance accepted by legacy-facing and recipe APIs. Existing + * three-field values remain valid; an omitted tone means cool. + */ export interface ResolvedThemeAppearance { colorScheme: ThemeColorScheme; contrast: ThemeContrast; interfaceLevel: ThemeInterfaceLevel; + colorTone?: ColorTone; +} + +/** + * A resolved appearance produced by the theme runtime. Every axis, including + * tone, is concrete. + */ +export interface NormalizedThemeAppearance extends ResolvedThemeAppearance { + colorTone: ColorTone; } export interface ThemeAppearanceState { requested: Readonly<ThemeAppearanceRequest>; - resolved: Readonly<ResolvedThemeAppearance>; + resolved: Readonly<NormalizedThemeAppearance>; } export interface ThemeAppearanceSourceSnapshot { diff --git a/packages/agentic/design/src/utilities/objects.ts b/packages/agentic/design/src/utilities/objects.ts index 607689b9bdc..c5085e306e3 100644 --- a/packages/agentic/design/src/utilities/objects.ts +++ b/packages/agentic/design/src/utilities/objects.ts @@ -5,26 +5,34 @@ */ export type ObjectFromObjectMapping = Record<string, string>; +export type InvalidPathReason = 'empty' | 'unsafe'; + const unsafePathSegments = new Set(['__proto__', 'constructor', 'prototype']); -function getPathSegments(path: string, pathKind: 'source' | 'destination'): string[] { +/** + * Split a dotted object path, rejecting empty and prototype-polluting segments with the caller's error. + */ +export function splitObjectPath(path: string, invalidPath: (reason: InvalidPathReason) => Error): string[] { const segments = path.split('.'); if (segments.some((segment) => segment.length === 0)) { - throw new Error(`Invalid ${pathKind} path "${path}".`); + throw invalidPath('empty'); } if (segments.some((segment) => unsafePathSegments.has(segment))) { - throw new Error(`Unsafe ${pathKind} path "${path}".`); + throw invalidPath('unsafe'); } return segments; } -function isRecord(value: unknown): value is Record<string, unknown> { +export function isRecord(value: unknown): value is Record<string, unknown> { return typeof value === 'object' && value !== null && !Array.isArray(value); } -function getValueAtPath(source: object, path: string): unknown { +/** + * Read an own value at the path, or undefined when any segment is missing. + */ +export function getValueAtSegments(source: object, segments: readonly string[]): unknown { let value: unknown = source; - for (const segment of getPathSegments(path, 'source')) { + for (const segment of segments) { if (!isRecord(value) || !Object.prototype.hasOwnProperty.call(value, segment)) { return undefined; } @@ -33,10 +41,15 @@ function getValueAtPath(source: object, path: string): unknown { return value; } -function setValueAtPath(destination: Record<string, unknown>, path: string, value: unknown): void { - const segments = getPathSegments(path, 'destination'); +/** + * Return the record that owns the path's leaf, creating missing parents. A non-record parent throws the caller's error. + */ +export function ensureParentRecord( + destination: Record<string, unknown>, + segments: readonly string[], + conflict: (segment: string) => Error, +): Record<string, unknown> { let target = destination; - for (const segment of segments.slice(0, -1)) { const existing = target[segment]; if (existing === undefined) { @@ -46,9 +59,27 @@ function setValueAtPath(destination: Record<string, unknown>, path: string, valu } else if (isRecord(existing)) { target = existing; } else { - throw new Error(`Cannot create destination path "${path}" because "${segment}" is not an object.`); + throw conflict(segment); } } + return target; +} + +function getPathSegments(path: string, pathKind: 'source' | 'destination'): string[] { + return splitObjectPath(path, (reason) => new Error(`${reason === 'empty' ? 'Invalid' : 'Unsafe'} ${pathKind} path "${path}".`)); +} + +function getValueAtPath(source: object, path: string): unknown { + return getValueAtSegments(source, getPathSegments(path, 'source')); +} + +function setValueAtPath(destination: Record<string, unknown>, path: string, value: unknown): void { + const segments = getPathSegments(path, 'destination'); + const target = ensureParentRecord( + destination, + segments, + (segment) => new Error(`Cannot create destination path "${path}" because "${segment}" is not an object.`), + ); const leaf = segments[segments.length - 1]; if (target[leaf] !== undefined) { diff --git a/packages/agentic/storybook-desktop-runtime/AGENTS.md b/packages/agentic/storybook-desktop-runtime/AGENTS.md index 27d7fcee9b9..a7158feac30 100644 --- a/packages/agentic/storybook-desktop-runtime/AGENTS.md +++ b/packages/agentic/storybook-desktop-runtime/AGENTS.md @@ -15,8 +15,9 @@ authenticated bridge, Metro, theme, and platform chrome. test reporting belong to the integration and harness packages. - Preserve the authenticated nonce, correlated request/run IDs, readiness, error signaling, and native story-root verification. -- Keep one `ThemedRoot` around app content and chrome. Preserve explicit story - background overrides and safe fallback behavior for opaque native colors. +- Keep one Flex `ThemedRoot` around app content and chrome; apply the selected + theme only to story content through the nested provider. Preserve explicit + story background overrides and safe fallback behavior for opaque native colors. - Keep platform-specific behavior in platform files. Preserve Win32's desktop-only chrome and keep macOS/Windows on upstream LiteUI. - Metro configuration has side effects: loading it can generate the runtime diff --git a/packages/agentic/storybook-desktop-runtime/references/runtime-contract.md b/packages/agentic/storybook-desktop-runtime/references/runtime-contract.md index c96b9b761ca..3987305bb39 100644 --- a/packages/agentic/storybook-desktop-runtime/references/runtime-contract.md +++ b/packages/agentic/storybook-desktop-runtime/references/runtime-contract.md @@ -17,12 +17,33 @@ contracts and fail closed on stale or uncorrelated messages. ## Theme and chrome -One `ThemedRoot` covers the app, toolbar, and chrome. Theme changes update the -preview and chrome without replacing the Storybook instance. macOS and Windows -keep upstream LiteUI; Win32 uses the package's desktop chrome with persistent -resizable sidebar, story preview, bottom addon panel, and optional -Callout-backed pop-outs. Do not add mobile drawer portals or window-dimension -assumptions to the Win32 host. +One Flex `ThemedRoot` covers the app, toolbar, and chrome, so the Storybook +chrome and story canvas always use the Flex theme. Story content receives the +selected theme through a nested `ThemeProvider` that adds no view and shares the +root's input modality. Theme changes update the preview and chrome without +replacing the Storybook instance. macOS and Windows keep upstream LiteUI; Win32 +uses the package's desktop chrome with persistent resizable sidebar, story +preview, bottom addon panel, and optional Callout-backed pop-outs. Do not add +mobile drawer portals or window-dimension assumptions to the Win32 host. + +The toolbar selects four independent axes from inline dropdown menus: + +| Axis | Test-ID segment | Values | +| -------- | --------------- | ------------------------------------------------------------------------------------------------------- | +| Theme | `source` | Story theme: `flex` (the design package's Flex defaults) or `fluent` (the legacy default theme) | +| Scheme | `scheme` | `light`, `dark`, or `system`, which follows the platform appearance | +| Contrast | `contrast` | `standard` or `highContrast` | +| Tone | `tone` | `cool` or `warm`; Flex only, so it is disabled and reports `cool` for the Fluent theme, chrome included | + +The chrome and story themes receive the selection as one structured appearance +request, so a selection never constructs a new theme reference. The default, +Flex, light, standard, and cool, does not depend on the host appearance. The +toolbar is `<prefix>-theme-toolbar`; each axis trigger is a combobox with test +ID `<prefix>-theme-<segment>` that reports its value and expanded state; its +open menu is `<prefix>-theme-<segment>-menu`; and each option is +`<prefix>-theme-<segment>-<value>`. One menu is open at a time, and selecting +an option closes it. Native story tests can select a theme configuration +through these IDs before asserting. Opaque platform colors may be unusable by Storybook JavaScript color utilities. Preserve native tokens; use the documented contrasting theme color diff --git a/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.test.tsx b/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.test.tsx index c4e5532fcab..8f5fc1c1556 100644 --- a/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.test.tsx +++ b/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.test.tsx @@ -1,9 +1,11 @@ import * as React from 'react'; -import { StyleSheet, Text } from 'react-native'; +import { Appearance, StyleSheet, Text } from 'react-native'; import { fireEvent, render } from '@testing-library/react-native'; -import { useRootSettings, useThemeState } from '@fluentui-react-native/design'; -import type { RootSettings, ThemeState } from '@fluentui-react-native/design'; +import { FlexThemeReference, useRootSettings, useThemeAppearance, useThemeState } from '@fluentui-react-native/design'; +import type { RootSettings, ThemeAppearanceState, ThemeState } from '@fluentui-react-native/design'; +import { ThemeContext } from '@fluentui-react-native/design/theming'; +import type { Theme as LegacyTheme } from '@fluentui-react-native/design/theming'; import { defaultFlexTokens } from '@fluentui-react-native/design/testing'; import type { View as StorybookView } from '@storybook/react-native'; import { theme as lightTheme } from '@storybook/react-native-theming'; @@ -15,16 +17,23 @@ import { StorybookUIComponent } from './StorybookUI'; jest.mock('./DesktopDriverBridge', () => ({ DesktopDriverBridge: jest.fn(() => null) })); jest.mock('./StorybookUI', () => ({ StorybookUIComponent: jest.fn(() => null) })); +type Scene = Awaited<ReturnType<typeof render>>; + function createTestApp(storyBackgroundColor?: string) { const roots: RootSettings[] = []; const bridgeRoots: RootSettings[] = []; const themes: ThemeState[] = []; + const chromeThemes: ThemeState[] = []; + const appearances: ThemeAppearanceState[] = []; + const legacyThemes: (LegacyTheme | undefined)[] = []; const mounted = jest.fn(); const unmounted = jest.fn(); function Story() { roots.push(useRootSettings()); themes.push(useThemeState()); + appearances.push(useThemeAppearance()); + legacyThemes.push(React.useContext(ThemeContext)); React.useEffect(() => { mounted(); return unmounted; @@ -36,7 +45,10 @@ function createTestApp(storyBackgroundColor?: string) { bridgeRoots.push(useRootSettings()); return null; }); - jest.mocked(StorybookUIComponent).mockImplementation(({ children }) => <>{children}</>); + jest.mocked(StorybookUIComponent).mockImplementation(({ children }) => { + chromeThemes.push(useThemeState()); + return <>{children}</>; + }); const getStorybookUI = jest.fn<ReturnType<StorybookView['getStorybookUI']>, Parameters<StorybookView['getStorybookUI']>>((params) => { const UI = params?.CustomUIComponent; @@ -56,24 +68,61 @@ function createTestApp(storyBackgroundColor?: string) { ); }); const App = createDesktopStorybookApp({ getStorybookUI }, { enableWebsockets: false, testIDPrefix: 'test' }); - return { App, roots, bridgeRoots, themes, mounted, unmounted, getStorybookUI }; + return { App, roots, bridgeRoots, themes, chromeThemes, appearances, legacyThemes, mounted, unmounted, getStorybookUI }; +} + +async function selectTheme(scene: Scene, axis: string, value: string) { + await fireEvent.press(scene.getByTestId(`test-theme-${axis}`)); + await fireEvent.press(scene.getByTestId(`test-theme-${axis}-${value}`)); } +function latestStorybookTheme() { + const calls = jest.mocked(StorybookUIComponent).mock.calls; + return calls[calls.length - 1][0].theme; +} + +const selectionSteps = [ + ['scheme', 'dark'], + ['tone', 'warm'], + ['contrast', 'highContrast'], + ['source', 'fluent'], + ['contrast', 'standard'], + ['scheme', 'light'], + ['source', 'flex'], + ['tone', 'cool'], +] as const; + afterEach(() => { jest.clearAllMocks(); jest.restoreAllMocks(); }); describe('Storybook app theme root', () => { - it('places the toolbar, UI, story, and runtime bridge in the same default Flex scene', async () => { - const { App, roots, bridgeRoots, themes } = createTestApp(); + it('places the toolbar, UI, story, and runtime bridge in one deterministic default Flex scene', async () => { + const { App, roots, bridgeRoots, themes, chromeThemes, appearances, legacyThemes } = createTestApp(); const scene = await render(<App />); expect(scene.getByTestId('test-app-root')).toBeOnTheScreen(); expect(scene.getByTestId('test-theme-toolbar')).toBeOnTheScreen(); expect(scene.getByTestId('selected-story')).toBeOnTheScreen(); - expect(scene.getByRole('button', { name: 'Default Flex' })).toBeOnTheScreen(); + for (const [axis, label] of [ + ['source', 'Flex'], + ['scheme', 'Light'], + ['contrast', 'Standard'], + ['tone', 'Cool'], + ]) { + const trigger = scene.getByTestId(`test-theme-${axis}`); + expect(trigger.props.accessibilityValue).toEqual({ text: label }); + expect(trigger.props.accessibilityState).toEqual({ disabled: false, expanded: false }); + } + expect(appearances[0]).toEqual({ + requested: { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'system', colorTone: 'cool' }, + resolved: { colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base', colorTone: 'cool' }, + }); + expect(themes[0].appearance).toBe(appearances[0].resolved); expect(themes[0].tokens).toEqual(defaultFlexTokens); + expect(chromeThemes[0]).toBe(themes[0]); + expect(legacyThemes[0]).toBeUndefined(); expect(bridgeRoots.every((root) => root === roots[0])).toBe(true); expect(roots[0].inputModality).toBe('pointer'); }); @@ -95,68 +144,157 @@ describe('Storybook app theme root', () => { expect(roots).toHaveLength(renderCount); }); - it.each(['none', 'light', 'dark'])('keeps the %s canvas distinct from the Secondary Button fill', async (choice) => { + it('opens one axis menu at a time and closes it after a selection', async () => { + const { App } = createTestApp(); + const scene = await render(<App />); + + await fireEvent.press(scene.getByTestId('test-theme-scheme')); + expect(scene.getByTestId('test-theme-scheme').props.accessibilityState.expanded).toBe(true); + expect(scene.getByTestId('test-theme-scheme-light').props.accessibilityState.selected).toBe(true); + expect(scene.getByTestId('test-theme-scheme-system')).toBeOnTheScreen(); + + await fireEvent.press(scene.getByTestId('test-theme-source')); + expect(scene.queryByTestId('test-theme-scheme-menu')).toBeNull(); + expect(scene.getByTestId('test-theme-source-menu')).toBeOnTheScreen(); + + await fireEvent.press(scene.getByTestId('test-theme-source')); + expect(scene.queryByTestId('test-theme-source-menu')).toBeNull(); + + await selectTheme(scene, 'scheme', 'dark'); + expect(scene.queryByTestId('test-theme-scheme-menu')).toBeNull(); + expect(scene.getByTestId('test-theme-scheme').props.accessibilityValue).toEqual({ text: 'Dark' }); + }); + + it('applies scheme, contrast, and tone to the Flex defaults', async () => { const { App, themes } = createTestApp(); const scene = await render(<App />); + const coolLight = themes[themes.length - 1].tokens; + + await selectTheme(scene, 'tone', 'warm'); + const warmLight = themes[themes.length - 1]; + expect(warmLight.appearance).toEqual({ colorScheme: 'light', contrast: 'standard', interfaceLevel: 'base', colorTone: 'warm' }); + expect(warmLight.tokens.color.surfaceNeutralFar.rest).not.toBe(coolLight.color.surfaceNeutralFar.rest); + + await selectTheme(scene, 'scheme', 'dark'); + const warmDark = themes[themes.length - 1]; + expect(warmDark.appearance.colorScheme).toBe('dark'); + expect(warmDark.tokens.color.surfaceNeutralFar.rest).not.toBe(warmLight.tokens.color.surfaceNeutralFar.rest); + expect(warmDark.tokens.color.backgroundBrandLoud.hover).not.toBe(warmDark.tokens.color.backgroundBrandLoud.rest); + + await selectTheme(scene, 'contrast', 'highContrast'); + const highContrast = themes[themes.length - 1]; + expect(highContrast.appearance.contrast).toBe('highContrast'); + expect(highContrast.tokens.color.backgroundBrandLoud.hover).toBe(highContrast.tokens.color.backgroundBrandLoud.rest); + expect(highContrast.tokens.color.backgroundBrandLoud.pressed).toBe(highContrast.tokens.color.backgroundBrandLoud.rest); + }); + + it('follows the platform scheme only when System is selected', async () => { + jest.spyOn(Appearance, 'getColorScheme').mockReturnValue('dark'); + const { App, themes, appearances } = createTestApp(); + const scene = await render(<App />); + expect(themes[themes.length - 1].appearance.colorScheme).toBe('light'); + + await selectTheme(scene, 'scheme', 'system'); + expect(appearances[appearances.length - 1].requested.colorScheme).toBe('system'); + expect(themes[themes.length - 1].appearance.colorScheme).toBe('dark'); + }); + + it('applies the legacy Fluent default theme to stories without tone and restores the Flex tone', async () => { + const { App, themes, chromeThemes, legacyThemes } = createTestApp(); + const scene = await render(<App />); + await selectTheme(scene, 'tone', 'warm'); + + await selectTheme(scene, 'source', 'fluent'); + const tone = scene.getByTestId('test-theme-tone'); + expect(tone.props.accessibilityState).toEqual({ disabled: true, expanded: false }); + expect(tone.props.accessibilityValue).toEqual({ text: 'Cool' }); + await fireEvent.press(tone); + expect(scene.queryByTestId('test-theme-tone-menu')).toBeNull(); + expect(themes[themes.length - 1].appearance.colorTone).toBe('cool'); + expect(themes[themes.length - 1].tokens).not.toEqual(defaultFlexTokens); + expect(chromeThemes[chromeThemes.length - 1].tokens).toEqual(defaultFlexTokens); + expect(legacyThemes[legacyThemes.length - 1]?.host.appearance).toBe('light'); + + await selectTheme(scene, 'scheme', 'dark'); + expect(legacyThemes[legacyThemes.length - 1]?.host.appearance).toBe('dark'); + await selectTheme(scene, 'contrast', 'highContrast'); + expect(legacyThemes[legacyThemes.length - 1]?.host.appearance).toBe('highContrast'); + + await selectTheme(scene, 'source', 'flex'); + expect(legacyThemes[legacyThemes.length - 1]).toBeUndefined(); + expect(scene.getByTestId('test-theme-tone').props.accessibilityValue).toEqual({ text: 'Warm' }); + expect(themes[themes.length - 1].appearance.colorTone).toBe('warm'); + }); + + it.each([ + ['flex', 'light'], + ['flex', 'dark'], + ['fluent', 'light'], + ['fluent', 'dark'], + ])('keeps the Flex canvas distinct from the %s %s Secondary Button fill', async (source, scheme) => { + const { App, themes, chromeThemes } = createTestApp(); + const scene = await render(<App />); - await fireEvent.press(scene.getByTestId(`test-theme-${choice}`)); + await selectTheme(scene, 'source', source); + await selectTheme(scene, 'scheme', scheme); - const state = themes[themes.length - 1]; - const calls = jest.mocked(StorybookUIComponent).mock.calls; - const theme = calls[calls.length - 1][0].theme; - expect(theme.background.content).toBe(state.tokens.color.surfaceNeutralFar); + const story = themes[themes.length - 1]; + const chrome = chromeThemes[chromeThemes.length - 1]; + const theme = latestStorybookTheme(); + expect(theme.background.content).toBe(chrome.tokens.color.surfaceNeutralFar.rest); expect(theme.background.content).toBe(theme.background.preview); - expect(theme.background.content).not.toBe(state.tokens.color.backgroundNeutralSubtle); + expect(theme.background.content).not.toBe(story.tokens.color.backgroundNeutralSubtle.rest); }); it.each(['#ffeedd', 'transparent'])('preserves the explicit %s story background across theme changes', async (storyBackgroundColor) => { const { App } = createTestApp(storyBackgroundColor); const scene = await render(<App />); - for (const choice of ['none', 'dark', 'light']) { - await fireEvent.press(scene.getByTestId(`test-theme-${choice}`)); + for (const [axis, value] of selectionSteps) { + await selectTheme(scene, axis, value); const calls = jest.mocked(StorybookUIComponent).mock.calls; expect(calls[calls.length - 1][0].storyBackgroundColor).toBe(storyBackgroundColor); } }); - it('switches chrome and story colors together without recreating Storybook or resetting the scene', async () => { - const warn = jest.spyOn(console, 'warn').mockImplementation(); - const { App, roots, themes, mounted, unmounted, getStorybookUI } = createTestApp(); + it('switches Flex chrome and selected story colors together without recreating Storybook or resetting the scene', async () => { + const flex = new FlexThemeReference(); + const { App, roots, themes, chromeThemes, mounted, unmounted, getStorybookUI } = createTestApp(); const scene = await render(<App />); const root = roots[0]; - const defaultBackground = themes[0].tokens.color.surfaceNeutralFar; - const backgrounds: Record<string, unknown> = {}; + const defaultBackground = themes[0].tokens.color.surfaceNeutralFar.rest; + const backgrounds = new Set<unknown>([defaultBackground]); + let source = 'flex'; await fireEvent(scene.getByTestId('test-app-root'), 'keyDownCapture', { nativeEvent: { key: 'Tab' } }); - for (const choice of ['dark', 'highContrast', 'light', 'none']) { - await fireEvent.press(scene.getByTestId(`test-theme-${choice}`)); - const state = themes[themes.length - 1]; - const calls = jest.mocked(StorybookUIComponent).mock.calls; - const theme = calls[calls.length - 1][0].theme; - backgrounds[choice] = theme.background.app; + for (const [axis, value] of selectionSteps) { + await selectTheme(scene, axis, value); + source = axis === 'source' ? value : source; + const story = themes[themes.length - 1]; + const chrome = chromeThemes[chromeThemes.length - 1]; + const { color } = chrome.tokens; + const theme = latestStorybookTheme(); + backgrounds.add(theme.background.app); - expect(scene.getByTestId(`test-theme-${choice}`).props.accessibilityState.selected).toBe(true); + expect(chrome.appearance).toEqual(story.appearance); + expect(chrome.tokens).toEqual(flex.resolveFlexTokens(chrome.appearance)); + expect(story === chrome).toBe(source === 'flex'); expect(StyleSheet.flatten(scene.getByTestId('test-theme-toolbar').props.style).backgroundColor).toBe( - state.tokens.color.backgroundNeutralSubtle, + color.backgroundNeutralSubtle.rest, ); - expect(StyleSheet.flatten(scene.getByText('Theme').props.style).color).toBe(state.tokens.color.foregroundNeutralPrimary); - const foreground = theme.base === 'dark' ? state.tokens.color.fixedWhite : state.tokens.color.fixedBlack; - const background = theme.base === 'dark' ? state.tokens.color.fixedBlack : state.tokens.color.fixedWhite; - const literal = (value: unknown, fallback: unknown) => (typeof value === 'string' ? value : fallback); - expect(theme.background.app).toBe(literal(state.tokens.color.surfaceNeutralFar, background)); - expect(theme.background.content).toBe(literal(state.tokens.color.surfaceNeutralFar, background)); - expect(theme.background.preview).toBe(literal(state.tokens.color.surfaceNeutralFar, background)); - expect(theme.color.defaultText).toBe(literal(state.tokens.color.foregroundNeutralPrimary, foreground)); - expect(theme.input.color).toBe(literal(state.tokens.color.foregroundNeutralPrimary, foreground)); - expect(theme.button.background).toBe(literal(state.tokens.color.backgroundNeutralLoud, background)); + expect(StyleSheet.flatten(scene.getByText('Theme').props.style).color).toBe(color.foregroundNeutralPrimary.rest); + expect(theme.background.app).toBe(color.surfaceNeutralFar.rest); + expect(theme.background.content).toBe(color.surfaceNeutralFar.rest); + expect(theme.background.preview).toBe(color.surfaceNeutralFar.rest); + expect(theme.color.defaultText).toBe(color.foregroundNeutralPrimary.rest); + expect(theme.input.color).toBe(color.foregroundNeutralPrimary.rest); + expect(theme.button.background).toBe(color.backgroundNeutralLoud.rest); expect(root.inputModality).toBe('keyboard'); expect(roots.every((settings) => settings === root)).toBe(true); } - expect(backgrounds.dark).not.toBe(backgrounds.light); - expect(backgrounds.none).toBe(defaultBackground); - expect(warn).toHaveBeenCalledWith(expect.stringContaining('Storybook chrome cannot resolve native system colors')); + expect(themes[themes.length - 1].tokens.color.surfaceNeutralFar.rest).toBe(defaultBackground); + expect(backgrounds.size).toBeGreaterThan(3); expect(getStorybookUI).toHaveBeenCalledTimes(1); expect(mounted).toHaveBeenCalledTimes(1); expect(unmounted).not.toHaveBeenCalled(); diff --git a/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.tsx b/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.tsx index 5904b7f039e..c18706a18c4 100644 --- a/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.tsx +++ b/packages/agentic/storybook-desktop-runtime/src/StorybookTheme.tsx @@ -2,66 +2,158 @@ import * as React from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; import { createDefaultTheme } from '@fluentui-react-native/default-theme'; -import { ThemedRoot, themedStyleSheetFactory, useThemeState } from '@fluentui-react-native/design'; -import type { ThemeReference } from '@fluentui-react-native/design/theming'; +import { FlexThemeReference, ThemedRoot, ThemeProvider, themedStyleSheetFactory, useThemeState } from '@fluentui-react-native/design'; +import type { ColorTone, ThemeAppearanceOptions, ThemeSource } from '@fluentui-react-native/design'; import { useDesktopStorybookTestID } from './DesktopStorybookConfig'; -type ThemeChoice = { - label: string; - theme?: ThemeReference; +/** The theme configuration selected in the Storybook toolbar. */ +export type StorybookThemeSelection = { + /** The story theme: the package's Flex defaults or the legacy Fluent default theme. The chrome always uses Flex. */ + source: 'flex' | 'fluent'; + colorScheme: 'light' | 'dark' | 'system'; + contrast: 'standard' | 'highContrast'; + /** Flex palette and interaction tone. Legacy Fluent themes have no tone. */ + colorTone: ColorTone; }; -const themeChoiceNames = ['none', 'light', 'dark', 'highContrast'] as const; -type ThemeChoiceName = (typeof themeChoiceNames)[number]; +type ThemeAxisKey = keyof StorybookThemeSelection; -const themeChoices: Record<ThemeChoiceName, ThemeChoice> = { - none: { label: 'Default Flex' }, - light: { label: 'Light', theme: createDefaultTheme({ appearance: 'light' }) }, - dark: { label: 'Dark', theme: createDefaultTheme({ appearance: 'dark' }) }, - highContrast: { label: 'High contrast', theme: createDefaultTheme({ appearance: 'highContrast' }) }, +type ThemeAxis = { + readonly key: ThemeAxisKey; + /** Stable test-ID segment for the axis and its options. */ + readonly id: string; + readonly label: string; + readonly options: readonly { readonly value: string; readonly label: string }[]; }; +/** A deterministic default that does not depend on the host appearance. */ +export const defaultStorybookThemeSelection: Readonly<StorybookThemeSelection> = Object.freeze({ + source: 'flex', + colorScheme: 'light', + contrast: 'standard', + colorTone: 'cool', +}); + +function themeAxis<Key extends ThemeAxisKey>( + key: Key, + id: string, + label: string, + options: readonly { value: StorybookThemeSelection[Key]; label: string }[], +): ThemeAxis { + return { key, id, label, options }; +} + +const themeAxes: readonly ThemeAxis[] = [ + themeAxis('source', 'source', 'Theme', [ + { value: 'flex', label: 'Flex' }, + { value: 'fluent', label: 'Fluent' }, + ]), + themeAxis('colorScheme', 'scheme', 'Scheme', [ + { value: 'light', label: 'Light' }, + { value: 'dark', label: 'Dark' }, + { value: 'system', label: 'System' }, + ]), + themeAxis('contrast', 'contrast', 'Contrast', [ + { value: 'standard', label: 'Standard' }, + { value: 'highContrast', label: 'High' }, + ]), + themeAxis('colorTone', 'tone', 'Tone', [ + { value: 'cool', label: 'Cool' }, + { value: 'warm', label: 'Warm' }, + ]), +]; + +// Each source resolves every appearance itself, so selection changes only the appearance request. +const themeSources: Record<StorybookThemeSelection['source'], ThemeSource> = { + flex: new FlexThemeReference(), + fluent: createDefaultTheme({ appearance: 'dynamic' }), +}; + +function appearanceFromSelection({ source, colorScheme, contrast, colorTone }: StorybookThemeSelection): ThemeAppearanceOptions { + // Omitting tone for Fluent keeps the resolved appearance at its cool default. + return source === 'flex' ? { colorScheme, contrast, colorTone } : { colorScheme, contrast }; +} + +function isAxisDisabled(key: ThemeAxisKey, selection: StorybookThemeSelection): boolean { + return key === 'colorTone' && selection.source !== 'flex'; +} + +type StoryTheme = { + readonly theme: ThemeSource; + readonly appearance: ThemeAppearanceOptions; +}; + +const StoryThemeContext = React.createContext<StoryTheme | undefined>(undefined); + export function StorybookThemeHost({ children }: React.PropsWithChildren) { - const [selectedName, setSelectedName] = React.useState<ThemeChoiceName>('none'); + const [selection, setSelection] = React.useState<StorybookThemeSelection>(defaultStorybookThemeSelection); + const storyTheme = React.useMemo<StoryTheme>( + () => ({ theme: themeSources[selection.source], appearance: appearanceFromSelection(selection) }), + [selection], + ); const testID = useDesktopStorybookTestID('app-root'); + // The chrome always uses Flex at the selected appearance; only story content follows the selected source. return ( - <ThemedRoot style={layoutStyles.root} testID={testID} theme={themeChoices[selectedName].theme}> - <StorybookThemeContent selectedName={selectedName} onSelect={setSelectedName}> - {children} - </StorybookThemeContent> + <ThemedRoot appearance={storyTheme.appearance} style={layoutStyles.root} testID={testID} theme={themeSources.flex}> + <StoryThemeContext.Provider value={storyTheme}> + <StorybookThemeContent selection={selection} onSelectionChange={setSelection}> + {children} + </StorybookThemeContent> + </StoryThemeContext.Provider> </ThemedRoot> ); } +/** Applies the selected story theme inside the Flex chrome without adding a view or a second input root. */ +export function StorybookStoryTheme({ children }: React.PropsWithChildren) { + const storyTheme = React.useContext(StoryThemeContext); + if (!storyTheme) { + return <>{children}</>; + } + return ( + <ThemeProvider appearance={storyTheme.appearance} theme={storyTheme.theme}> + {children} + </ThemeProvider> + ); +} + function StorybookThemeContent({ children, - selectedName, - onSelect, -}: React.PropsWithChildren<{ selectedName: ThemeChoiceName; onSelect: (name: ThemeChoiceName) => void }>) { + selection, + onSelectionChange, +}: React.PropsWithChildren<{ + selection: StorybookThemeSelection; + onSelectionChange: React.Dispatch<React.SetStateAction<StorybookThemeSelection>>; +}>) { const styles = getStyles(useThemeState()); const toolbarTestID = useDesktopStorybookTestID('theme-toolbar'); - const optionTestID = useDesktopStorybookTestID('theme'); + const axisTestID = useDesktopStorybookTestID('theme'); + const [openAxis, setOpenAxis] = React.useState<ThemeAxisKey>(); + + const select = (key: ThemeAxisKey, value: string) => { + onSelectionChange((current) => (current[key] === value ? current : ({ ...current, [key]: value } as StorybookThemeSelection))); + setOpenAxis(undefined); + }; return ( <View style={styles.root}> <View accessibilityRole="toolbar" style={styles.header} testID={toolbarTestID}> - <Text style={styles.label}>Theme</Text> - {themeChoiceNames.map((name) => { - const choice = themeChoices[name]; - const selected = name === selectedName; + {themeAxes.map((axis) => { + const disabled = isAxisDisabled(axis.key, selection); return ( - <Pressable - accessibilityRole="button" - accessibilityState={{ selected }} - key={name} - onPress={() => onSelect(name)} - style={({ pressed }) => [styles.option, selected && styles.selectedOption, pressed && styles.pressedOption]} - testID={`${optionTestID}-${name}`} - > - <Text style={[styles.optionText, selected && styles.selectedOptionText]}>{choice.label}</Text> - </Pressable> + <ThemeAxisDropdown + axis={axis} + disabled={disabled} + key={axis.key} + open={!disabled && openAxis === axis.key} + styles={styles} + testID={`${axisTestID}-${axis.id}`} + value={disabled ? defaultStorybookThemeSelection[axis.key] : selection[axis.key]} + onSelect={(value) => select(axis.key, value)} + onToggle={() => setOpenAxis((current) => (current === axis.key ? undefined : axis.key))} + /> ); })} </View> @@ -70,6 +162,65 @@ function StorybookThemeContent({ ); } +type ThemeAxisDropdownProps = { + axis: ThemeAxis; + disabled: boolean; + open: boolean; + styles: ReturnType<typeof getStyles>; + testID: string; + value: string; + onSelect(value: string): void; + onToggle(): void; +}; + +function ThemeAxisDropdown({ axis, disabled, open, styles, testID, value, onSelect, onToggle }: ThemeAxisDropdownProps) { + const selectedLabel = axis.options.find((option) => option.value === value)?.label ?? value; + + return ( + <View style={styles.field}> + <Text style={[styles.label, disabled && styles.disabledText]}>{axis.label}</Text> + <View> + <Pressable + accessibilityLabel={axis.label} + accessibilityRole="combobox" + accessibilityState={{ disabled, expanded: open }} + accessibilityValue={{ text: selectedLabel }} + disabled={disabled} + onPress={onToggle} + style={({ pressed }) => [styles.option, styles.trigger, pressed && styles.pressedOption, disabled && styles.disabledOption]} + testID={testID} + > + <Text style={[styles.optionText, disabled && styles.disabledText]}>{selectedLabel}</Text> + <Text style={[styles.chevron, disabled && styles.disabledText]}>{open ? '\u25b4' : '\u25be'}</Text> + </Pressable> + {open ? ( + <View accessibilityRole="list" style={styles.menu} testID={`${testID}-menu`}> + {axis.options.map((option) => { + const selected = option.value === value; + return ( + <Pressable + accessibilityRole="button" + accessibilityState={{ selected }} + key={option.value} + onPress={() => onSelect(option.value)} + style={({ pressed }) => [ + styles.menuOption, + selected && styles.selectedOption, + pressed && (selected ? styles.pressedSelectedOption : styles.pressedMenuOption), + ]} + testID={`${testID}-${option.value}`} + > + <Text style={[styles.optionText, selected && styles.selectedOptionText]}>{option.label}</Text> + </Pressable> + ); + })} + </View> + ) : null} + </View> + </View> + ); +} + const layoutStyles = StyleSheet.create({ root: { flex: 1, @@ -80,48 +231,91 @@ const getStyles = themedStyleSheetFactory('StorybookTheme', ({ tokens }) => StyleSheet.create({ root: { flex: 1, - backgroundColor: tokens.color.surfaceNeutralFar, + backgroundColor: tokens.color.surfaceNeutralFar.rest, }, header: { - alignItems: 'center', - backgroundColor: tokens.color.backgroundNeutralSubtle, - borderBottomColor: tokens.color.strokeNeutralSubtle, + alignItems: 'flex-start', + backgroundColor: tokens.color.backgroundNeutralSubtle.rest, + borderBottomColor: tokens.color.strokeNeutralSubtle.rest, borderBottomWidth: 1, flexDirection: 'row', flexWrap: 'wrap', - gap: 8, + gap: 16, minHeight: 44, paddingHorizontal: 12, - paddingVertical: 6, + paddingVertical: 8, + }, + field: { + alignItems: 'flex-start', + flexDirection: 'row', + gap: 6, }, label: { - color: tokens.color.foregroundNeutralPrimary, + color: tokens.color.foregroundNeutralPrimary.rest, fontSize: 14, fontWeight: '600', - marginEnd: 4, + paddingVertical: 5, }, option: { - backgroundColor: tokens.color.backgroundNeutralLoud, - borderColor: tokens.color.strokeNeutralSoft, + backgroundColor: tokens.color.surfaceNeutralNearer.rest, + borderColor: tokens.color.strokeNeutralLoud.rest, borderRadius: 4, borderWidth: 1, paddingHorizontal: 10, paddingVertical: 5, }, - selectedOption: { - backgroundColor: tokens.color.backgroundBrandHeavy, - borderColor: tokens.color.strokeBrandLoud, + trigger: { + alignItems: 'center', + flexDirection: 'row', + gap: 8, + justifyContent: 'space-between', + minWidth: 96, }, pressedOption: { - opacity: 0.75, + backgroundColor: tokens.color.surfaceNeutralNearer.pressed, + borderColor: tokens.color.strokeNeutralLoud.pressed, + }, + disabledOption: { + backgroundColor: tokens.color.backgroundNeutralDisabled.rest, + borderColor: tokens.color.strokeNeutralDisabled.rest, + }, + menu: { + backgroundColor: tokens.color.surfaceNeutralNearer.rest, + borderColor: tokens.color.strokeNeutralSubtle.rest, + borderRadius: 4, + borderWidth: 1, + gap: 2, + marginTop: 4, + padding: 2, + }, + menuOption: { + backgroundColor: tokens.color.backgroundNeutralTransparent.rest, + borderRadius: 3, + paddingHorizontal: 10, + paddingVertical: 5, + }, + pressedMenuOption: { + backgroundColor: tokens.color.backgroundNeutralTransparent.pressed, + }, + selectedOption: { + backgroundColor: tokens.color.backgroundNeutralSoft.rest, + }, + pressedSelectedOption: { + backgroundColor: tokens.color.backgroundNeutralSoft.pressed, }, optionText: { - color: tokens.color.foregroundNeutralPrimary, + color: tokens.color.foregroundNeutralPrimary.rest, + fontSize: 12, + }, + chevron: { + color: tokens.color.foregroundNeutralSecondary.rest, fontSize: 12, }, selectedOptionText: { - color: tokens.color.foregroundBrandOnloud, fontWeight: '600', }, + disabledText: { + color: tokens.color.foregroundNeutralDisabled.rest, + }, }), ); diff --git a/packages/agentic/storybook-desktop-runtime/src/ThemedStorybookUI.tsx b/packages/agentic/storybook-desktop-runtime/src/ThemedStorybookUI.tsx index 629a7283bb7..7b8654f0f8e 100644 --- a/packages/agentic/storybook-desktop-runtime/src/ThemedStorybookUI.tsx +++ b/packages/agentic/storybook-desktop-runtime/src/ThemedStorybookUI.tsx @@ -1,9 +1,14 @@ import type { SBUI } from '@storybook/react-native-ui-common'; +import { StorybookStoryTheme } from './StorybookTheme'; import { StorybookUIComponent } from './StorybookUI'; import { useStorybookTheme } from './useStorybookTheme'; -export const ThemedStorybookUI: SBUI = (props) => { +export const ThemedStorybookUI: SBUI = ({ children, ...props }) => { const theme = useStorybookTheme(); - return <StorybookUIComponent {...props} theme={theme} />; + return ( + <StorybookUIComponent {...props} theme={theme}> + <StorybookStoryTheme>{children}</StorybookStoryTheme> + </StorybookUIComponent> + ); }; diff --git a/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.test.tsx b/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.test.tsx index 1118ab7d3a7..c69b42709df 100644 --- a/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.test.tsx +++ b/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.test.tsx @@ -47,7 +47,7 @@ describe('Storybook theme palette', () => { expect(themes[themes.length - 1].background.content).toBe('#654321'); expect(themes[themes.length - 1].background.preview).toBe('#654321'); expect(themes[themes.length - 1]).not.toBe(themes[0]); - expect(themes[themes.length - 1].appBorderColor).toBe(states[states.length - 1].tokens.color.strokeNeutralSubtle); + expect(themes[themes.length - 1].appBorderColor).toBe(states[states.length - 1].tokens.color.strokeNeutralSubtle.rest); }); it('warns and substitutes a contrasting theme color for native opaque colors', async () => { @@ -60,7 +60,7 @@ describe('Storybook theme palette', () => { <Probe themes={themes} states={states} /> </ThemedRoot>, ); - expect(themes[0].color.primary).toBe(states[0].tokens.color.fixedBlack); + expect(themes[0].color.primary).toBe(states[0].tokens.color.fixedBlack.rest); expect(warn).toHaveBeenCalledTimes(1); expect(warn).toHaveBeenCalledWith(expect.stringContaining('foregroundBrandPrimary')); }); @@ -84,8 +84,8 @@ describe('Storybook theme palette', () => { </ThemedRoot>, ); - expect(themes[0].background.content).toBe(states[0].tokens.color[fallback]); - expect(themes[0].background.preview).toBe(states[0].tokens.color[fallback]); + expect(themes[0].background.content).toBe(states[0].tokens.color[fallback].rest); + expect(themes[0].background.preview).toBe(states[0].tokens.color[fallback].rest); expect(warn).toHaveBeenCalledTimes(1); expect(warn).toHaveBeenCalledWith(expect.stringContaining('surfaceNeutralFar')); }); diff --git a/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.ts b/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.ts index 840cc7d9e95..4cfe02a5781 100644 --- a/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.ts +++ b/packages/agentic/storybook-desktop-runtime/src/useStorybookTheme.ts @@ -24,14 +24,14 @@ function storybookThemeFromThemeState({ appearance, highContrast, tokens }: Them const background = base.base === 'dark' ? 'fixedBlack' : 'fixedWhite'; const nativeColors = new Set<keyof SemanticColorTokenValues>(); const color = (name: keyof SemanticColorTokenValues, role: 'foreground' | 'background' = 'foreground'): string => { - const value = tokens.color[name]; + const value = tokens.color[name].rest; // Storybook also passes these colors to JS color utilities, not just native styles. if (typeof value === 'string') { return value; } nativeColors.add(name); const fallbackName = role === 'foreground' ? foreground : background; - const fallback = tokens.color[fallbackName]; + const fallback = tokens.color[fallbackName].rest; if (typeof fallback !== 'string') { throw new Error(`Storybook chrome requires a literal "${fallbackName}" fallback for the "${name}" theme token.`); } diff --git a/packages/components/Badge/src/__tests__/__snapshots__/Badge.test.tsx.snap b/packages/components/Badge/src/__tests__/__snapshots__/Badge.test.tsx.snap index 42e26f68f83..ed4fbdae56b 100644 --- a/packages/components/Badge/src/__tests__/__snapshots__/Badge.test.tsx.snap +++ b/packages/components/Badge/src/__tests__/__snapshots__/Badge.test.tsx.snap @@ -8,7 +8,7 @@ exports[`Badge component tests Badge all props 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderColor": "#0f6cbd", "borderRadius": 4, "borderWidth": 1, @@ -29,9 +29,12 @@ exports[`Badge component tests Badge all props 1`] = ` style={ { "color": "#fff", + "dynamicTypeRamp": "body", "fontFamily": "Arial", "fontSize": 16, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -64,8 +67,8 @@ exports[`Badge component tests Badge tokens 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "yellow", - "borderColor": "#f09", + "backgroundColor": "#0f6cbd", + "borderColor": "#00000000", "borderRadius": 9999, "borderWidth": 4, "bottom": 0, @@ -86,6 +89,7 @@ exports[`Badge component tests Badge tokens 1`] = ` numberOfLines={0} style={ { + "color": "#ffffff", "fontFamily": "System", "fontSize": 12, "fontWeight": "400", @@ -104,7 +108,8 @@ exports[`Badge component tests Empty Badge 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#0f6cbd", + "borderColor": "#00000000", "borderRadius": 9999, "borderWidth": 1, "bottom": 0, @@ -126,6 +131,8 @@ exports[`Badge component tests Filled badge with shadow 1`] = ` style={ { "alignSelf": "flex-start", + "backgroundColor": "#0f6cbd", + "borderColor": "#00000000", "borderRadius": 9999, "bottom": 0, "justifyContent": "center", @@ -149,6 +156,8 @@ exports[`Badge component tests Filled badge with shadow 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", + "backgroundColor": "#0f6cbd", + "borderColor": "#00000000", "borderRadius": 9999, "borderWidth": 1, "flexDirection": "row", @@ -173,6 +182,7 @@ exports[`Badge component tests Filled badge with shadow 1`] = ` numberOfLines={0} style={ { + "color": "#ffffff", "fontFamily": "System", "fontSize": 12, "fontWeight": "400", @@ -195,7 +205,8 @@ exports[`CounterBadge component tests CounterBadge all props 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 1, "bottom": 0, @@ -214,9 +225,12 @@ exports[`CounterBadge component tests CounterBadge all props 1`] = ` style={ { "color": "#fff", + "dynamicTypeRamp": "body", "fontFamily": "Arial", "fontSize": 16, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -228,13 +242,13 @@ exports[`CounterBadge component tests CounterBadge all props 1`] = ` numberOfLines={0} style={ { - "color": "#323130", + "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, @@ -252,7 +266,8 @@ exports[`CounterBadge component tests CounterBadge shows 99+ 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#0f6cbd", + "borderColor": "#00000000", "borderRadius": 9999, "borderWidth": 1, "bottom": 0, @@ -271,13 +286,13 @@ exports[`CounterBadge component tests CounterBadge shows 99+ 1`] = ` numberOfLines={0} style={ { - "color": "#323130", + "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, @@ -295,7 +310,8 @@ exports[`CounterBadge component tests CounterBadge shows 1000+ 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#0f6cbd", + "borderColor": "#00000000", "borderRadius": 9999, "borderWidth": 1, "bottom": 0, @@ -314,13 +330,13 @@ exports[`CounterBadge component tests CounterBadge shows 1000+ 1`] = ` numberOfLines={0} style={ { - "color": "#323130", + "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, @@ -339,7 +355,8 @@ exports[`CounterBadge component tests CounterBadge shows zero 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#0f6cbd", + "borderColor": "#00000000", "borderRadius": 9999, "borderWidth": 1, "bottom": 0, @@ -358,13 +375,13 @@ exports[`CounterBadge component tests CounterBadge shows zero 1`] = ` numberOfLines={0} style={ { - "color": "#323130", + "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, @@ -402,13 +419,13 @@ exports[`CounterBadge component tests CounterBadge tokens 1`] = ` numberOfLines={0} style={ { - "color": "#323130", + "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, diff --git a/packages/components/Button/src/FAB/__snapshots__/FAB.test.tsx.snap b/packages/components/Button/src/FAB/__snapshots__/FAB.test.tsx.snap index b9bccf7e849..1c09067d681 100644 --- a/packages/components/Button/src/FAB/__snapshots__/FAB.test.tsx.snap +++ b/packages/components/Button/src/FAB/__snapshots__/FAB.test.tsx.snap @@ -60,9 +60,12 @@ exports[`Custom FAB with no shadow(iOS) 1`] = ` style={ { "color": "#fff", + "dynamicTypeRamp": "body", "fontFamily": "Arial", "fontSize": 16, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -77,7 +80,7 @@ exports[`Custom FAB with no shadow(iOS) 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -178,9 +181,12 @@ exports[`Default FAB (iOS) 1`] = ` style={ { "color": "#fff", + "dynamicTypeRamp": "body", "fontFamily": "Arial", "fontSize": 16, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -195,7 +201,7 @@ exports[`Default FAB (iOS) 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "600", "margin": 0, "marginBottom": 0, diff --git a/packages/components/Button/src/ToggleButton/__snapshots__/ToggleButton.test.tsx.snap b/packages/components/Button/src/ToggleButton/__snapshots__/ToggleButton.test.tsx.snap index bff788bf319..50b57be3aa5 100644 --- a/packages/components/Button/src/ToggleButton/__snapshots__/ToggleButton.test.tsx.snap +++ b/packages/components/Button/src/ToggleButton/__snapshots__/ToggleButton.test.tsx.snap @@ -69,7 +69,7 @@ exports[`ToggleButton default 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, diff --git a/packages/components/Button/src/__snapshots__/Button.test.tsx.snap b/packages/components/Button/src/__snapshots__/Button.test.tsx.snap index d088c90b4d7..c70b7a40d95 100644 --- a/packages/components/Button/src/__snapshots__/Button.test.tsx.snap +++ b/packages/components/Button/src/__snapshots__/Button.test.tsx.snap @@ -63,7 +63,7 @@ exports[`Button component tests Button circular 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -139,7 +139,7 @@ exports[`Button component tests Button composed 1`] = ` "color": "#ffffff", "dynamicTypeRamp": undefined, "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontStyle": undefined, "fontWeight": "600", "letterSpacing": undefined, @@ -220,7 +220,7 @@ exports[`Button component tests Button customized 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -297,7 +297,7 @@ exports[`Button component tests Button default 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -352,7 +352,7 @@ exports[`Button component tests Button disabled 1`] = ` "alignItems": "center", "alignSelf": "flex-start", "backgroundColor": "#b4d6fa", - "borderColor": "#f3f2f1", + "borderColor": "#e0e0e0", "borderRadius": 8, "borderWidth": 1, "display": "flex", @@ -374,7 +374,7 @@ exports[`Button component tests Button disabled 1`] = ` { "color": "#bdbdbd", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -452,7 +452,7 @@ exports[`Button component tests Button large 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -530,7 +530,7 @@ exports[`Button component tests Button primary 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -608,7 +608,7 @@ exports[`Button component tests Button small 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -686,7 +686,7 @@ exports[`Button component tests Button square 1`] = ` { "color": "#ffffff", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, @@ -741,8 +741,8 @@ exports[`Button component tests Button subtle 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": "#ffffff", - "borderColor": "#ffffff", + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 8, "borderWidth": 1, "display": "flex", @@ -762,9 +762,9 @@ exports[`Button component tests Button subtle 1`] = ` numberOfLines={0} style={ { - "color": "#323130", + "color": "#242424", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", "margin": 0, "marginBottom": 0, diff --git a/packages/components/Button/src/__snapshots__/ColorTokens.test.win32.ts.snap b/packages/components/Button/src/__snapshots__/ColorTokens.test.win32.ts.snap index ffb840ffd2e..794504e3ac5 100644 --- a/packages/components/Button/src/__snapshots__/ColorTokens.test.win32.ts.snap +++ b/packages/components/Button/src/__snapshots__/ColorTokens.test.win32.ts.snap @@ -331,6 +331,7 @@ exports[`Button color tokens pins v1 CompoundButton color tokens 1`] = ` exports[`Button color tokens pins v1 FAB color tokens 1`] = ` { "backgroundColor": "#D83B01", + "color": "#ffffff", "disabled": { "backgroundColor": "#ebebeb", "color": "#B1B1B1", @@ -340,9 +341,14 @@ exports[`Button color tokens pins v1 FAB color tokens 1`] = ` "backgroundColor": "#D83B01", "borderColor": "#969696", "borderInnerColor": "#ffffff", + "color": "#ffffff", + "iconColor": "#ffffff", }, + "iconColor": "#ffffff", "pressed": { "backgroundColor": "#A22C01", + "color": "#ffffff", + "iconColor": "#ffffff", }, "rippleColor": "#D4D4D4", "subtle": { @@ -363,6 +369,8 @@ exports[`Button color tokens pins v1 FAB color tokens 1`] = ` "iconColor": "#aec6eb", "pressed": { "backgroundColor": "#B1B1B1", + "color": "#185abd", + "iconColor": "#185abd", }, "rippleColor": "#D4D4D4", }, diff --git a/packages/components/Button/src/__snapshots__/ColorTokens.test.windows.ts.snap b/packages/components/Button/src/__snapshots__/ColorTokens.test.windows.ts.snap index ffb840ffd2e..794504e3ac5 100644 --- a/packages/components/Button/src/__snapshots__/ColorTokens.test.windows.ts.snap +++ b/packages/components/Button/src/__snapshots__/ColorTokens.test.windows.ts.snap @@ -331,6 +331,7 @@ exports[`Button color tokens pins v1 CompoundButton color tokens 1`] = ` exports[`Button color tokens pins v1 FAB color tokens 1`] = ` { "backgroundColor": "#D83B01", + "color": "#ffffff", "disabled": { "backgroundColor": "#ebebeb", "color": "#B1B1B1", @@ -340,9 +341,14 @@ exports[`Button color tokens pins v1 FAB color tokens 1`] = ` "backgroundColor": "#D83B01", "borderColor": "#969696", "borderInnerColor": "#ffffff", + "color": "#ffffff", + "iconColor": "#ffffff", }, + "iconColor": "#ffffff", "pressed": { "backgroundColor": "#A22C01", + "color": "#ffffff", + "iconColor": "#ffffff", }, "rippleColor": "#D4D4D4", "subtle": { @@ -363,6 +369,8 @@ exports[`Button color tokens pins v1 FAB color tokens 1`] = ` "iconColor": "#aec6eb", "pressed": { "backgroundColor": "#B1B1B1", + "color": "#185abd", + "iconColor": "#185abd", }, "rippleColor": "#D4D4D4", }, diff --git a/packages/components/Button/src/deprecated/__snapshots__/Button.test.tsx.snap b/packages/components/Button/src/deprecated/__snapshots__/Button.test.tsx.snap index e77d0aed4e3..f497a3cd5d5 100644 --- a/packages/components/Button/src/deprecated/__snapshots__/Button.test.tsx.snap +++ b/packages/components/Button/src/deprecated/__snapshots__/Button.test.tsx.snap @@ -25,8 +25,8 @@ exports[`Button default 1`] = ` { "alignItems": "flex-start", "alignSelf": "flex-start", - "backgroundColor": "#f3f2f1", - "borderColor": "#8a8886", + "backgroundColor": "#ffffff", + "borderColor": "#d1d1d1", "borderRadius": 4, "borderWidth": 1, "display": "flex", @@ -62,10 +62,13 @@ exports[`Button default 1`] = ` <Text style={ { - "color": "#323130", + "color": "#242424", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, "marginEnd": 2, "marginStart": 2, diff --git a/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.win32.ts.snap b/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.win32.ts.snap index f9978e77c68..e3fd6f5cf76 100644 --- a/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.win32.ts.snap +++ b/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.win32.ts.snap @@ -78,5 +78,6 @@ exports[`Checkbox color tokens pins v1 Checkbox color tokens 1`] = ` "checkmarkColor": "#262626", "color": "#262626", }, + "requiredColor": "#bc2f32", } `; diff --git a/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.windows.ts.snap b/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.windows.ts.snap index f9978e77c68..e3fd6f5cf76 100644 --- a/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.windows.ts.snap +++ b/packages/components/Checkbox/src/__snapshots__/ColorTokens.test.windows.ts.snap @@ -78,5 +78,6 @@ exports[`Checkbox color tokens pins v1 Checkbox color tokens 1`] = ` "checkmarkColor": "#262626", "color": "#262626", }, + "requiredColor": "#bc2f32", } `; diff --git a/packages/components/Checkbox/src/__tests__/__snapshots__/Checkbox.test.tsx.snap b/packages/components/Checkbox/src/__tests__/__snapshots__/Checkbox.test.tsx.snap index a2a9b2013a4..c9a9eed6fc3 100644 --- a/packages/components/Checkbox/src/__tests__/__snapshots__/Checkbox.test.tsx.snap +++ b/packages/components/Checkbox/src/__tests__/__snapshots__/Checkbox.test.tsx.snap @@ -95,6 +95,7 @@ exports[`Checkbox component tests Checkbox all props 1`] = ` onAccessibilityTap={[Function]} style={ { + "color": "#bc2f32", "fontFamily": "Segoe UI", "fontSize": 14, "fontWeight": "400", diff --git a/packages/components/Chip/src/__snapshots__/ChipColorTokens.test.win32.ts.snap b/packages/components/Chip/src/__snapshots__/ChipColorTokens.test.win32.ts.snap index b71c85659d6..55724e94681 100644 --- a/packages/components/Chip/src/__snapshots__/ChipColorTokens.test.win32.ts.snap +++ b/packages/components/Chip/src/__snapshots__/ChipColorTokens.test.win32.ts.snap @@ -4,8 +4,11 @@ exports[`pins Chip color tokens on Win32 1`] = ` { "backgroundColor": "#ebebeb", "brand": { + "backgroundColor": "#d2e0f4", + "color": "#1651aa", "selected": { "backgroundColor": "#D83B01", + "color": "#ffffff", }, }, "color": "#666666", @@ -19,10 +22,17 @@ exports[`pins Chip color tokens on Win32 1`] = ` }, "disabled": { "backgroundColor": "#ebebeb", + "color": "#bdbdbd", }, "searchBar": { "backgroundColor": "#e6e6e6", "brand": { + "backgroundColor": "#d2e0f4", + "color": "#ffffff", + "disabled": { + "backgroundColor": "#d2e0f4", + "color": "#bdbdbd", + }, "selected": { "backgroundColor": "antiquewhite", "color": "#aec6eb", @@ -31,6 +41,11 @@ exports[`pins Chip color tokens on Win32 1`] = ` "color": "#262626", "disabled": { "backgroundColor": "#e6e6e6", + "color": "#bdbdbd", + }, + "selected": { + "backgroundColor": "#616161", + "color": "#ffffff", }, }, "selected": { diff --git a/packages/components/Chip/src/__tests__/__snapshots__/Chip.test.tsx.snap b/packages/components/Chip/src/__tests__/__snapshots__/Chip.test.tsx.snap index 56bd2b201fb..0cf1414cd57 100644 --- a/packages/components/Chip/src/__tests__/__snapshots__/Chip.test.tsx.snap +++ b/packages/components/Chip/src/__tests__/__snapshots__/Chip.test.tsx.snap @@ -68,6 +68,8 @@ exports[`Chip component tests Chip all props 1`] = ` "fontFamily": "Arial", "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -81,9 +83,11 @@ exports[`Chip component tests Chip all props 1`] = ` style={ { "color": "#616161", - "fontFamily": "Segoe UI", + "fontFamily": "Roboto", "fontSize": 14, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 18, "margin": 0, "marginStart": 8, } @@ -152,9 +156,11 @@ exports[`Chip component tests Chip tokens 1`] = ` style={ { "color": "#616161", - "fontFamily": "Segoe UI", + "fontFamily": "Roboto", "fontSize": 14, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 18, "margin": 0, } } diff --git a/packages/components/ContextualMenu/src/__tests__/__snapshots__/ContextualMenu.test.tsx.snap b/packages/components/ContextualMenu/src/__tests__/__snapshots__/ContextualMenu.test.tsx.snap index b24e3de0559..44bb3b2c6a6 100644 --- a/packages/components/ContextualMenu/src/__tests__/__snapshots__/ContextualMenu.test.tsx.snap +++ b/packages/components/ContextualMenu/src/__tests__/__snapshots__/ContextualMenu.test.tsx.snap @@ -17,7 +17,7 @@ exports[`ContextualMenu default props 1`] = ` }, { "backgroundColor": "#ffffff", - "borderColor": "#8a8886", + "borderColor": "#d1d1d1", "borderWidth": 1, }, ] diff --git a/packages/components/Divider/src/__tests__/__snapshots__/Divider.test.tsx.snap b/packages/components/Divider/src/__tests__/__snapshots__/Divider.test.tsx.snap index bca753fb65b..65252b5de31 100644 --- a/packages/components/Divider/src/__tests__/__snapshots__/Divider.test.tsx.snap +++ b/packages/components/Divider/src/__tests__/__snapshots__/Divider.test.tsx.snap @@ -135,7 +135,7 @@ exports[`Divider component tests Divider with all props + tokens set 1`] = ` style={ { "color": "red", - "fontFamily": "System", + "fontFamily": "Segoe UI", "fontSize": 10, "fontStyle": "italic", "fontWeight": "600", diff --git a/packages/components/Input/src/__tests__/__snapshots__/Input.test.tsx.snap b/packages/components/Input/src/__tests__/__snapshots__/Input.test.tsx.snap index ffe805c2a64..d7962eadb67 100644 --- a/packages/components/Input/src/__tests__/__snapshots__/Input.test.tsx.snap +++ b/packages/components/Input/src/__tests__/__snapshots__/Input.test.tsx.snap @@ -51,12 +51,12 @@ exports[`Input component tests Input default 1`] = ` "dynamicTypeRamp": undefined, "flexGrow": 1, "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -125,12 +125,12 @@ exports[`Input component tests Input in error state 1`] = ` "dynamicTypeRamp": undefined, "flexGrow": 1, "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -147,6 +147,11 @@ exports[`Input component tests Input in error state 1`] = ` style={ { "color": "#bc2f32", + "fontFamily": "Roboto", + "fontSize": 12, + "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 16, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -193,6 +198,11 @@ exports[`Input component tests Input with all optional text 1`] = ` style={ { "color": "#616161", + "fontFamily": "Roboto", + "fontSize": 12, + "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 16, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -228,12 +238,12 @@ exports[`Input component tests Input with all optional text 1`] = ` "dynamicTypeRamp": undefined, "flexGrow": 1, "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -250,6 +260,11 @@ exports[`Input component tests Input with all optional text 1`] = ` style={ { "color": "#616161", + "fontFamily": "Roboto", + "fontSize": 12, + "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 16, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -320,6 +335,8 @@ exports[`Input component tests Input with icon 1`] = ` "fontFamily": "Arial", "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -351,12 +368,12 @@ exports[`Input component tests Input with icon 1`] = ` "dynamicTypeRamp": undefined, "flexGrow": 1, "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -426,12 +443,12 @@ exports[`Input component tests Input with placeholder 1`] = ` "dynamicTypeRamp": undefined, "flexGrow": 1, "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginBottom": 0, "marginEnd": 0, @@ -500,12 +517,12 @@ exports[`Input component tests Input without accessoryIcon 1`] = ` "dynamicTypeRamp": undefined, "flexGrow": 1, "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginBottom": 0, "marginEnd": 0, diff --git a/packages/components/Link/src/__tests__/__snapshots__/Link.test.tsx.snap b/packages/components/Link/src/__tests__/__snapshots__/Link.test.tsx.snap index 209cbebd0a0..eea6c11f77b 100644 --- a/packages/components/Link/src/__tests__/__snapshots__/Link.test.tsx.snap +++ b/packages/components/Link/src/__tests__/__snapshots__/Link.test.tsx.snap @@ -40,9 +40,11 @@ exports[`Link component tests Default Link 1`] = ` { "alignSelf": "flex-start", "color": "#0f6cbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -91,9 +93,11 @@ exports[`Link component tests Default Link as a pressable 1`] = ` { "alignSelf": "flex-start", "color": "#0f6cbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -143,9 +147,11 @@ exports[`Link component tests Inline Link 1`] = ` { "alignSelf": "flex-start", "color": "#0f6cbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "textDecorationLine": "underline", } @@ -197,9 +203,11 @@ exports[`Link component tests Subtle Link 1`] = ` { "alignSelf": "flex-start", "color": "#0f6cbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } diff --git a/packages/components/Link/src/legacy/__tests__/__snapshots__/Link.test.tsx.snap b/packages/components/Link/src/legacy/__tests__/__snapshots__/Link.test.tsx.snap index 87b44b3d008..3d1f326295a 100644 --- a/packages/components/Link/src/legacy/__tests__/__snapshots__/Link.test.tsx.snap +++ b/packages/components/Link/src/legacy/__tests__/__snapshots__/Link.test.tsx.snap @@ -34,9 +34,11 @@ exports[`Link all props 1`] = ` "borderStyle": "solid", "borderWidth": 2, "color": "#0f6cbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "textAlign": "center", "textDecorationLine": "underline", @@ -82,9 +84,11 @@ exports[`Link with child 1`] = ` "borderStyle": "solid", "borderWidth": 2, "color": "#0f6cbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "textAlign": "center", "textDecorationLine": "underline", diff --git a/packages/components/Notification/src/__tests__/__snapshots__/Notification.test.tsx.snap b/packages/components/Notification/src/__tests__/__snapshots__/Notification.test.tsx.snap index 5bfc706d5fa..bd1cfcaa43a 100644 --- a/packages/components/Notification/src/__tests__/__snapshots__/Notification.test.tsx.snap +++ b/packages/components/Notification/src/__tests__/__snapshots__/Notification.test.tsx.snap @@ -78,6 +78,8 @@ exports[`Notification component tests Notification default 1`] = ` "fontFamily": "System", "fontSize": 15, "fontWeight": "400", + "letterSpacing": -0.23, + "lineHeight": 20, "margin": 0, } } @@ -141,7 +143,7 @@ exports[`Notification component tests Notification default 1`] = ` "alignItems": "center", "alignSelf": "center", "backgroundColor": "transparent", - "borderColor": "#ffffff", + "borderColor": "#00000000", "borderRadius": 8, "borderWidth": 1, "display": "flex", @@ -164,8 +166,10 @@ exports[`Notification component tests Notification default 1`] = ` { "color": "#0f548c", "fontFamily": "System", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600", + "letterSpacing": -0.23, + "lineHeight": 20, "margin": 0, "marginBottom": 0, "marginEnd": 0, diff --git a/packages/components/RadioGroup/src/Radio/__tests__/__snapshots__/RadioExperimental.test.tsx.snap b/packages/components/RadioGroup/src/Radio/__tests__/__snapshots__/RadioExperimental.test.tsx.snap index 2fa97ebaf87..046fddbabb8 100644 --- a/packages/components/RadioGroup/src/Radio/__tests__/__snapshots__/RadioExperimental.test.tsx.snap +++ b/packages/components/RadioGroup/src/Radio/__tests__/__snapshots__/RadioExperimental.test.tsx.snap @@ -150,9 +150,11 @@ exports[`Radio component tests Radio default 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -314,9 +316,11 @@ exports[`Radio component tests Radio disabled 1`] = ` style={ { "color": "#bdbdbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } diff --git a/packages/components/RadioGroup/src/RadioGroup/__tests__/__snapshots__/RadioGroupExperimental.test.tsx.snap b/packages/components/RadioGroup/src/RadioGroup/__tests__/__snapshots__/RadioGroupExperimental.test.tsx.snap index 94b276b5ec3..22ec0c35bb0 100644 --- a/packages/components/RadioGroup/src/RadioGroup/__tests__/__snapshots__/RadioGroupExperimental.test.tsx.snap +++ b/packages/components/RadioGroup/src/RadioGroup/__tests__/__snapshots__/RadioGroupExperimental.test.tsx.snap @@ -36,9 +36,11 @@ exports[`RadioGroup component tests Radio not direct child of radio group 1`] = style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, - "fontWeight": "600", + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -205,9 +207,11 @@ exports[`RadioGroup component tests Radio not direct child of radio group 1`] = style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -366,9 +370,11 @@ exports[`RadioGroup component tests Radio not direct child of radio group 1`] = style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -418,9 +424,11 @@ exports[`RadioGroup component tests RadioGroup default 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, - "fontWeight": "600", + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -587,9 +595,11 @@ exports[`RadioGroup component tests RadioGroup default 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -748,9 +758,11 @@ exports[`RadioGroup component tests RadioGroup default 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -800,9 +812,11 @@ exports[`RadioGroup component tests RadioGroup disabled 1`] = ` style={ { "color": "#bdbdbd", - "fontFamily": "Segoe UI", - "fontSize": 13, - "fontWeight": "600", + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -969,9 +983,11 @@ exports[`RadioGroup component tests RadioGroup disabled 1`] = ` style={ { "color": "#bdbdbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -1130,9 +1146,11 @@ exports[`RadioGroup component tests RadioGroup disabled 1`] = ` style={ { "color": "#bdbdbd", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -1183,9 +1201,11 @@ exports[`RadioGroup component tests RadioGroup horizontal 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, - "fontWeight": "600", + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -1352,9 +1372,11 @@ exports[`RadioGroup component tests RadioGroup horizontal 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -1513,9 +1535,11 @@ exports[`RadioGroup component tests RadioGroup horizontal 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -1566,9 +1590,11 @@ exports[`RadioGroup component tests RadioGroup horizontal-stacked 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, - "fontWeight": "600", + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -1735,9 +1761,11 @@ exports[`RadioGroup component tests RadioGroup horizontal-stacked 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -1896,9 +1924,11 @@ exports[`RadioGroup component tests RadioGroup horizontal-stacked 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -1948,9 +1978,11 @@ exports[`RadioGroup component tests RadioGroup required 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, - "fontWeight": "600", + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -1963,9 +1995,11 @@ exports[`RadioGroup component tests RadioGroup required 1`] = ` style={ { "color": "#750b1c", - "fontFamily": "Segoe UI", - "fontSize": 13, - "fontWeight": "600", + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "paddingStart": 2, } @@ -2133,9 +2167,11 @@ exports[`RadioGroup component tests RadioGroup required 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } @@ -2294,9 +2330,11 @@ exports[`RadioGroup component tests RadioGroup required 1`] = ` style={ { "color": "#242424", - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginHorizontal": 2, } diff --git a/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.win32.ts.snap b/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.win32.ts.snap index e4f3fc0cb8b..0b1a358b226 100644 --- a/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.win32.ts.snap +++ b/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.win32.ts.snap @@ -85,5 +85,6 @@ exports[`RadioGroup color tokens pins RadioGroup v1 colors: RadioGroup v1 1`] = "disabled": { "color": "#B1B1B1", }, + "requiredColor": "#d13438", } `; diff --git a/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.windows.ts.snap b/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.windows.ts.snap index e4f3fc0cb8b..0b1a358b226 100644 --- a/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.windows.ts.snap +++ b/packages/components/RadioGroup/src/__tests__/__snapshots__/ColorTokens.test.windows.ts.snap @@ -85,5 +85,6 @@ exports[`RadioGroup color tokens pins RadioGroup v1 colors: RadioGroup v1 1`] = "disabled": { "color": "#B1B1B1", }, + "requiredColor": "#d13438", } `; diff --git a/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButton.test.tsx.snap b/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButton.test.tsx.snap index 29917aaf2f1..ee10064d3fc 100644 --- a/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButton.test.tsx.snap +++ b/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButton.test.tsx.snap @@ -48,7 +48,7 @@ exports[`RadioButton component tests RadioButton default 1`] = ` style={ { "backgroundColor": "transparent", - "borderColor": "#323130", + "borderColor": "#242424", "borderRadius": 10, "borderStyle": "solid", "borderWidth": 1, @@ -66,7 +66,7 @@ exports[`RadioButton component tests RadioButton default 1`] = ` <View style={ { - "backgroundColor": "#323130", + "backgroundColor": "#242424", "borderRadius": 5, "height": 10, "left": 4, @@ -84,10 +84,12 @@ exports[`RadioButton component tests RadioButton default 1`] = ` "borderColor": "transparent", "borderStyle": "solid", "borderWidth": 2, - "color": "#323130", - "fontFamily": "Segoe UI", - "fontSize": 16, - "fontWeight": "400", + "color": "#242424", + "fontFamily": "Roboto", + "fontSize": 18, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginTop": 2, } diff --git a/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButtonGroup.test.tsx.snap b/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButtonGroup.test.tsx.snap index 21112a731d0..60e18bd51c2 100644 --- a/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButtonGroup.test.tsx.snap +++ b/packages/components/RadioGroup/src/legacy/__tests__/__snapshots__/RadioButtonGroup.test.tsx.snap @@ -16,10 +16,12 @@ exports[`RadioButton component tests RadioButton default 1`] = ` <Text style={ { - "color": "#323130", - "fontFamily": "Segoe UI", + "color": "#242424", + "fontFamily": "Roboto", "fontSize": 16, "fontWeight": "600", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -76,7 +78,7 @@ exports[`RadioButton component tests RadioButton default 1`] = ` style={ { "backgroundColor": "transparent", - "borderColor": "#323130", + "borderColor": "#242424", "borderRadius": 10, "borderStyle": "solid", "borderWidth": 1, @@ -94,7 +96,7 @@ exports[`RadioButton component tests RadioButton default 1`] = ` <View style={ { - "backgroundColor": "#323130", + "backgroundColor": "#242424", "borderRadius": 5, "height": 10, "left": 4, @@ -112,10 +114,12 @@ exports[`RadioButton component tests RadioButton default 1`] = ` "borderColor": "transparent", "borderStyle": "solid", "borderWidth": 2, - "color": "#323130", - "fontFamily": "Segoe UI", - "fontSize": 16, - "fontWeight": "400", + "color": "#242424", + "fontFamily": "Roboto", + "fontSize": 18, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginTop": 2, } @@ -171,7 +175,7 @@ exports[`RadioButton component tests RadioButton default 1`] = ` style={ { "backgroundColor": "transparent", - "borderColor": "#323130", + "borderColor": "#242424", "borderRadius": 10, "borderStyle": "solid", "borderWidth": 1, @@ -189,7 +193,7 @@ exports[`RadioButton component tests RadioButton default 1`] = ` <View style={ { - "backgroundColor": "#323130", + "backgroundColor": "#242424", "borderRadius": 5, "height": 10, "left": 4, @@ -207,10 +211,12 @@ exports[`RadioButton component tests RadioButton default 1`] = ` "borderColor": "transparent", "borderStyle": "solid", "borderWidth": 2, - "color": "#323130", - "fontFamily": "Segoe UI", - "fontSize": 16, - "fontWeight": "400", + "color": "#242424", + "fontFamily": "Roboto", + "fontSize": 18, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginTop": 2, } @@ -239,10 +245,12 @@ exports[`RadioButton component tests RadioButton not direct child of radio group <Text style={ { - "color": "#323130", - "fontFamily": "Segoe UI", + "color": "#242424", + "fontFamily": "Roboto", "fontSize": 16, "fontWeight": "600", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -300,7 +308,7 @@ exports[`RadioButton component tests RadioButton not direct child of radio group style={ { "backgroundColor": "transparent", - "borderColor": "#323130", + "borderColor": "#242424", "borderRadius": 10, "borderStyle": "solid", "borderWidth": 1, @@ -318,7 +326,7 @@ exports[`RadioButton component tests RadioButton not direct child of radio group <View style={ { - "backgroundColor": "#323130", + "backgroundColor": "#242424", "borderRadius": 5, "height": 10, "left": 4, @@ -336,10 +344,12 @@ exports[`RadioButton component tests RadioButton not direct child of radio group "borderColor": "transparent", "borderStyle": "solid", "borderWidth": 2, - "color": "#323130", - "fontFamily": "Segoe UI", - "fontSize": 16, - "fontWeight": "400", + "color": "#242424", + "fontFamily": "Roboto", + "fontSize": 18, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginTop": 2, } @@ -395,7 +405,7 @@ exports[`RadioButton component tests RadioButton not direct child of radio group style={ { "backgroundColor": "transparent", - "borderColor": "#323130", + "borderColor": "#242424", "borderRadius": 10, "borderStyle": "solid", "borderWidth": 1, @@ -413,7 +423,7 @@ exports[`RadioButton component tests RadioButton not direct child of radio group <View style={ { - "backgroundColor": "#323130", + "backgroundColor": "#242424", "borderRadius": 5, "height": 10, "left": 4, @@ -431,10 +441,12 @@ exports[`RadioButton component tests RadioButton not direct child of radio group "borderColor": "transparent", "borderStyle": "solid", "borderWidth": 2, - "color": "#323130", - "fontFamily": "Segoe UI", - "fontSize": 16, - "fontWeight": "400", + "color": "#242424", + "fontFamily": "Roboto", + "fontSize": 18, + "fontWeight": "500", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "marginTop": 2, } diff --git a/packages/components/Stack/src/__tests__/__snapshots__/Stack.test.tsx.snap b/packages/components/Stack/src/__tests__/__snapshots__/Stack.test.tsx.snap index cdf90f64c3b..31d16876d85 100644 --- a/packages/components/Stack/src/__tests__/__snapshots__/Stack.test.tsx.snap +++ b/packages/components/Stack/src/__tests__/__snapshots__/Stack.test.tsx.snap @@ -13,7 +13,7 @@ exports[`Stack with tokens 1`] = ` <Text style={ { - "color": "#323130", + "color": "#242424", "fontFamily": "Segoe UI", "fontSize": 12, "fontWeight": "400", @@ -26,7 +26,7 @@ exports[`Stack with tokens 1`] = ` <Text style={ { - "color": "#323130", + "color": "#242424", "fontFamily": "Segoe UI", "fontSize": 12, "fontWeight": "400", @@ -40,7 +40,7 @@ exports[`Stack with tokens 1`] = ` <Text style={ { - "color": "#323130", + "color": "#242424", "fontFamily": "Segoe UI", "fontSize": 12, "fontWeight": "400", diff --git a/packages/components/Switch/src/__tests__/__snapshots__/Switch.test.tsx.snap b/packages/components/Switch/src/__tests__/__snapshots__/Switch.test.tsx.snap index 5e31d6bc58b..918c0207fe6 100644 --- a/packages/components/Switch/src/__tests__/__snapshots__/Switch.test.tsx.snap +++ b/packages/components/Switch/src/__tests__/__snapshots__/Switch.test.tsx.snap @@ -71,9 +71,11 @@ exports[`Switch Default 1`] = ` { "color": "#242424", "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } @@ -197,9 +199,11 @@ exports[`Switch Disabled 1`] = ` { "color": "#e0e0e0", "flexShrink": 1, - "fontFamily": "Segoe UI", - "fontSize": 13, + "fontFamily": "Roboto", + "fontSize": 16, "fontWeight": "400", + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, } } diff --git a/packages/components/TabList/src/Tab/__tests__/__snapshots__/Tab.test.tsx.snap b/packages/components/TabList/src/Tab/__tests__/__snapshots__/Tab.test.tsx.snap index 5b70717ea02..abc5b2e3ccc 100644 --- a/packages/components/TabList/src/Tab/__tests__/__snapshots__/Tab.test.tsx.snap +++ b/packages/components/TabList/src/Tab/__tests__/__snapshots__/Tab.test.tsx.snap @@ -48,7 +48,8 @@ exports[`Tab component tests Customized Tab 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -88,9 +89,12 @@ exports[`Tab component tests Customized Tab 1`] = ` style={ { "color": "red", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -102,7 +106,7 @@ exports[`Tab component tests Customized Tab 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 4, "paddingHorizontal": 8, "width": "100%", @@ -112,7 +116,7 @@ exports[`Tab component tests Customized Tab 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -170,7 +174,8 @@ exports[`Tab component tests Tab default props 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -210,9 +215,12 @@ exports[`Tab component tests Tab default props 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -224,7 +232,7 @@ exports[`Tab component tests Tab default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 8, "width": "100%", @@ -234,7 +242,7 @@ exports[`Tab component tests Tab default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -292,7 +300,8 @@ exports[`Tab component tests Tab disabled 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -331,9 +340,13 @@ exports[`Tab component tests Tab disabled 1`] = ` numberOfLines={1} style={ { + "color": "#bdbdbd", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -345,7 +358,7 @@ exports[`Tab component tests Tab disabled 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 8, "width": "100%", @@ -355,7 +368,7 @@ exports[`Tab component tests Tab disabled 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -413,7 +426,8 @@ exports[`Tab component tests Tab render icon + text 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -465,9 +479,12 @@ exports[`Tab component tests Tab render icon + text 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -479,7 +496,7 @@ exports[`Tab component tests Tab render icon + text 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 8, "width": "100%", @@ -489,7 +506,7 @@ exports[`Tab component tests Tab render icon + text 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -547,7 +564,8 @@ exports[`Tab component tests Tab render icon only 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -588,7 +606,7 @@ exports[`Tab component tests Tab render icon only 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 8, "width": "100%", @@ -598,7 +616,7 @@ exports[`Tab component tests Tab render icon only 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } diff --git a/packages/components/TabList/src/TabList/__tests__/__snapshots__/TabList.test.tsx.snap b/packages/components/TabList/src/TabList/__tests__/__snapshots__/TabList.test.tsx.snap index 04b11362c02..de6a2f0615e 100644 --- a/packages/components/TabList/src/TabList/__tests__/__snapshots__/TabList.test.tsx.snap +++ b/packages/components/TabList/src/TabList/__tests__/__snapshots__/TabList.test.tsx.snap @@ -86,7 +86,8 @@ exports[`TabList component tests TabList appearance 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -126,9 +127,12 @@ exports[`TabList component tests TabList appearance 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -140,7 +144,7 @@ exports[`TabList component tests TabList appearance 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -150,7 +154,7 @@ exports[`TabList component tests TabList appearance 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -205,7 +209,8 @@ exports[`TabList component tests TabList appearance 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -245,9 +250,12 @@ exports[`TabList component tests TabList appearance 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -259,7 +267,7 @@ exports[`TabList component tests TabList appearance 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -269,7 +277,7 @@ exports[`TabList component tests TabList appearance 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -324,7 +332,8 @@ exports[`TabList component tests TabList appearance 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -364,9 +373,12 @@ exports[`TabList component tests TabList appearance 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -378,7 +390,7 @@ exports[`TabList component tests TabList appearance 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -388,7 +400,7 @@ exports[`TabList component tests TabList appearance 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -487,7 +499,8 @@ exports[`TabList component tests TabList default props 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -527,9 +540,12 @@ exports[`TabList component tests TabList default props 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -541,7 +557,7 @@ exports[`TabList component tests TabList default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -551,7 +567,7 @@ exports[`TabList component tests TabList default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -606,7 +622,8 @@ exports[`TabList component tests TabList default props 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -646,9 +663,12 @@ exports[`TabList component tests TabList default props 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -660,7 +680,7 @@ exports[`TabList component tests TabList default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -670,7 +690,7 @@ exports[`TabList component tests TabList default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -725,7 +745,8 @@ exports[`TabList component tests TabList default props 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -765,9 +786,12 @@ exports[`TabList component tests TabList default props 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -779,7 +803,7 @@ exports[`TabList component tests TabList default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -789,7 +813,7 @@ exports[`TabList component tests TabList default props 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -888,7 +912,8 @@ exports[`TabList component tests TabList disabled list 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -927,9 +952,13 @@ exports[`TabList component tests TabList disabled list 1`] = ` numberOfLines={1} style={ { + "color": "#bdbdbd", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -941,7 +970,7 @@ exports[`TabList component tests TabList disabled list 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -951,7 +980,7 @@ exports[`TabList component tests TabList disabled list 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -1006,7 +1035,8 @@ exports[`TabList component tests TabList disabled list 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1045,9 +1075,13 @@ exports[`TabList component tests TabList disabled list 1`] = ` numberOfLines={1} style={ { + "color": "#bdbdbd", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1059,7 +1093,7 @@ exports[`TabList component tests TabList disabled list 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -1069,7 +1103,7 @@ exports[`TabList component tests TabList disabled list 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -1124,7 +1158,8 @@ exports[`TabList component tests TabList disabled list 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1163,9 +1198,13 @@ exports[`TabList component tests TabList disabled list 1`] = ` numberOfLines={1} style={ { + "color": "#bdbdbd", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1177,7 +1216,7 @@ exports[`TabList component tests TabList disabled list 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -1187,7 +1226,7 @@ exports[`TabList component tests TabList disabled list 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -1286,7 +1325,8 @@ exports[`TabList component tests TabList orientation 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1325,9 +1365,12 @@ exports[`TabList component tests TabList orientation 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1339,7 +1382,7 @@ exports[`TabList component tests TabList orientation 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": "100%", "paddingVertical": 12, "width": 2, @@ -1349,7 +1392,7 @@ exports[`TabList component tests TabList orientation 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -1404,7 +1447,8 @@ exports[`TabList component tests TabList orientation 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1443,9 +1487,12 @@ exports[`TabList component tests TabList orientation 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1457,7 +1504,7 @@ exports[`TabList component tests TabList orientation 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": "100%", "paddingVertical": 12, "width": 2, @@ -1467,7 +1514,7 @@ exports[`TabList component tests TabList orientation 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -1522,7 +1569,8 @@ exports[`TabList component tests TabList orientation 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1561,9 +1609,12 @@ exports[`TabList component tests TabList orientation 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1575,7 +1626,7 @@ exports[`TabList component tests TabList orientation 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": "100%", "paddingVertical": 12, "width": 2, @@ -1585,7 +1636,7 @@ exports[`TabList component tests TabList orientation 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -1685,7 +1736,8 @@ exports[`TabList component tests TabList selected key 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1725,9 +1777,12 @@ exports[`TabList component tests TabList selected key 1`] = ` style={ { "color": "#242424", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "600", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1739,7 +1794,7 @@ exports[`TabList component tests TabList selected key 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -1749,7 +1804,7 @@ exports[`TabList component tests TabList selected key 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#0f6cbd", "borderRadius": 99, "flex": 1, } @@ -1804,7 +1859,8 @@ exports[`TabList component tests TabList selected key 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1844,9 +1900,12 @@ exports[`TabList component tests TabList selected key 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1858,7 +1917,7 @@ exports[`TabList component tests TabList selected key 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -1868,7 +1927,7 @@ exports[`TabList component tests TabList selected key 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -1923,7 +1982,8 @@ exports[`TabList component tests TabList selected key 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -1963,9 +2023,12 @@ exports[`TabList component tests TabList selected key 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "body", "fontFamily": "System", - "fontSize": 13, + "fontSize": 17, "fontWeight": "400", + "letterSpacing": -0.43, + "lineHeight": 22, "margin": 0, } } @@ -1977,7 +2040,7 @@ exports[`TabList component tests TabList selected key 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -1987,7 +2050,7 @@ exports[`TabList component tests TabList selected key 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -2086,7 +2149,8 @@ exports[`TabList component tests TabList size 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -2126,9 +2190,12 @@ exports[`TabList component tests TabList size 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "subheadline", "fontFamily": "System", "fontSize": 15, "fontWeight": "400", + "letterSpacing": -0.23, + "lineHeight": 20, "margin": 0, } } @@ -2140,7 +2207,7 @@ exports[`TabList component tests TabList size 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -2150,7 +2217,7 @@ exports[`TabList component tests TabList size 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -2205,7 +2272,8 @@ exports[`TabList component tests TabList size 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -2245,9 +2313,12 @@ exports[`TabList component tests TabList size 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "subheadline", "fontFamily": "System", "fontSize": 15, "fontWeight": "400", + "letterSpacing": -0.23, + "lineHeight": 20, "margin": 0, } } @@ -2259,7 +2330,7 @@ exports[`TabList component tests TabList size 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -2269,7 +2340,7 @@ exports[`TabList component tests TabList size 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } @@ -2324,7 +2395,8 @@ exports[`TabList component tests TabList size 1`] = ` { "alignItems": "center", "alignSelf": "flex-start", - "backgroundColor": undefined, + "backgroundColor": "#00000000", + "borderColor": "#00000000", "borderRadius": 4, "borderWidth": 2, "display": "flex", @@ -2364,9 +2436,12 @@ exports[`TabList component tests TabList size 1`] = ` style={ { "color": "#616161", + "dynamicTypeRamp": "subheadline", "fontFamily": "System", "fontSize": 15, "fontWeight": "400", + "letterSpacing": -0.23, + "lineHeight": 20, "margin": 0, } } @@ -2378,7 +2453,7 @@ exports[`TabList component tests TabList size 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "height": 2, "paddingHorizontal": 12, "width": "100%", @@ -2388,7 +2463,7 @@ exports[`TabList component tests TabList size 1`] = ` <View style={ { - "backgroundColor": undefined, + "backgroundColor": "#00000000", "borderRadius": 99, "flex": 1, } diff --git a/packages/components/Text/MIGRATION.md b/packages/components/Text/MIGRATION.md index 281c19cc8e7..239875d9415 100644 --- a/packages/components/Text/MIGRATION.md +++ b/packages/components/Text/MIGRATION.md @@ -21,7 +21,7 @@ import { TextV1 as Text } from '@fluentui-react-native/text'; ### Props changed -- `variant` => Prop name remains identical, but will support a different collection of named font variants. Newly defined v1 variants can be found in [Typography.types](../../agentic/design/src/theming/types/Typography.types.ts) under theme-types. +- `variant` => Prop name remains identical, but will support a different collection of named font variants. Newly defined v1 variants can be found in [Typography.types](../../agentic/design/src/fluent/types/Typography.types.ts) under theme-types. ### Props added diff --git a/packages/components/Text/src/__tests__/__snapshots__/Text.test.tsx.snap b/packages/components/Text/src/__tests__/__snapshots__/Text.test.tsx.snap index 38f12106feb..7cf39e4d93d 100644 --- a/packages/components/Text/src/__tests__/__snapshots__/Text.test.tsx.snap +++ b/packages/components/Text/src/__tests__/__snapshots__/Text.test.tsx.snap @@ -6,13 +6,13 @@ exports[`Text component tests Text all props 1`] = ` numberOfLines={0} style={ { - "color": "#323130", - "fontFamily": "Segoe UI", + "color": "#242424", + "fontFamily": "Roboto", "fontSize": 14, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 18, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, @@ -29,13 +29,13 @@ exports[`Text component tests Text all tokens 1`] = ` numberOfLines={0} style={ { - "color": "#323130", + "color": "#242424", "fontFamily": "Wingdings", "fontSize": 20, "fontStyle": undefined, "fontWeight": "900", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, @@ -52,13 +52,13 @@ exports[`Text component tests Text default 1`] = ` numberOfLines={0} style={ { - "color": "#323130", - "fontFamily": "Segoe UI", - "fontSize": 13, + "color": "#242424", + "fontFamily": "Roboto", + "fontSize": 16, "fontStyle": undefined, "fontWeight": "400", - "letterSpacing": undefined, - "lineHeight": undefined, + "letterSpacing": 0, + "lineHeight": 24, "margin": 0, "textAlign": undefined, "textDecorationLine": undefined, @@ -76,9 +76,11 @@ exports[`Text component tests Text variants render correctly with style 1`] = ` style={ { "color": "blue", - "fontFamily": "Segoe UI", + "fontFamily": "Roboto", "fontSize": 60, - "fontWeight": "600", + "fontWeight": "400", + "letterSpacing": -0.5, + "lineHeight": 72, "margin": 0, "marginBottom": 8, "marginTop": 4, diff --git a/packages/shim/theme-tokens/README.md b/packages/shim/theme-tokens/README.md index a955de89ad2..ded9907125b 100644 --- a/packages/shim/theme-tokens/README.md +++ b/packages/shim/theme-tokens/README.md @@ -1,8 +1,10 @@ # Theme-tokens -> **Deprecated:** Import `globalTokens`, `getAliasTokens`, `getShadowTokens`, -> and `hcAliasTokens` from `@fluentui-react-native/design/tokens/legacy` -> instead. +> **Deprecated:** These Fluent 2 token values are deprecated and have no +> replacement API. They remain available from +> `@fluentui-react-native/design/deprecated` for existing platform themes; new +> code should use the generated Fluent themes from +> `@fluentui-react-native/design/themes`. This package is a compatibility shim and will not receive new APIs. It preserves the existing entry point while consumers migrate to the design package. diff --git a/packages/shim/theme-tokens/src/index.ts b/packages/shim/theme-tokens/src/index.ts index e57f4d2183d..9ad9de3046f 100644 --- a/packages/shim/theme-tokens/src/index.ts +++ b/packages/shim/theme-tokens/src/index.ts @@ -1,4 +1,4 @@ // This package is a compatibility shim. Legacy Fluent token values now live in -// the `@fluentui-react-native/design/tokens/legacy` submodule. These explicit +// the `@fluentui-react-native/design/deprecated` submodule. These explicit // re-exports preserve the existing `@fluentui-react-native/theme-tokens` entry point. -export { getAliasTokens, getShadowTokens, globalTokens, hcAliasTokens } from '@fluentui-react-native/design/tokens/legacy'; +export { getAliasTokens, getShadowTokens, globalTokens, hcAliasTokens } from '@fluentui-react-native/design/deprecated'; diff --git a/packages/shim/theming-utils/README.md b/packages/shim/theming-utils/README.md index 82c4b8e8a72..1caadd4192b 100644 --- a/packages/shim/theming-utils/README.md +++ b/packages/shim/theming-utils/README.md @@ -1,7 +1,10 @@ # Theming Utils -> **Deprecated:** Import appearance and token-pipeline helpers from -> `@fluentui-react-native/design/theming` instead. +> **Deprecated:** Import the appearance helpers from +> `@fluentui-react-native/design/theming` instead. The token-pipeline mappers +> (`mapPipelineToTheme`, `mapFontPipelineToTheme`, and `mapPipelineToShadow`) +> are deprecated with no replacement; they remain available from +> `@fluentui-react-native/design/deprecated` for existing platform themes. This package is a compatibility shim and will not receive new APIs. It preserves the existing entry point while consumers migrate to the design package. diff --git a/packages/shim/theming-utils/src/index.ts b/packages/shim/theming-utils/src/index.ts index 077e7f4220c..f77188776cb 100644 --- a/packages/shim/theming-utils/src/index.ts +++ b/packages/shim/theming-utils/src/index.ts @@ -1,11 +1,6 @@ -// This package is a compatibility shim. Theme appearance and token-pipeline -// utilities now live in the `@fluentui-react-native/design/theming` submodule. +// This package is a compatibility shim. Theme appearance utilities now live in +// the `@fluentui-react-native/design/theming` submodule, and the deprecated +// token-pipeline mappers live in `@fluentui-react-native/design/deprecated`. // These explicit re-exports preserve the existing package entry point. -export { - getCurrentAppearance, - isHighContrast, - mapFontPipelineToTheme, - mapPipelineToShadow, - mapPipelineToTheme, - setIsHighContrast, -} from '@fluentui-react-native/design/theming'; +export { getCurrentAppearance, isHighContrast, setIsHighContrast } from '@fluentui-react-native/design/theming'; +export { mapFontPipelineToTheme, mapPipelineToShadow, mapPipelineToTheme } from '@fluentui-react-native/design/deprecated'; diff --git a/packages/theming/android-theme/src/createAliasTokens.ts b/packages/theming/android-theme/src/createAliasTokens.ts index f6e55a87bcb..2eab70edbcf 100644 --- a/packages/theming/android-theme/src/createAliasTokens.ts +++ b/packages/theming/android-theme/src/createAliasTokens.ts @@ -1,7 +1,6 @@ import { memoize } from '@fluentui-react-native/framework-base'; -import { getAliasTokens, getShadowTokens } from '@fluentui-react-native/design/tokens/legacy'; +import { getAliasTokens, getShadowTokens, mapPipelineToShadow, mapPipelineToTheme } from '@fluentui-react-native/design/deprecated'; import type { AliasColorTokens, AppearanceOptions, ThemeShadowDefinition } from '@fluentui-react-native/design/theming'; -import { mapPipelineToShadow, mapPipelineToTheme } from '@fluentui-react-native/design/theming'; function createColorAliasTokensWorker(mode: AppearanceOptions): AliasColorTokens { const aliasTokens = getAliasTokens(mode); diff --git a/packages/theming/android-theme/src/createFontAliasTokens.ts b/packages/theming/android-theme/src/createFontAliasTokens.ts index 6f5494f58c1..563ba58aa34 100644 --- a/packages/theming/android-theme/src/createFontAliasTokens.ts +++ b/packages/theming/android-theme/src/createFontAliasTokens.ts @@ -1,7 +1,6 @@ import { memoize } from '@fluentui-react-native/framework-base'; -import { getAliasTokens } from '@fluentui-react-native/design/tokens/legacy'; +import { getAliasTokens, mapFontPipelineToTheme } from '@fluentui-react-native/design/deprecated'; import type { Variants } from '@fluentui-react-native/design/theming'; -import { mapFontPipelineToTheme } from '@fluentui-react-native/design/theming'; function createFontAliasTokensWorker(): Partial<Variants> { const aliasTokens = getAliasTokens('light'); diff --git a/packages/theming/apple-theme/src/createFontAliasTokens.ios.ts b/packages/theming/apple-theme/src/createFontAliasTokens.ios.ts index cacfcbf6238..d1b8b18f77f 100644 --- a/packages/theming/apple-theme/src/createFontAliasTokens.ios.ts +++ b/packages/theming/apple-theme/src/createFontAliasTokens.ios.ts @@ -1,7 +1,7 @@ import aliasTokens from '@fluentui-react-native/design-tokens-ios/light/tokens-aliases.json'; // Font alias tokens should be the same for all color styles import { memoize } from '@fluentui-react-native/framework-base'; +import { mapFontPipelineToTheme } from '@fluentui-react-native/design/deprecated'; import type { Variants } from '@fluentui-react-native/design/theming'; -import { mapFontPipelineToTheme } from '@fluentui-react-native/design/theming'; function createFontAliasTokensWorker(): Partial<Variants> { return mapFontPipelineToTheme(aliasTokens); diff --git a/packages/theming/apple-theme/src/createMacOSAliasTokens.ts b/packages/theming/apple-theme/src/createMacOSAliasTokens.ts index d2cc77eb70f..75ede44e805 100644 --- a/packages/theming/apple-theme/src/createMacOSAliasTokens.ts +++ b/packages/theming/apple-theme/src/createMacOSAliasTokens.ts @@ -1,7 +1,7 @@ import { memoize } from '@fluentui-react-native/framework-base'; +import { mapPipelineToTheme, mapPipelineToShadow } from '@fluentui-react-native/design/deprecated'; import type { AliasColorTokens, AppearanceOptions } from '@fluentui-react-native/design/theming'; import type { ThemeShadowDefinition } from '@fluentui-react-native/design/theming'; -import { mapPipelineToTheme, mapPipelineToShadow } from '@fluentui-react-native/design/theming'; import { getMacOSAliasTokens, getMacOSShadowTokens } from './getMacOSTokens'; diff --git a/packages/theming/apple-theme/src/createiOSAliasTokens.ts b/packages/theming/apple-theme/src/createiOSAliasTokens.ts index 5f425502916..7a9fb438e0b 100644 --- a/packages/theming/apple-theme/src/createiOSAliasTokens.ts +++ b/packages/theming/apple-theme/src/createiOSAliasTokens.ts @@ -1,8 +1,7 @@ import { memoize } from '@fluentui-react-native/framework-base'; -import { getAliasTokens, getShadowTokens } from '@fluentui-react-native/design/tokens/legacy'; +import { getAliasTokens, getShadowTokens, mapPipelineToTheme, mapPipelineToShadow } from '@fluentui-react-native/design/deprecated'; import type { AliasColorTokens, AppearanceOptions } from '@fluentui-react-native/design/theming'; import type { ThemeShadowDefinition } from '@fluentui-react-native/design/theming'; -import { mapPipelineToTheme, mapPipelineToShadow } from '@fluentui-react-native/design/theming'; function createiOSColorAliasTokensWorker(mode: AppearanceOptions): AliasColorTokens { const aliasTokens = getAliasTokens(mode); diff --git a/packages/theming/default-theme/README.md b/packages/theming/default-theme/README.md index 41804f4aa60..a35dea37984 100644 --- a/packages/theming/default-theme/README.md +++ b/packages/theming/default-theme/README.md @@ -1,3 +1,6 @@ # default-theme -A pure base theme for the fluentui-react-native components, defined purely in JavaScript +The Fluent default themes for the fluentui-react-native components. `defaultFluentTheme` and `defaultFluentDarkTheme` +are the `@fluentui-react-native/design` package's `fluentLightTheme` and `fluentDarkTheme`, and `createDefaultTheme` +returns a `ThemeReference` that resolves the design package's `fluentTheme`, including its high-contrast themes, for the +requested appearance. diff --git a/packages/theming/default-theme/package.json b/packages/theming/default-theme/package.json index 2119ac15dde..2168dd7f2db 100644 --- a/packages/theming/default-theme/package.json +++ b/packages/theming/default-theme/package.json @@ -33,9 +33,7 @@ "update-snapshots": "fluentui-scripts jest -u" }, "dependencies": { - "@fluentui-react-native/design": "workspace:*", - "@fluentui-react-native/framework-base": "workspace:*", - "assert-never": "^1.2.1" + "@fluentui-react-native/design": "workspace:*" }, "devDependencies": { "@babel/core": "catalog:", diff --git a/packages/theming/default-theme/src/__tests__/__snapshots__/default-theme.test.ts.snap b/packages/theming/default-theme/src/__tests__/__snapshots__/default-theme.test.ts.snap index 95cfed8eb36..7fee9b0eafd 100644 --- a/packages/theming/default-theme/src/__tests__/__snapshots__/default-theme.test.ts.snap +++ b/packages/theming/default-theme/src/__tests__/__snapshots__/default-theme.test.ts.snap @@ -1,1105 +1,79 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`createColorAliasTokens test appearanceOptions - dark 1`] = ` -{ - "brandBackground": "#1651aa", - "brandBackground2": "#004578", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#185abd", - "brandBackgroundPressed": "#004578", - "brandBackgroundSelected": "#13458f", - "brandBackgroundStatic": "#185abd", - "brandForeground1": "#6794d7", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#aec6eb", - "brandForegroundLink": "#2e6ac5", - "brandForegroundLinkHover": "#aec6eb", - "brandForegroundLinkPressed": "#6794d7", - "brandForegroundLinkSelected": "#2e6ac5", - "brandStroke1": "#2e6ac5", - "brandStroke2": "#0e336a", - "compoundBrandBackground1": "#2e6ac5", - "compoundBrandBackground1Hover": "#6794d7", - "compoundBrandBackground1Pressed": "#185abd", - "compoundBrandForeground1": "#2e6ac5", - "compoundBrandForeground1Hover": "#6794d7", - "compoundBrandForeground1Pressed": "#185abd", - "compoundBrandStroke1": "#2e6ac5", - "compoundBrandStroke1Hover": "#6794d7", - "compoundBrandStroke1Pressed": "#185abd", - "dangerBackground1": "#3f1011", - "dangerBackground2": "#751d1f", - "dangerBackground3": "#d13438", - "dangerBorder1": "#d13438", - "dangerBorder2": "#dc5e62", - "dangerBorderActive": "#e37d80", - "dangerForeground1": "#e37d80", - "dangerForeground2": "#f1bbbc", - "dangerForeground3": "#e37d80", - "dangerForegroundInverted": "#d13438", - "neutralBackground1": "#292929", - "neutralBackground1Hover": "#3d3d3d", - "neutralBackground1Pressed": "#1f1f1f", - "neutralBackground1Selected": "#383838", - "neutralBackground2": "#1f1f1f", - "neutralBackground2Hover": "#333333", - "neutralBackground2Pressed": "#141414", - "neutralBackground2Selected": "#2e2e2e", - "neutralBackground3": "#141414", - "neutralBackground3Hover": "#292929", - "neutralBackground3Pressed": "#0a0a0a", - "neutralBackground3Selected": "#242424", - "neutralBackground4": "#0a0a0a", - "neutralBackground4Hover": "#1f1f1f", - "neutralBackground4Pressed": "#000000", - "neutralBackground4Selected": "#1a1a1a", - "neutralBackground5": "#000000", - "neutralBackground5Hover": "#141414", - "neutralBackground5Pressed": "#050505", - "neutralBackground5Selected": "#0f0f0f", - "neutralBackground6": "#333333", - "neutralBackgroundDisabled": "#141414", - "neutralBackgroundInverted": "#ffffff", - "neutralForeground1": "#ffffff", - "neutralForeground1Hover": "#ffffff", - "neutralForeground1Pressed": "#ffffff", - "neutralForeground1Selected": "#ffffff", - "neutralForeground2": "#d6d6d6", - "neutralForeground2BrandHover": "#6794d7", - "neutralForeground2BrandPressed": "#2e6ac5", - "neutralForeground2BrandSelected": "#6794d7", - "neutralForeground2Hover": "#ffffff", - "neutralForeground2Pressed": "#ffffff", - "neutralForeground2Selected": "#ffffff", - "neutralForeground3": "#adadad", - "neutralForeground3BrandHover": "#6794d7", - "neutralForeground3BrandPressed": "#2e6ac5", - "neutralForeground3BrandSelected": "#6794d7", - "neutralForeground3Hover": "#d6d6d6", - "neutralForeground3Pressed": "#d6d6d6", - "neutralForeground3Selected": "#d6d6d6", - "neutralForeground4": "#999999", - "neutralForegroundDisabled": "#5c5c5c", - "neutralForegroundInverted": "#242424", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", - "neutralForegroundOnBrand": "#ffffff", - "neutralForegroundOnBrandHover": "#ffffff", - "neutralForegroundOnBrandPressed": "#ffffff", - "neutralForegroundOnBrandSelected": "#ffffff", - "neutralStencil1": "#333333", - "neutralStencil2": "#575757", - "neutralStroke1": "#666666", - "neutralStroke1Hover": "#757575", - "neutralStroke1Pressed": "#6b6b6b", - "neutralStroke1Selected": "#707070", - "neutralStroke2": "#525252", - "neutralStroke3": "#3d3d3d", - "neutralStrokeAccessible": "#adadad", - "neutralStrokeAccessibleHover": "#bdbdbd", - "neutralStrokeAccessiblePressed": "#b3b3b3", - "neutralStrokeAccessibleSelected": "#6794d7", - "neutralStrokeDisabled": "#424242", - "outofofficeBackground1": "#3a1136", - "outofofficeBackground2": "#6d2064", - "outofofficeBackground3": "#c239b3", - "outofofficeBorder1": "#c239b3", - "outofofficeBorder2": "#d161c4", - "outofofficeBorderActive": "#da7ed0", - "outofofficeForeground1": "#da7ed0", - "outofofficeForeground2": "#edbbe7", - "outofofficeForeground3": "#d161c4", - "severeBackground1": "#411200", - "severeBackground2": "#7a2101", - "severeBackground3": "#da3b01", - "severeBorder1": "#da3b01", - "severeBorder2": "#e9835e", - "severeBorderActive": "#e9835e", - "severeForeground1": "#e9835e", - "severeForeground2": "#f4bfab", - "severeForeground3": "#e9835e", - "strokeFocus1": "#000000", - "strokeFocus2": "#ffffff", - "subtleBackground": "#00000000", - "subtleBackgroundHover": "#383838", - "subtleBackgroundPressed": "#2e2e2e", - "subtleBackgroundSelected": "#333333", - "successBackground1": "#052505", - "successBackground2": "#094509", - "successBackground3": "#107c10", - "successBorder1": "#107c10", - "successBorder2": "#9fd89f", - "successBorderActive": "#54b054", - "successForeground1": "#54b054", - "successForeground2": "#9fd89f", - "successForeground3": "#9fd89f", - "successForegroundInverted": "#107c10", - "transparentBackground": "#00000000", - "transparentBackgroundHover": "#00000000", - "transparentBackgroundPressed": "#00000000", - "transparentBackgroundSelected": "#00000000", - "transparentStroke": "#00000000", - "transparentStrokeDisabled": "#00000000", - "transparentStrokeInteractive": "#00000000", - "warningBackground1": "#4c4400", - "warningBackground2": "#817400", - "warningBackground3": "#fde300", - "warningBorder1": "#fde300", - "warningBorder2": "#fdea3d", - "warningBorderActive": "#feee66", - "warningForeground1": "#feee66", - "warningForeground2": "#fef7b2", - "warningForeground3": "#fdea3d", - "warningForegroundInverted": "#817400", -} -`; - -exports[`createColorAliasTokens test appearanceOptions - highContrast 1`] = ` -{ - "brandBackground": { - "resource_paths": [ - "ButtonFace", - ], - }, - "brandBackground2": { - "resource_paths": [ - "ButtonFace", - ], - }, - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": { - "resource_paths": [ - "Highlight", - ], - }, - "brandBackgroundPressed": { - "resource_paths": [ - "Highlight", - ], - }, - "brandBackgroundSelected": { - "resource_paths": [ - "Highlight", - ], - }, - "brandBackgroundStatic": { - "resource_paths": [ - "Window", - ], - }, - "brandForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": { - "resource_paths": [ - "ButtonText", - ], - }, - "brandForegroundLink": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandForegroundLinkHover": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandForegroundLinkPressed": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandForegroundLinkSelected": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandStroke1": { - "resource_paths": [ - "WindowText", - ], - }, - "brandStroke2": { - "resource_paths": [ - "Window", - ], - }, - "compoundBrandBackground1": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandBackground1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandBackground1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandForeground1": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandForeground1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandForeground1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandStroke1": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandStroke1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandStroke1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "dangerBackground1": { - "resource_paths": [ - "Window", - ], - }, - "dangerBackground2": { - "resource_paths": [ - "Window", - ], - }, - "dangerBackground3": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerBorder1": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerBorder2": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerBorderActive": { - "resource_paths": [ - "Highlight", - ], - }, - "dangerForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerForeground2": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerForeground3": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerForegroundInverted": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralBackground1": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackground1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground1Selected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground2": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackground2Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground2Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground2Selected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground3": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackground3Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground3Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground3Selected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground4": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackground4Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground4Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground4Selected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground5": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackground5Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground5Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground5Selected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground6": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackgroundDisabled": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackgroundInverted": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralForeground1Hover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground1Pressed": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground1Selected": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground2": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralForeground2BrandHover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground2BrandPressed": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground2BrandSelected": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground2Hover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground2Pressed": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground2Selected": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralForeground3BrandHover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3BrandPressed": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3BrandSelected": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3Hover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3Pressed": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3Selected": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground4": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralForegroundDisabled": { - "resource_paths": [ - "GrayText", - ], - }, - "neutralForegroundInverted": { - "resource_paths": [ - "Window", - ], - }, - "neutralForegroundInvertedLink": { - "resource_paths": [ - "Hotlight", - ], - }, - "neutralForegroundInvertedLinkHover": { - "resource_paths": [ - "Hotlight", - ], - }, - "neutralForegroundInvertedLinkPressed": { - "resource_paths": [ - "Hotlight", - ], - }, - "neutralForegroundInvertedLinkSelected": { - "resource_paths": [ - "Hotlight", - ], - }, - "neutralForegroundOnBrand": { - "resource_paths": [ - "ButtonText", - ], - }, - "neutralForegroundOnBrandHover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForegroundOnBrandPressed": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForegroundOnBrandSelected": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralStencil1": "#141414", - "neutralStencil2": "#858585", - "neutralStroke1": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralStroke1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralStroke1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralStroke1Selected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralStroke2": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralStroke3": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralStrokeAccessible": { - "resource_paths": [ - "WindowText", - ], - }, - "neutralStrokeAccessibleHover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralStrokeAccessiblePressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralStrokeAccessibleSelected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralStrokeDisabled": { - "resource_paths": [ - "GrayText", - ], - }, - "outofofficeBackground1": { - "resource_paths": [ - "Window", - ], - }, - "outofofficeBackground2": { - "resource_paths": [ - "Window", - ], - }, - "outofofficeBackground3": { - "resource_paths": [ - "WindowText", - ], - }, - "outofofficeBorder1": { - "resource_paths": [ - "WindowText", - ], - }, - "outofofficeBorder2": { - "resource_paths": [ - "WindowText", - ], - }, - "outofofficeBorderActive": { - "resource_paths": [ - "Highlight", - ], - }, - "outofofficeForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "outofofficeForeground2": { - "resource_paths": [ - "WindowText", - ], - }, - "outofofficeForeground3": { - "resource_paths": [ - "WindowText", - ], - }, - "severeBackground1": { - "resource_paths": [ - "Window", - ], - }, - "severeBackground2": { - "resource_paths": [ - "Window", - ], - }, - "severeBackground3": { - "resource_paths": [ - "WindowText", - ], - }, - "severeBorder1": { - "resource_paths": [ - "WindowText", - ], - }, - "severeBorder2": { - "resource_paths": [ - "WindowText", - ], - }, - "severeBorderActive": { - "resource_paths": [ - "Highlight", - ], - }, - "severeForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "severeForeground2": { - "resource_paths": [ - "WindowText", - ], - }, - "severeForeground3": { - "resource_paths": [ - "WindowText", - ], - }, - "strokeFocus1": { - "resource_paths": [ - "Window", - ], - }, - "strokeFocus2": { - "resource_paths": [ - "Highlight", - ], - }, - "subtleBackground": "#00000000", - "subtleBackgroundHover": { - "resource_paths": [ - "Highlight", - ], - }, - "subtleBackgroundPressed": { - "resource_paths": [ - "Highlight", - ], - }, - "subtleBackgroundSelected": { - "resource_paths": [ - "Highlight", - ], - }, - "successBackground1": { - "resource_paths": [ - "Window", - ], - }, - "successBackground2": { - "resource_paths": [ - "Window", - ], - }, - "successBackground3": { - "resource_paths": [ - "WindowText", - ], - }, - "successBorder1": { - "resource_paths": [ - "WindowText", - ], - }, - "successBorder2": { - "resource_paths": [ - "WindowText", - ], - }, - "successBorderActive": { - "resource_paths": [ - "Highlight", - ], - }, - "successForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "successForeground2": { - "resource_paths": [ - "WindowText", - ], - }, - "successForeground3": { - "resource_paths": [ - "WindowText", - ], - }, - "successForegroundInverted": { - "resource_paths": [ - "WindowText", - ], - }, - "transparentBackground": "#00000000", - "transparentBackgroundHover": "#00000000", - "transparentBackgroundPressed": "#00000000", - "transparentBackgroundSelected": "#00000000", - "transparentStroke": { - "resource_paths": [ - "WindowText", - ], - }, - "transparentStrokeDisabled": { - "resource_paths": [ - "GrayText", - ], - }, - "transparentStrokeInteractive": { - "resource_paths": [ - "Highlight", - ], - }, - "warningBackground1": { - "resource_paths": [ - "Window", - ], - }, - "warningBackground2": { - "resource_paths": [ - "Window", - ], - }, - "warningBackground3": { - "resource_paths": [ - "WindowText", - ], - }, - "warningBorder1": { - "resource_paths": [ - "WindowText", - ], - }, - "warningBorder2": { - "resource_paths": [ - "WindowText", - ], - }, - "warningBorderActive": { - "resource_paths": [ - "Highlight", - ], - }, - "warningForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "warningForeground2": { - "resource_paths": [ - "WindowText", - ], - }, - "warningForeground3": { - "resource_paths": [ - "WindowText", - ], - }, - "warningForegroundInverted": { - "resource_paths": [ - "WindowText", - ], - }, -} -`; - -exports[`createColorAliasTokens test appearanceOptions - light 1`] = ` -{ - "brandBackground": "#185abd", - "brandBackground2": "#eff6fc", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#1651aa", - "brandBackgroundPressed": "#004578", - "brandBackgroundSelected": "#13458f", - "brandBackgroundStatic": "#185abd", - "brandForeground1": "#185abd", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#1651aa", - "brandForegroundLink": "#1651aa", - "brandForegroundLinkHover": "#13458f", - "brandForegroundLinkPressed": "#004578", - "brandForegroundLinkSelected": "#1651aa", - "brandStroke1": "#185abd", - "brandStroke2": "#d2e0f4", - "compoundBrandBackground1": "#185abd", - "compoundBrandBackground1Hover": "#1651aa", - "compoundBrandBackground1Pressed": "#13458f", - "compoundBrandForeground1": "#185abd", - "compoundBrandForeground1Hover": "#1651aa", - "compoundBrandForeground1Pressed": "#13458f", - "compoundBrandStroke1": "#185abd", - "compoundBrandStroke1Hover": "#1651aa", - "compoundBrandStroke1Pressed": "#13458f", - "dangerBackground1": "#fdf6f6", - "dangerBackground2": "#f1bbbc", - "dangerBackground3": "#d13438", - "dangerBorder1": "#f1bbbc", - "dangerBorder2": "#d13438", - "dangerBorderActive": "#d13438", - "dangerForeground1": "#bc2f32", - "dangerForeground2": "#751d1f", - "dangerForeground3": "#d13438", - "dangerForegroundInverted": "#dc5e62", - "neutralBackground1": "#ffffff", - "neutralBackground1Hover": "#f5f5f5", - "neutralBackground1Pressed": "#e0e0e0", - "neutralBackground1Selected": "#ebebeb", - "neutralBackground2": "#fafafa", - "neutralBackground2Hover": "#f0f0f0", - "neutralBackground2Pressed": "#dbdbdb", - "neutralBackground2Selected": "#e6e6e6", - "neutralBackground3": "#f5f5f5", - "neutralBackground3Hover": "#ebebeb", - "neutralBackground3Pressed": "#d6d6d6", - "neutralBackground3Selected": "#e0e0e0", - "neutralBackground4": "#f0f0f0", - "neutralBackground4Hover": "#fafafa", - "neutralBackground4Pressed": "#f5f5f5", - "neutralBackground4Selected": "#ffffff", - "neutralBackground5": "#ebebeb", - "neutralBackground5Hover": "#f5f5f5", - "neutralBackground5Pressed": "#f0f0f0", - "neutralBackground5Selected": "#fafafa", - "neutralBackground6": "#e6e6e6", - "neutralBackgroundDisabled": "#f0f0f0", - "neutralBackgroundInverted": "#616161", - "neutralForeground1": "#242424", - "neutralForeground1Hover": "#242424", - "neutralForeground1Pressed": "#242424", - "neutralForeground1Selected": "#242424", - "neutralForeground2": "#424242", - "neutralForeground2BrandHover": "#185abd", - "neutralForeground2BrandPressed": "#1651aa", - "neutralForeground2BrandSelected": "#185abd", - "neutralForeground2Hover": "#242424", - "neutralForeground2Pressed": "#242424", - "neutralForeground2Selected": "#242424", - "neutralForeground3": "#616161", - "neutralForeground3BrandHover": "#185abd", - "neutralForeground3BrandPressed": "#1651aa", - "neutralForeground3BrandSelected": "#185abd", - "neutralForeground3Hover": "#424242", - "neutralForeground3Pressed": "#424242", - "neutralForeground3Selected": "#424242", - "neutralForeground4": "#707070", - "neutralForegroundDisabled": "#bdbdbd", - "neutralForegroundInverted": "#ffffff", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", - "neutralForegroundOnBrand": "#ffffff", - "neutralForegroundOnBrandHover": "#ffffff", - "neutralForegroundOnBrandPressed": "#ffffff", - "neutralForegroundOnBrandSelected": "#ffffff", - "neutralStencil1": "#e6e6e6", - "neutralStencil2": "#fafafa", - "neutralStroke1": "#d1d1d1", - "neutralStroke1Hover": "#c7c7c7", - "neutralStroke1Pressed": "#b3b3b3", - "neutralStroke1Selected": "#bdbdbd", - "neutralStroke2": "#e0e0e0", - "neutralStroke3": "#f0f0f0", - "neutralStrokeAccessible": "#616161", - "neutralStrokeAccessibleHover": "#575757", - "neutralStrokeAccessiblePressed": "#4d4d4d", - "neutralStrokeAccessibleSelected": "#185abd", - "neutralStrokeDisabled": "#e0e0e0", - "outofofficeBackground1": "#fdf5fc", - "outofofficeBackground2": "#edbbe7", - "outofofficeBackground3": "#c239b3", - "outofofficeBorder1": "#edbbe7", - "outofofficeBorder2": "#c239b3", - "outofofficeBorderActive": "#c239b3", - "outofofficeForeground1": "#af33a1", - "outofofficeForeground2": "#6d2064", - "outofofficeForeground3": "#c239b3", - "severeBackground1": "#fdf6f3", - "severeBackground2": "#f4bfab", - "severeBackground3": "#da3b01", - "severeBorder1": "#f4bfab", - "severeBorder2": "#da3b01", - "severeBorderActive": "#da3b01", - "severeForeground1": "#c43501", - "severeForeground2": "#7a2101", - "severeForeground3": "#da3b01", - "strokeFocus1": "#ffffff", - "strokeFocus2": "#000000", - "subtleBackground": "#00000000", - "subtleBackgroundHover": "#f5f5f5", - "subtleBackgroundPressed": "#e0e0e0", - "subtleBackgroundSelected": "#ebebeb", - "successBackground1": "#f1faf1", - "successBackground2": "#9fd89f", - "successBackground3": "#107c10", - "successBorder1": "#9fd89f", - "successBorder2": "#107c10", - "successBorderActive": "#107c10", - "successForeground1": "#0e700e", - "successForeground2": "#094509", - "successForeground3": "#107c10", - "successForegroundInverted": "#359b35", - "transparentBackground": "#00000000", - "transparentBackgroundHover": "#00000000", - "transparentBackgroundPressed": "#00000000", - "transparentBackgroundSelected": "#00000000", - "transparentStroke": "#00000000", - "transparentStrokeDisabled": "#00000000", - "transparentStrokeInteractive": "#00000000", - "warningBackground1": "#fffef5", - "warningBackground2": "#fef7b2", - "warningBackground3": "#fde300", - "warningBorder1": "#fef7b2", - "warningBorder2": "#fde300", - "warningBorderActive": "#fde300", - "warningForeground1": "#817400", - "warningForeground2": "#817400", - "warningForeground3": "#fde300", - "warningForegroundInverted": "#fef7b2", -} -`; - exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppearance: 'light' } 1`] = ` { "colors": { "accentButtonBackground": "#185abd", - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "actionLink": "#ffffff", + "background": "#292929", + "bodyDivider": "#525252", + "bodyFrameBackground": "#292929", + "bodyFrameDivider": "#525252", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", - "brandBackground": "#1651aa", - "brandBackground2": "#004578", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#185abd", - "brandBackgroundPressed": "#004578", + "brandBackground": "#185abd", + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#141414", + "brandBackgroundHover": "#1651aa", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#141414", + "brandBackgroundPressed": "#0e336a", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", - "brandForeground1": "#6794d7", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#aec6eb", - "brandForegroundLink": "#2e6ac5", - "brandForegroundLinkHover": "#aec6eb", - "brandForegroundLinkPressed": "#6794d7", - "brandForegroundLinkSelected": "#2e6ac5", - "brandStroke1": "#2e6ac5", - "brandStroke2": "#0e336a", - "brandedBackground": "#2e6ac5", - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandBackgroundTint": "#d2e0f4", + "brandForeground1": "#aec6eb", + "brandForeground1Disabled": "#5c5c5c", + "brandForeground1Pressed": "#aec6eb", + "brandForeground1Selected": "#aec6eb", + "brandForeground2": "#d2e0f4", + "brandForegroundDisabled1": "#5c5c5c", + "brandForegroundDisabled2": "#5c5c5c", + "brandForegroundLink": "#aec6eb", + "brandForegroundLinkHover": "#d2e0f4", + "brandForegroundLinkPressed": "#2e6ac5", + "brandForegroundLinkSelected": "#d2e0f4", + "brandForegroundTint": "#d2e0f4", + "brandStroke1": "#185abd", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", + "brandedBackground": "#185abd", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#292929", + "buttonBackgroundChecked": "#383838", + "buttonBackgroundDisabled": "#141414", + "buttonBackgroundHovered": "#3d3d3d", + "buttonBackgroundPressed": "#1f1f1f", + "buttonBorder": "#666666", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": "#2e6ac5", - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", - "compoundBrandBackground1": "#2e6ac5", - "compoundBrandBackground1Hover": "#6794d7", - "compoundBrandBackground1Pressed": "#185abd", - "compoundBrandForeground1": "#2e6ac5", - "compoundBrandForeground1Hover": "#6794d7", - "compoundBrandForeground1Pressed": "#185abd", - "compoundBrandStroke1": "#2e6ac5", - "compoundBrandStroke1Hover": "#6794d7", - "compoundBrandStroke1Pressed": "#185abd", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#185abd", + "checkboxBackgroundDisabled": "#141414", + "checkboxBorderColor": "#adadad", + "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#185abd", + "compoundBrandBackground1Hover": "#1651aa", + "compoundBrandBackground1Pressed": "#0e336a", + "compoundBrandForeground1": "#aec6eb", + "compoundBrandForeground1Hover": "#d2e0f4", + "compoundBrandForeground1Pressed": "#2e6ac5", + "compoundBrandStroke1": "#185abd", + "compoundBrandStroke1Hover": "#1651aa", + "compoundBrandStroke1Pressed": "#0e336a", "dangerBackground1": "#3f1011", "dangerBackground2": "#751d1f", "dangerBackground3": "#d13438", @@ -1110,83 +84,84 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "dangerForeground2": "#f1bbbc", "dangerForeground3": "#e37d80", "dangerForegroundInverted": "#d13438", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "dangerStroke1": "#d13438", + "defaultBackground": "#292929", + "defaultBorder": "#666666", + "defaultCheckedBackground": "#383838", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#3d3d3d", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#141414", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#3d3d3d", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#3d3d3d", + "defaultHoveredBorder": "#757575", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#d6d6d6", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", + "defaultPressedBackground": "#1f1f1f", + "defaultPressedBorder": "#6b6b6b", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#d6d6d6", + "disabledBackground": "#141414", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": "#2e6ac5", - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": "#2e6ac5", - "linkHovered": "#82c7ff", - "linkPressed": "#aec6eb", - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": "#6794d7", - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#ffffff", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#d6d6d6", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#d6d6d6", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#292929", + "inputBorder": "#666666", + "inputFocusBorderAlt": "#185abd", + "inputPlaceholderText": "#999999", + "inputText": "#ffffff", + "link": "#aec6eb", + "linkHovered": "#d2e0f4", + "linkPressed": "#2e6ac5", + "listHeaderBackgroundHovered": "#3d3d3d", + "listHeaderBackgroundPressed": "#1f1f1f", + "menuBackground": "#292929", + "menuDivider": "#525252", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#3d3d3d", + "menuItemBackgroundPressed": "#1f1f1f", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", "neutralBackground1": "#292929", "neutralBackground1Hover": "#3d3d3d", "neutralBackground1Pressed": "#1f1f1f", @@ -1208,37 +183,46 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "neutralBackground5Pressed": "#050505", "neutralBackground5Selected": "#0f0f0f", "neutralBackground6": "#333333", + "neutralBackgroundCanvas": "#292929", + "neutralBackgroundDarkStatic": "#3d3d3d", "neutralBackgroundDisabled": "#141414", "neutralBackgroundInverted": "#ffffff", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#141414", "neutralForeground1": "#ffffff", "neutralForeground1Hover": "#ffffff", "neutralForeground1Pressed": "#ffffff", "neutralForeground1Selected": "#ffffff", "neutralForeground2": "#d6d6d6", - "neutralForeground2BrandHover": "#6794d7", + "neutralForeground2BrandHover": "#d2e0f4", "neutralForeground2BrandPressed": "#2e6ac5", - "neutralForeground2BrandSelected": "#6794d7", + "neutralForeground2BrandSelected": "#d2e0f4", "neutralForeground2Hover": "#ffffff", "neutralForeground2Pressed": "#ffffff", "neutralForeground2Selected": "#ffffff", "neutralForeground3": "#adadad", - "neutralForeground3BrandHover": "#6794d7", + "neutralForeground3BrandHover": "#d2e0f4", "neutralForeground3BrandPressed": "#2e6ac5", - "neutralForeground3BrandSelected": "#6794d7", + "neutralForeground3BrandSelected": "#d2e0f4", "neutralForeground3Hover": "#d6d6d6", "neutralForeground3Pressed": "#d6d6d6", "neutralForeground3Selected": "#d6d6d6", "neutralForeground4": "#999999", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#5c5c5c", - "neutralForegroundInverted": "#242424", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundDisabled1": "#5c5c5c", + "neutralForegroundDisabled2": "#5c5c5c", + "neutralForegroundInverted": "#000000", + "neutralForegroundInvertedLink": "#292929", + "neutralForegroundInvertedLinkHover": "#292929", + "neutralForegroundInvertedLinkPressed": "#292929", + "neutralForegroundInvertedLinkSelected": "#292929", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#333333", "neutralStencil2": "#575757", "neutralStroke1": "#666666", @@ -1250,8 +234,10 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "neutralStrokeAccessible": "#adadad", "neutralStrokeAccessibleHover": "#bdbdbd", "neutralStrokeAccessiblePressed": "#b3b3b3", - "neutralStrokeAccessibleSelected": "#6794d7", + "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#424242", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", "outofofficeBackground1": "#3a1136", "outofofficeBackground2": "#6d2064", "outofofficeBackground3": "#c239b3", @@ -1261,18 +247,31 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "outofofficeForeground1": "#da7ed0", "outofofficeForeground2": "#edbbe7", "outofofficeForeground3": "#d161c4", - "personaActivityGlow": "#2e6ac5", - "personaActivityRing": "#1b1a19", - "primaryButtonBackground": "#2e6ac5", - "primaryButtonBackgroundDisabled": "#252423", - "primaryButtonBackgroundHovered": "#6794d7", - "primaryButtonBackgroundPressed": "#aec6eb", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "personaActivityGlow": "#185abd", + "personaActivityRing": "#292929", + "presenceAvailable": "#54b054", + "presenceAway": "#feee66", + "presenceDnd": "#e37d80", + "presenceOof": "#da7ed0", + "primaryButtonBackground": "#185abd", + "primaryButtonBackgroundDisabled": "#141414", + "primaryButtonBackgroundHovered": "#1651aa", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#751d1f", + "redBackground3": "#d13438", + "redBorder1": "#d13438", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#f1bbbc", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#7a2101", "severeBackground3": "#da3b01", @@ -1282,13 +281,14 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "severeForeground1": "#e9835e", "severeForeground2": "#f4bfab", "severeForeground3": "#e9835e", + "severeStroke1": "#da3b01", "strokeFocus1": "#000000", "strokeFocus2": "#ffffff", - "subText": "#a19f9d", + "subText": "#d6d6d6", "subtleBackground": "#00000000", - "subtleBackgroundHover": "#383838", - "subtleBackgroundPressed": "#2e2e2e", - "subtleBackgroundSelected": "#333333", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", "successBackground1": "#052505", "successBackground2": "#094509", "successBackground3": "#107c10", @@ -1299,6 +299,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "successForeground2": "#9fd89f", "successForeground3": "#9fd89f", "successForegroundInverted": "#107c10", + "successStroke1": "#107c10", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -1306,7 +307,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#292827", + "variantBorder": "#525252", "warningBackground1": "#4c4400", "warningBackground2": "#817400", "warningBackground3": "#fde300", @@ -1317,6 +318,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "warningForeground2": "#fef7b2", "warningForeground3": "#fdea3d", "warningForegroundInverted": "#817400", + "warningStroke1": "#fde300", }, "components": {}, "host": { @@ -1501,13 +503,13 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -1521,138 +523,153 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dark', defaultAppe "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -1667,63 +684,76 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA { "colors": { "accentButtonBackground": "#185abd", - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "actionLink": "#ffffff", + "background": "#292929", + "bodyDivider": "#525252", + "bodyFrameBackground": "#292929", + "bodyFrameDivider": "#525252", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", - "brandBackground": "#1651aa", - "brandBackground2": "#004578", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#185abd", - "brandBackgroundPressed": "#004578", + "brandBackground": "#185abd", + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#141414", + "brandBackgroundHover": "#1651aa", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#141414", + "brandBackgroundPressed": "#0e336a", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", - "brandForeground1": "#6794d7", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#aec6eb", - "brandForegroundLink": "#2e6ac5", - "brandForegroundLinkHover": "#aec6eb", - "brandForegroundLinkPressed": "#6794d7", - "brandForegroundLinkSelected": "#2e6ac5", - "brandStroke1": "#2e6ac5", - "brandStroke2": "#0e336a", - "brandedBackground": "#2e6ac5", - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandBackgroundTint": "#d2e0f4", + "brandForeground1": "#aec6eb", + "brandForeground1Disabled": "#5c5c5c", + "brandForeground1Pressed": "#aec6eb", + "brandForeground1Selected": "#aec6eb", + "brandForeground2": "#d2e0f4", + "brandForegroundDisabled1": "#5c5c5c", + "brandForegroundDisabled2": "#5c5c5c", + "brandForegroundLink": "#aec6eb", + "brandForegroundLinkHover": "#d2e0f4", + "brandForegroundLinkPressed": "#2e6ac5", + "brandForegroundLinkSelected": "#d2e0f4", + "brandForegroundTint": "#d2e0f4", + "brandStroke1": "#185abd", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", + "brandedBackground": "#185abd", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#292929", + "buttonBackgroundChecked": "#383838", + "buttonBackgroundDisabled": "#141414", + "buttonBackgroundHovered": "#3d3d3d", + "buttonBackgroundPressed": "#1f1f1f", + "buttonBorder": "#666666", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": "#2e6ac5", - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", - "compoundBrandBackground1": "#2e6ac5", - "compoundBrandBackground1Hover": "#6794d7", - "compoundBrandBackground1Pressed": "#185abd", - "compoundBrandForeground1": "#2e6ac5", - "compoundBrandForeground1Hover": "#6794d7", - "compoundBrandForeground1Pressed": "#185abd", - "compoundBrandStroke1": "#2e6ac5", - "compoundBrandStroke1Hover": "#6794d7", - "compoundBrandStroke1Pressed": "#185abd", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#185abd", + "checkboxBackgroundDisabled": "#141414", + "checkboxBorderColor": "#adadad", + "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#185abd", + "compoundBrandBackground1Hover": "#1651aa", + "compoundBrandBackground1Pressed": "#0e336a", + "compoundBrandForeground1": "#aec6eb", + "compoundBrandForeground1Hover": "#d2e0f4", + "compoundBrandForeground1Pressed": "#2e6ac5", + "compoundBrandStroke1": "#185abd", + "compoundBrandStroke1Hover": "#1651aa", + "compoundBrandStroke1Pressed": "#0e336a", "dangerBackground1": "#3f1011", "dangerBackground2": "#751d1f", "dangerBackground3": "#d13438", @@ -1734,83 +764,84 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "dangerForeground2": "#f1bbbc", "dangerForeground3": "#e37d80", "dangerForegroundInverted": "#d13438", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "dangerStroke1": "#d13438", + "defaultBackground": "#292929", + "defaultBorder": "#666666", + "defaultCheckedBackground": "#383838", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#3d3d3d", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#141414", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#3d3d3d", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#3d3d3d", + "defaultHoveredBorder": "#757575", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#d6d6d6", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", + "defaultPressedBackground": "#1f1f1f", + "defaultPressedBorder": "#6b6b6b", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#d6d6d6", + "disabledBackground": "#141414", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": "#2e6ac5", - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": "#2e6ac5", - "linkHovered": "#82c7ff", - "linkPressed": "#aec6eb", - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": "#6794d7", - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#ffffff", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#d6d6d6", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#d6d6d6", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#292929", + "inputBorder": "#666666", + "inputFocusBorderAlt": "#185abd", + "inputPlaceholderText": "#999999", + "inputText": "#ffffff", + "link": "#aec6eb", + "linkHovered": "#d2e0f4", + "linkPressed": "#2e6ac5", + "listHeaderBackgroundHovered": "#3d3d3d", + "listHeaderBackgroundPressed": "#1f1f1f", + "menuBackground": "#292929", + "menuDivider": "#525252", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#3d3d3d", + "menuItemBackgroundPressed": "#1f1f1f", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", "neutralBackground1": "#292929", "neutralBackground1Hover": "#3d3d3d", "neutralBackground1Pressed": "#1f1f1f", @@ -1832,37 +863,46 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "neutralBackground5Pressed": "#050505", "neutralBackground5Selected": "#0f0f0f", "neutralBackground6": "#333333", + "neutralBackgroundCanvas": "#292929", + "neutralBackgroundDarkStatic": "#3d3d3d", "neutralBackgroundDisabled": "#141414", "neutralBackgroundInverted": "#ffffff", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#141414", "neutralForeground1": "#ffffff", "neutralForeground1Hover": "#ffffff", "neutralForeground1Pressed": "#ffffff", "neutralForeground1Selected": "#ffffff", "neutralForeground2": "#d6d6d6", - "neutralForeground2BrandHover": "#6794d7", + "neutralForeground2BrandHover": "#d2e0f4", "neutralForeground2BrandPressed": "#2e6ac5", - "neutralForeground2BrandSelected": "#6794d7", + "neutralForeground2BrandSelected": "#d2e0f4", "neutralForeground2Hover": "#ffffff", "neutralForeground2Pressed": "#ffffff", "neutralForeground2Selected": "#ffffff", "neutralForeground3": "#adadad", - "neutralForeground3BrandHover": "#6794d7", + "neutralForeground3BrandHover": "#d2e0f4", "neutralForeground3BrandPressed": "#2e6ac5", - "neutralForeground3BrandSelected": "#6794d7", + "neutralForeground3BrandSelected": "#d2e0f4", "neutralForeground3Hover": "#d6d6d6", "neutralForeground3Pressed": "#d6d6d6", "neutralForeground3Selected": "#d6d6d6", "neutralForeground4": "#999999", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#5c5c5c", - "neutralForegroundInverted": "#242424", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundDisabled1": "#5c5c5c", + "neutralForegroundDisabled2": "#5c5c5c", + "neutralForegroundInverted": "#000000", + "neutralForegroundInvertedLink": "#292929", + "neutralForegroundInvertedLinkHover": "#292929", + "neutralForegroundInvertedLinkPressed": "#292929", + "neutralForegroundInvertedLinkSelected": "#292929", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#333333", "neutralStencil2": "#575757", "neutralStroke1": "#666666", @@ -1874,8 +914,10 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "neutralStrokeAccessible": "#adadad", "neutralStrokeAccessibleHover": "#bdbdbd", "neutralStrokeAccessiblePressed": "#b3b3b3", - "neutralStrokeAccessibleSelected": "#6794d7", + "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#424242", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", "outofofficeBackground1": "#3a1136", "outofofficeBackground2": "#6d2064", "outofofficeBackground3": "#c239b3", @@ -1885,18 +927,31 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "outofofficeForeground1": "#da7ed0", "outofofficeForeground2": "#edbbe7", "outofofficeForeground3": "#d161c4", - "personaActivityGlow": "#2e6ac5", - "personaActivityRing": "#1b1a19", - "primaryButtonBackground": "#2e6ac5", - "primaryButtonBackgroundDisabled": "#252423", - "primaryButtonBackgroundHovered": "#6794d7", - "primaryButtonBackgroundPressed": "#aec6eb", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "personaActivityGlow": "#185abd", + "personaActivityRing": "#292929", + "presenceAvailable": "#54b054", + "presenceAway": "#feee66", + "presenceDnd": "#e37d80", + "presenceOof": "#da7ed0", + "primaryButtonBackground": "#185abd", + "primaryButtonBackgroundDisabled": "#141414", + "primaryButtonBackgroundHovered": "#1651aa", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#751d1f", + "redBackground3": "#d13438", + "redBorder1": "#d13438", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#f1bbbc", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#7a2101", "severeBackground3": "#da3b01", @@ -1906,13 +961,14 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "severeForeground1": "#e9835e", "severeForeground2": "#f4bfab", "severeForeground3": "#e9835e", + "severeStroke1": "#da3b01", "strokeFocus1": "#000000", "strokeFocus2": "#ffffff", - "subText": "#a19f9d", + "subText": "#d6d6d6", "subtleBackground": "#00000000", - "subtleBackgroundHover": "#383838", - "subtleBackgroundPressed": "#2e2e2e", - "subtleBackgroundSelected": "#333333", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", "successBackground1": "#052505", "successBackground2": "#094509", "successBackground3": "#107c10", @@ -1923,6 +979,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "successForeground2": "#9fd89f", "successForeground3": "#9fd89f", "successForegroundInverted": "#107c10", + "successStroke1": "#107c10", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -1930,7 +987,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#292827", + "variantBorder": "#525252", "warningBackground1": "#4c4400", "warningBackground2": "#817400", "warningBackground3": "#fde300", @@ -1941,6 +998,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "warningForeground2": "#fef7b2", "warningForeground3": "#fdea3d", "warningForegroundInverted": "#817400", + "warningStroke1": "#fde300", }, "components": {}, "host": { @@ -2125,13 +1183,13 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -2145,138 +1203,153 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -2290,283 +1363,793 @@ exports[`createDefaultTheme test themeOption - { appearance: 'dynamic', defaultA exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', defaultAppearance: 'light' } 1`] = ` { "colors": { - "accentButtonBackground": "#000000", - "actionLink": "#ffff00", - "background": "#000000", - "bodyDivider": "#ffffff", - "bodyFrameBackground": "#000000", - "bodyFrameDivider": "#000000", - "bodyStandoutBackground": "#000000", - "bodyText": "#ffffff", - "bodyTextChecked": "#000000", - "brandBackground": { + "accentButtonBackground": { "resource_paths": [ "ButtonFace", ], }, - "brandBackground2": { + "actionLink": { "resource_paths": [ - "ButtonFace", + "WindowText", ], }, - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": { + "background": { "resource_paths": [ - "Highlight", + "Window", ], }, - "brandBackgroundPressed": { + "bodyDivider": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "brandBackgroundSelected": { + "bodyFrameBackground": { "resource_paths": [ - "Highlight", + "Window", + ], + }, + "bodyFrameDivider": { + "resource_paths": [ + "WindowText", + ], + }, + "bodyStandoutBackground": { + "resource_paths": [ + "Window", + ], + }, + "bodyText": { + "resource_paths": [ + "WindowText", + ], + }, + "bodyTextChecked": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandBackground": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandBackground2": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandBackground2Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackground2Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackground3": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "brandBackgroundHover": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackgroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "brandBackgroundInvertedDisabled": { + "resource_paths": [ + "Window", + ], + }, + "brandBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackgroundSelected": { + "resource_paths": [ + "Highlight", ], }, "brandBackgroundStatic": { "resource_paths": [ - "Window", + "Window", + ], + }, + "brandBackgroundTint": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "brandForeground1Disabled": { + "resource_paths": [ + "GrayText", + ], + }, + "brandForeground1Pressed": { + "resource_paths": [ + "WindowText", + ], + }, + "brandForeground1Selected": { + "resource_paths": [ + "WindowText", + ], + }, + "brandForeground2": { + "resource_paths": [ + "ButtonText", + ], + }, + "brandForegroundDisabled1": { + "resource_paths": [ + "GrayText", + ], + }, + "brandForegroundDisabled2": { + "resource_paths": [ + "GrayText", + ], + }, + "brandForegroundLink": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundLinkHover": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundLinkPressed": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundLinkSelected": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundTint": { + "resource_paths": [ + "ButtonText", + ], + }, + "brandStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "brandStroke1Pressed": { + "resource_paths": [ + "WindowText", + ], + }, + "brandStroke1Selected": { + "resource_paths": [ + "WindowText", + ], + }, + "brandStroke2": { + "resource_paths": [ + "Window", + ], + }, + "brandStrokeTint": { + "resource_paths": [ + "Window", + ], + }, + "brandedBackground": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandedDisabledBorder": { + "resource_paths": [ + "GrayText", + ], + }, + "brandedFocusedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandedHoveredSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandedPressedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandedSecondaryContent": { + "resource_paths": [ + "ButtonText", + ], + }, + "buttonBackground": { + "resource_paths": [ + "Window", + ], + }, + "buttonBackgroundChecked": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "buttonBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "buttonBorderDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "buttonBorderFocused": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonText": { + "resource_paths": [ + "WindowText", + ], + }, + "buttonTextChecked": { + "resource_paths": [ + "HighlightText", + ], + }, + "buttonTextDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "buttonTextHovered": { + "resource_paths": [ + "HighlightText", + ], + }, + "buttonTextPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "checkboxBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "checkboxBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "checkboxBorderColor": { + "resource_paths": [ + "WindowText", + ], + }, + "checkmarkColor": { + "resource_paths": [ + "ButtonText", + ], + }, + "compoundBrandBackground1": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandBackground1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandBackground1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandForeground1": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandForeground1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandForeground1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandStroke1": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandStroke1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandStroke1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "dangerBackground1": { + "resource_paths": [ + "Window", + ], + }, + "dangerBackground2": { + "resource_paths": [ + "Window", + ], + }, + "dangerBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "dangerForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerForegroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultBackground": { + "resource_paths": [ + "Window", + ], + }, + "defaultBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultCheckedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultCheckedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultCheckedHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultCheckedHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultContent": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultDisabledBackground": { + "resource_paths": [ + "Window", + ], + }, + "defaultDisabledBorder": { + "resource_paths": [ + "GrayText", + ], + }, + "defaultDisabledContent": { + "resource_paths": [ + "GrayText", + ], + }, + "defaultDisabledIcon": { + "resource_paths": [ + "GrayText", + ], + }, + "defaultFocusedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultFocusedBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultFocusedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultFocusedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultHoveredBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultHoveredIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultHoveredSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultIcon": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultPressedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultPressedBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultPressedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultPressedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultPressedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "disabledBackground": { + "resource_paths": [ + "Window", + ], + }, + "disabledBodyText": { + "resource_paths": [ + "GrayText", + ], + }, + "disabledText": { + "resource_paths": [ + "GrayText", + ], + }, + "errorText": { + "resource_paths": [ + "WindowText", + ], + }, + "focusBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostBackground": "#00000000", + "ghostBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostCheckedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostCheckedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostCheckedHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostCheckedHoveredBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostCheckedHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostContent": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostDisabledContent": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostDisabledIcon": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostFocusedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostFocusedBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostFocusedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostFocusedIcon": { + "resource_paths": [ + "HighlightText", ], }, - "brandForeground1": { + "ghostFocusedSecondaryContent": { "resource_paths": [ "WindowText", ], }, - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": { + "ghostHoveredBackground": { "resource_paths": [ - "ButtonText", + "Highlight", ], }, - "brandForegroundLink": { + "ghostHoveredBorder": { "resource_paths": [ - "Hotlight", + "WindowText", ], }, - "brandForegroundLinkHover": { + "ghostHoveredContent": { "resource_paths": [ - "Hotlight", + "HighlightText", ], }, - "brandForegroundLinkPressed": { + "ghostHoveredIcon": { "resource_paths": [ - "Hotlight", + "HighlightText", ], }, - "brandForegroundLinkSelected": { + "ghostHoveredSecondaryContent": { "resource_paths": [ - "Hotlight", + "HighlightText", ], }, - "brandStroke1": { + "ghostIcon": { "resource_paths": [ "WindowText", ], }, - "brandStroke2": { + "ghostPressedBackground": { "resource_paths": [ - "Window", + "Highlight", ], }, - "brandedBackground": "#000000", - "brandedDisabledBorder": "#3ff23f", - "brandedFocusedSecondaryContent": "#ffffff", - "brandedHoveredSecondaryContent": "#000000", - "brandedPressedSecondaryContent": "#000000", - "brandedSecondaryContent": "#ffffff", - "buttonBackground": "#000000", - "buttonBackgroundChecked": "#1aebff", - "buttonBackgroundDisabled": "#000000", - "buttonBackgroundHovered": "#1aebff", - "buttonBackgroundPressed": "#1aebff", - "buttonBorder": "#ffffff", - "buttonBorderDisabled": "#3ff23f", - "buttonBorderFocused": "#ffffff", - "buttonText": "#ffffff", - "buttonTextChecked": "#000000", - "buttonTextDisabled": "#3ff23f", - "buttonTextHovered": "#000000", - "buttonTextPressed": "#000000", - "checkboxBackground": "#000000", - "checkboxBackgroundDisabled": "#000000", - "checkboxBorderColor": "#ffffff", - "checkmarkColor": "#ffffff", - "compoundBrandBackground1": { + "ghostPressedBorder": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "compoundBrandBackground1Hover": { + "ghostPressedContent": { "resource_paths": [ - "Highlight", + "HighlightText", ], }, - "compoundBrandBackground1Pressed": { + "ghostPressedIcon": { "resource_paths": [ - "Highlight", + "HighlightText", ], }, - "compoundBrandForeground1": { + "ghostPressedSecondaryContent": { "resource_paths": [ - "Highlight", + "HighlightText", ], }, - "compoundBrandForeground1Hover": { + "ghostSecondaryContent": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "compoundBrandForeground1Pressed": { + "inputBackground": { "resource_paths": [ - "Highlight", + "Window", ], }, - "compoundBrandStroke1": { + "inputBorder": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "compoundBrandStroke1Hover": { + "inputFocusBorderAlt": { "resource_paths": [ "Highlight", ], }, - "compoundBrandStroke1Pressed": { + "inputPlaceholderText": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "dangerBackground1": { + "inputText": { "resource_paths": [ - "Window", + "WindowText", ], }, - "dangerBackground2": { + "link": { "resource_paths": [ - "Window", + "Hotlight", ], }, - "dangerBackground3": { + "linkHovered": { "resource_paths": [ - "WindowText", + "Hotlight", ], }, - "dangerBorder1": { + "linkPressed": { "resource_paths": [ - "WindowText", + "Hotlight", ], }, - "dangerBorder2": { + "listHeaderBackgroundHovered": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "dangerBorderActive": { + "listHeaderBackgroundPressed": { "resource_paths": [ "Highlight", ], }, - "dangerForeground1": { + "menuBackground": { "resource_paths": [ - "WindowText", + "Window", ], }, - "dangerForeground2": { + "menuDivider": { "resource_paths": [ "WindowText", ], }, - "dangerForeground3": { + "menuIcon": { "resource_paths": [ "WindowText", ], }, - "dangerForegroundInverted": { + "menuItemBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "menuItemBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "menuItemText": { "resource_paths": [ "WindowText", ], }, - "defaultBackground": "#000000", - "defaultBorder": "#ffffff", - "defaultCheckedBackground": "#1aebff", - "defaultCheckedContent": "#000000", - "defaultCheckedHoveredBackground": "#1aebff", - "defaultCheckedHoveredContent": "#000000", - "defaultContent": "#ffffff", - "defaultDisabledBackground": "#000000", - "defaultDisabledBorder": "#3ff23f", - "defaultDisabledContent": "#3ff23f", - "defaultDisabledIcon": "#3ff23f", - "defaultFocusedBackground": "#000000", - "defaultFocusedBorder": "#ffffff", - "defaultFocusedContent": "#ffffff", - "defaultFocusedIcon": "#ffffff", - "defaultHoveredBackground": "#1aebff", - "defaultHoveredBorder": "#1aebff", - "defaultHoveredContent": "#000000", - "defaultHoveredIcon": "#000000", - "defaultHoveredSecondaryContent": "#000000", - "defaultIcon": "#ffffff", - "defaultPressedBackground": "#1aebff", - "defaultPressedBorder": "#1aebff", - "defaultPressedContent": "#000000", - "defaultPressedIcon": "#000000", - "defaultPressedSecondaryContent": "#000000", - "disabledBackground": "#000000", - "disabledBodyText": "#3ff23f", - "disabledText": "#3ff23f", - "errorText": "#ffffff", - "focusBorder": "#ffffff", - "ghostBackground": "#000000", - "ghostBorder": "#000000", - "ghostCheckedBackground": "#1aebff", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#1aebff", - "ghostCheckedHoveredBorder": "#000000", - "ghostCheckedHoveredContent": "#000000", - "ghostContent": "#ffffff", - "ghostDisabledBackground": "#000000", - "ghostDisabledBorder": "#000000", - "ghostDisabledContent": "#3ff23f", - "ghostDisabledIcon": "#3ff23f", - "ghostFocusedBackground": "#000000", - "ghostFocusedBorder": "#ffffff", - "ghostFocusedContent": "#ffffff", - "ghostFocusedIcon": "#ffffff", - "ghostFocusedSecondaryContent": "#ffffff", - "ghostHoveredBackground": "#1aebff", - "ghostHoveredBorder": "#1aebff", - "ghostHoveredContent": "#000000", - "ghostHoveredIcon": "#000000", - "ghostHoveredSecondaryContent": "#000000", - "ghostIcon": "#ffffff", - "ghostPressedBackground": "#1aebff", - "ghostPressedBorder": "#1aebff", - "ghostPressedContent": "#000000", - "ghostPressedIcon": "#000000", - "ghostPressedSecondaryContent": "#000000", - "ghostSecondaryContent": "#ffffff", - "inputBackground": "#000000", - "inputBorder": "#ffffff", - "inputFocusBorderAlt": "#ffffff", - "inputPlaceholderText": "#ffffff", - "inputText": "#ffffff", - "link": "#ffff00", - "linkHovered": "#ffffff", - "linkPressed": "#ffffff", - "listHeaderBackgroundHovered": "#1aebff", - "listHeaderBackgroundPressed": "#1aebff", - "menuBackground": "#000000", - "menuDivider": "#ffffff", - "menuIcon": "#ffffff", - "menuItemBackgroundHovered": "#1aebff", - "menuItemBackgroundPressed": "#1aebff", - "menuItemText": "#ffffff", - "menuItemTextHovered": "#000000", + "menuItemTextHovered": { + "resource_paths": [ + "HighlightText", + ], + }, "neutralBackground1": { "resource_paths": [ "Window", @@ -2672,6 +2255,12 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "Window", ], }, + "neutralBackgroundCanvas": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackgroundDarkStatic": "#3d3d3d", "neutralBackgroundDisabled": { "resource_paths": [ "Window", @@ -2682,6 +2271,12 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "WindowText", ], }, + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": { + "resource_paths": [ + "Window", + ], + }, "neutralForeground1": { "resource_paths": [ "WindowText", @@ -2772,175 +2367,315 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "HighlightText", ], }, - "neutralForeground4": { + "neutralForeground4": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundDisabled1": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundDisabled2": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundInverted": { + "resource_paths": [ + "Window", + ], + }, + "neutralForegroundInvertedLink": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkHover": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkPressed": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkSelected": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": { + "resource_paths": [ + "ButtonText", + ], + }, + "neutralForegroundOnBrandHover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnBrandPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnBrandSelected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnColor": { + "resource_paths": [ + "ButtonText", + ], + }, + "neutralStencil1": "#141414", + "neutralStencil2": "#858585", + "neutralStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStroke1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke1Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke2": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStroke3": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStrokeAccessible": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStrokeAccessibleHover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeAccessiblePressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeAccessibleSelected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralStrokeFocus1": { + "resource_paths": [ + "Window", + ], + }, + "neutralStrokeFocus2": { + "resource_paths": [ + "Highlight", + ], + }, + "outofofficeBackground1": { + "resource_paths": [ + "Window", + ], + }, + "outofofficeBackground2": { + "resource_paths": [ + "Window", + ], + }, + "outofofficeBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeBorder1": { "resource_paths": [ "WindowText", ], }, - "neutralForegroundDisabled": { + "outofofficeBorder2": { "resource_paths": [ - "GrayText", + "WindowText", ], }, - "neutralForegroundInverted": { + "outofofficeBorderActive": { "resource_paths": [ - "Window", + "Highlight", ], }, - "neutralForegroundInvertedLink": { + "outofofficeForeground1": { "resource_paths": [ - "Hotlight", + "WindowText", ], }, - "neutralForegroundInvertedLinkHover": { + "outofofficeForeground2": { "resource_paths": [ - "Hotlight", + "WindowText", ], }, - "neutralForegroundInvertedLinkPressed": { + "outofofficeForeground3": { "resource_paths": [ - "Hotlight", + "WindowText", ], }, - "neutralForegroundInvertedLinkSelected": { + "personaActivityGlow": { "resource_paths": [ - "Hotlight", + "ButtonFace", ], }, - "neutralForegroundOnBrand": { + "personaActivityRing": { "resource_paths": [ - "ButtonText", + "Window", ], }, - "neutralForegroundOnBrandHover": { + "presenceAvailable": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralForegroundOnBrandPressed": { + "presenceAway": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralForegroundOnBrandSelected": { + "presenceDnd": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralStencil1": "#141414", - "neutralStencil2": "#858585", - "neutralStroke1": { + "presenceOof": { "resource_paths": [ "WindowText", ], }, - "neutralStroke1Hover": { + "primaryButtonBackground": { "resource_paths": [ - "Highlight", + "ButtonFace", ], }, - "neutralStroke1Pressed": { + "primaryButtonBackgroundDisabled": { "resource_paths": [ - "Highlight", + "Window", ], }, - "neutralStroke1Selected": { + "primaryButtonBackgroundHovered": { "resource_paths": [ "Highlight", ], }, - "neutralStroke2": { + "primaryButtonBackgroundPressed": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "neutralStroke3": { + "primaryButtonBorder": { "resource_paths": [ "WindowText", ], }, - "neutralStrokeAccessible": { + "primaryButtonBorderFocused": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "neutralStrokeAccessibleHover": { + "primaryButtonText": { "resource_paths": [ - "Highlight", + "ButtonText", ], }, - "neutralStrokeAccessiblePressed": { + "primaryButtonTextDisabled": { "resource_paths": [ - "Highlight", + "GrayText", ], }, - "neutralStrokeAccessibleSelected": { + "primaryButtonTextHovered": { "resource_paths": [ - "Highlight", + "HighlightText", ], }, - "neutralStrokeDisabled": { + "primaryButtonTextPressed": { "resource_paths": [ - "GrayText", + "HighlightText", ], }, - "outofofficeBackground1": { + "redBackground1": { "resource_paths": [ "Window", ], }, - "outofofficeBackground2": { + "redBackground2": { "resource_paths": [ "Window", ], }, - "outofofficeBackground3": { + "redBackground3": { "resource_paths": [ "WindowText", ], }, - "outofofficeBorder1": { + "redBorder1": { "resource_paths": [ "WindowText", ], }, - "outofofficeBorder2": { + "redBorder2": { "resource_paths": [ "WindowText", ], }, - "outofofficeBorderActive": { + "redBorderActive": { "resource_paths": [ "Highlight", ], }, - "outofofficeForeground1": { + "redForeground1": { "resource_paths": [ "WindowText", ], }, - "outofofficeForeground2": { + "redForeground2": { "resource_paths": [ "WindowText", ], }, - "outofofficeForeground3": { + "redForeground3": { "resource_paths": [ "WindowText", ], }, - "personaActivityGlow": "transparent", - "personaActivityRing": "#ffffff", - "primaryButtonBackground": "#000000", - "primaryButtonBackgroundDisabled": "#000000", - "primaryButtonBackgroundHovered": "#1aebff", - "primaryButtonBackgroundPressed": "#1aebff", - "primaryButtonBorder": "#ffffff", - "primaryButtonBorderFocused": "#ffffff", - "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#3ff23f", - "primaryButtonTextHovered": "#000000", - "primaryButtonTextPressed": "#000000", "severeBackground1": { "resource_paths": [ "Window", @@ -2986,6 +2721,11 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "WindowText", ], }, + "severeStroke1": { + "resource_paths": [ + "WindowText", + ], + }, "strokeFocus1": { "resource_paths": [ "Window", @@ -2996,7 +2736,11 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "Highlight", ], }, - "subText": "#ffffff", + "subText": { + "resource_paths": [ + "WindowText", + ], + }, "subtleBackground": "#00000000", "subtleBackgroundHover": { "resource_paths": [ @@ -3063,6 +2807,11 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "WindowText", ], }, + "successStroke1": { + "resource_paths": [ + "WindowText", + ], + }, "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -3082,7 +2831,11 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "Highlight", ], }, - "variantBorder": "#ffffff", + "variantBorder": { + "resource_paths": [ + "WindowText", + ], + }, "warningBackground1": { "resource_paths": [ "Window", @@ -3133,6 +2886,11 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "WindowText", ], }, + "warningStroke1": { + "resource_paths": [ + "WindowText", + ], + }, }, "components": {}, "host": { @@ -3317,13 +3075,13 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -3337,138 +3095,153 @@ exports[`createDefaultTheme test themeOption - { appearance: 'highContrast', def "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -3483,63 +3256,76 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp { "colors": { "accentButtonBackground": "#185abd", - "actionLink": "#323130", + "actionLink": "#242424", "background": "#ffffff", - "bodyDivider": "#edebe9", + "bodyDivider": "#e0e0e0", "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", - "bodyTextChecked": "#000000", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#fafafa", + "bodyText": "#242424", + "bodyTextChecked": "#242424", "brandBackground": "#185abd", - "brandBackground2": "#eff6fc", - "brandBackgroundDisabled": undefined, + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#f0f0f0", "brandBackgroundHover": "#1651aa", - "brandBackgroundPressed": "#004578", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", + "brandBackgroundPressed": "#0e336a", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", + "brandBackgroundTint": "#d2e0f4", "brandForeground1": "#185abd", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, + "brandForeground1Disabled": "#bdbdbd", + "brandForeground1Pressed": "#185abd", + "brandForeground1Selected": "#185abd", "brandForeground2": "#1651aa", - "brandForegroundLink": "#1651aa", - "brandForegroundLinkHover": "#13458f", - "brandForegroundLinkPressed": "#004578", - "brandForegroundLinkSelected": "#1651aa", + "brandForegroundDisabled1": "#bdbdbd", + "brandForegroundDisabled2": "#bdbdbd", + "brandForegroundLink": "#185abd", + "brandForegroundLinkHover": "#1651aa", + "brandForegroundLinkPressed": "#0e336a", + "brandForegroundLinkSelected": "#13458f", + "brandForegroundTint": "#1651aa", "brandStroke1": "#185abd", - "brandStroke2": "#d2e0f4", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", "brandedBackground": "#185abd", - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#f0f0f0", + "buttonBackgroundHovered": "#f5f5f5", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", "checkboxBackground": "#185abd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", "compoundBrandBackground1": "#185abd", "compoundBrandBackground1Hover": "#1651aa", - "compoundBrandBackground1Pressed": "#13458f", + "compoundBrandBackground1Pressed": "#0e336a", "compoundBrandForeground1": "#185abd", "compoundBrandForeground1Hover": "#1651aa", - "compoundBrandForeground1Pressed": "#13458f", + "compoundBrandForeground1Pressed": "#0e336a", "compoundBrandStroke1": "#185abd", "compoundBrandStroke1Hover": "#1651aa", - "compoundBrandStroke1Pressed": "#13458f", + "compoundBrandStroke1Pressed": "#0e336a", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#f1bbbc", "dangerBackground3": "#d13438", @@ -3550,83 +3336,84 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "dangerForeground2": "#751d1f", "dangerForeground3": "#d13438", "dangerForegroundInverted": "#dc5e62", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", + "dangerStroke1": "#f1bbbc", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#f5f5f5", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#f0f0f0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#f5f5f5", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#f5f5f5", + "defaultHoveredBorder": "#c7c7c7", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#424242", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#b3b3b3", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#424242", + "disabledBackground": "#f0f0f0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#242424", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#242424", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#616161", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#424242", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#424242", + "ghostSecondaryContent": "#616161", "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", + "inputBorder": "#d1d1d1", "inputFocusBorderAlt": "#185abd", - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", + "inputPlaceholderText": "#707070", + "inputText": "#242424", "link": "#185abd", - "linkHovered": "#004578", - "linkPressed": "#13458f", - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", + "linkHovered": "#1651aa", + "linkPressed": "#0e336a", + "listHeaderBackgroundHovered": "#f5f5f5", + "listHeaderBackgroundPressed": "#e0e0e0", "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": "#185abd", - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", + "menuDivider": "#e0e0e0", + "menuIcon": "#424242", + "menuItemBackgroundHovered": "#f5f5f5", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", "neutralBackground1": "#ffffff", "neutralBackground1Hover": "#f5f5f5", "neutralBackground1Pressed": "#e0e0e0", @@ -3648,37 +3435,46 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "neutralBackground5Pressed": "#f0f0f0", "neutralBackground5Selected": "#fafafa", "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", "neutralBackgroundDisabled": "#f0f0f0", "neutralBackgroundInverted": "#616161", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", "neutralForeground1": "#242424", "neutralForeground1Hover": "#242424", "neutralForeground1Pressed": "#242424", "neutralForeground1Selected": "#242424", "neutralForeground2": "#424242", - "neutralForeground2BrandHover": "#185abd", - "neutralForeground2BrandPressed": "#1651aa", - "neutralForeground2BrandSelected": "#185abd", + "neutralForeground2BrandHover": "#1651aa", + "neutralForeground2BrandPressed": "#0e336a", + "neutralForeground2BrandSelected": "#13458f", "neutralForeground2Hover": "#242424", "neutralForeground2Pressed": "#242424", "neutralForeground2Selected": "#242424", "neutralForeground3": "#616161", - "neutralForeground3BrandHover": "#185abd", - "neutralForeground3BrandPressed": "#1651aa", - "neutralForeground3BrandSelected": "#185abd", + "neutralForeground3BrandHover": "#1651aa", + "neutralForeground3BrandPressed": "#0e336a", + "neutralForeground3BrandSelected": "#13458f", "neutralForeground3Hover": "#424242", "neutralForeground3Pressed": "#424242", "neutralForeground3Selected": "#424242", "neutralForeground4": "#707070", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#bdbdbd", + "neutralForegroundDisabled1": "#bdbdbd", + "neutralForegroundDisabled2": "#bdbdbd", "neutralForegroundInverted": "#ffffff", "neutralForegroundInvertedLink": "#ffffff", "neutralForegroundInvertedLinkHover": "#ffffff", "neutralForegroundInvertedLinkPressed": "#ffffff", "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", "neutralStroke1": "#d1d1d1", @@ -3692,6 +3488,8 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "neutralStrokeAccessiblePressed": "#4d4d4d", "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#e0e0e0", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", "outofofficeBackground1": "#fdf5fc", "outofofficeBackground2": "#edbbe7", "outofofficeBackground3": "#c239b3", @@ -3703,16 +3501,29 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "outofofficeForeground3": "#c239b3", "personaActivityGlow": "#185abd", "personaActivityRing": "#ffffff", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", "primaryButtonBackground": "#185abd", - "primaryButtonBackgroundDisabled": "#f3f2f1", + "primaryButtonBackgroundDisabled": "#f0f0f0", "primaryButtonBackgroundHovered": "#1651aa", - "primaryButtonBackgroundPressed": "#13458f", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", + "primaryButtonTextDisabled": "#bdbdbd", "primaryButtonTextHovered": "#ffffff", "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#f4bfab", "severeBackground3": "#da3b01", @@ -3722,9 +3533,10 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "severeForeground1": "#c43501", "severeForeground2": "#7a2101", "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", "strokeFocus1": "#ffffff", "strokeFocus2": "#000000", - "subText": "#605e5c", + "subText": "#424242", "subtleBackground": "#00000000", "subtleBackgroundHover": "#f5f5f5", "subtleBackgroundPressed": "#e0e0e0", @@ -3739,6 +3551,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "successForeground2": "#094509", "successForeground3": "#107c10", "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -3746,7 +3559,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#edebe9", + "variantBorder": "#e0e0e0", "warningBackground1": "#fffef5", "warningBackground2": "#fef7b2", "warningBackground3": "#fde300", @@ -3757,6 +3570,7 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "warningForeground2": "#817400", "warningForeground3": "#fde300", "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", }, "components": {}, "host": { @@ -3941,13 +3755,13 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -3961,138 +3775,153 @@ exports[`createDefaultTheme test themeOption - { appearance: 'light', defaultApp "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -4107,63 +3936,76 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA { "colors": { "accentButtonBackground": "#185abd", - "actionLink": "#323130", + "actionLink": "#242424", "background": "#ffffff", - "bodyDivider": "#edebe9", + "bodyDivider": "#e0e0e0", "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", - "bodyTextChecked": "#000000", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#fafafa", + "bodyText": "#242424", + "bodyTextChecked": "#242424", "brandBackground": "#185abd", - "brandBackground2": "#eff6fc", - "brandBackgroundDisabled": undefined, + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#f0f0f0", "brandBackgroundHover": "#1651aa", - "brandBackgroundPressed": "#004578", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", + "brandBackgroundPressed": "#0e336a", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", + "brandBackgroundTint": "#d2e0f4", "brandForeground1": "#185abd", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, + "brandForeground1Disabled": "#bdbdbd", + "brandForeground1Pressed": "#185abd", + "brandForeground1Selected": "#185abd", "brandForeground2": "#1651aa", - "brandForegroundLink": "#1651aa", - "brandForegroundLinkHover": "#13458f", - "brandForegroundLinkPressed": "#004578", - "brandForegroundLinkSelected": "#1651aa", + "brandForegroundDisabled1": "#bdbdbd", + "brandForegroundDisabled2": "#bdbdbd", + "brandForegroundLink": "#185abd", + "brandForegroundLinkHover": "#1651aa", + "brandForegroundLinkPressed": "#0e336a", + "brandForegroundLinkSelected": "#13458f", + "brandForegroundTint": "#1651aa", "brandStroke1": "#185abd", - "brandStroke2": "#d2e0f4", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", "brandedBackground": "#185abd", - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#f0f0f0", + "buttonBackgroundHovered": "#f5f5f5", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", "checkboxBackground": "#185abd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", "compoundBrandBackground1": "#185abd", "compoundBrandBackground1Hover": "#1651aa", - "compoundBrandBackground1Pressed": "#13458f", + "compoundBrandBackground1Pressed": "#0e336a", "compoundBrandForeground1": "#185abd", "compoundBrandForeground1Hover": "#1651aa", - "compoundBrandForeground1Pressed": "#13458f", + "compoundBrandForeground1Pressed": "#0e336a", "compoundBrandStroke1": "#185abd", "compoundBrandStroke1Hover": "#1651aa", - "compoundBrandStroke1Pressed": "#13458f", + "compoundBrandStroke1Pressed": "#0e336a", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#f1bbbc", "dangerBackground3": "#d13438", @@ -4174,83 +4016,84 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "dangerForeground2": "#751d1f", "dangerForeground3": "#d13438", "dangerForegroundInverted": "#dc5e62", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", + "dangerStroke1": "#f1bbbc", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#f5f5f5", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#f0f0f0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#f5f5f5", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#f5f5f5", + "defaultHoveredBorder": "#c7c7c7", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#424242", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#b3b3b3", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#424242", + "disabledBackground": "#f0f0f0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#242424", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#242424", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#616161", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#424242", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#424242", + "ghostSecondaryContent": "#616161", "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", + "inputBorder": "#d1d1d1", "inputFocusBorderAlt": "#185abd", - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", + "inputPlaceholderText": "#707070", + "inputText": "#242424", "link": "#185abd", - "linkHovered": "#004578", - "linkPressed": "#13458f", - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", + "linkHovered": "#1651aa", + "linkPressed": "#0e336a", + "listHeaderBackgroundHovered": "#f5f5f5", + "listHeaderBackgroundPressed": "#e0e0e0", "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": "#185abd", - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", + "menuDivider": "#e0e0e0", + "menuIcon": "#424242", + "menuItemBackgroundHovered": "#f5f5f5", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", "neutralBackground1": "#ffffff", "neutralBackground1Hover": "#f5f5f5", "neutralBackground1Pressed": "#e0e0e0", @@ -4272,37 +4115,46 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "neutralBackground5Pressed": "#f0f0f0", "neutralBackground5Selected": "#fafafa", "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", "neutralBackgroundDisabled": "#f0f0f0", "neutralBackgroundInverted": "#616161", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", "neutralForeground1": "#242424", "neutralForeground1Hover": "#242424", "neutralForeground1Pressed": "#242424", "neutralForeground1Selected": "#242424", "neutralForeground2": "#424242", - "neutralForeground2BrandHover": "#185abd", - "neutralForeground2BrandPressed": "#1651aa", - "neutralForeground2BrandSelected": "#185abd", + "neutralForeground2BrandHover": "#1651aa", + "neutralForeground2BrandPressed": "#0e336a", + "neutralForeground2BrandSelected": "#13458f", "neutralForeground2Hover": "#242424", "neutralForeground2Pressed": "#242424", "neutralForeground2Selected": "#242424", "neutralForeground3": "#616161", - "neutralForeground3BrandHover": "#185abd", - "neutralForeground3BrandPressed": "#1651aa", - "neutralForeground3BrandSelected": "#185abd", + "neutralForeground3BrandHover": "#1651aa", + "neutralForeground3BrandPressed": "#0e336a", + "neutralForeground3BrandSelected": "#13458f", "neutralForeground3Hover": "#424242", "neutralForeground3Pressed": "#424242", "neutralForeground3Selected": "#424242", "neutralForeground4": "#707070", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#bdbdbd", + "neutralForegroundDisabled1": "#bdbdbd", + "neutralForegroundDisabled2": "#bdbdbd", "neutralForegroundInverted": "#ffffff", "neutralForegroundInvertedLink": "#ffffff", "neutralForegroundInvertedLinkHover": "#ffffff", "neutralForegroundInvertedLinkPressed": "#ffffff", "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", "neutralStroke1": "#d1d1d1", @@ -4316,6 +4168,8 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "neutralStrokeAccessiblePressed": "#4d4d4d", "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#e0e0e0", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", "outofofficeBackground1": "#fdf5fc", "outofofficeBackground2": "#edbbe7", "outofofficeBackground3": "#c239b3", @@ -4327,16 +4181,29 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "outofofficeForeground3": "#c239b3", "personaActivityGlow": "#185abd", "personaActivityRing": "#ffffff", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", "primaryButtonBackground": "#185abd", - "primaryButtonBackgroundDisabled": "#f3f2f1", + "primaryButtonBackgroundDisabled": "#f0f0f0", "primaryButtonBackgroundHovered": "#1651aa", - "primaryButtonBackgroundPressed": "#13458f", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", + "primaryButtonTextDisabled": "#bdbdbd", "primaryButtonTextHovered": "#ffffff", "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#f4bfab", "severeBackground3": "#da3b01", @@ -4346,9 +4213,10 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "severeForeground1": "#c43501", "severeForeground2": "#7a2101", "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", "strokeFocus1": "#ffffff", "strokeFocus2": "#000000", - "subText": "#605e5c", + "subText": "#424242", "subtleBackground": "#00000000", "subtleBackgroundHover": "#f5f5f5", "subtleBackgroundPressed": "#e0e0e0", @@ -4363,6 +4231,7 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "successForeground2": "#094509", "successForeground3": "#107c10", "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -4370,7 +4239,7 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#edebe9", + "variantBorder": "#e0e0e0", "warningBackground1": "#fffef5", "warningBackground2": "#fef7b2", "warningBackground3": "#fde300", @@ -4381,6 +4250,7 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "warningForeground2": "#817400", "warningForeground3": "#fde300", "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", }, "components": {}, "host": { @@ -4565,13 +4435,13 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -4585,138 +4455,153 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -4727,586 +4612,80 @@ exports[`createDefaultTheme test themeOption - { appearance: undefined, defaultA } `; -exports[`createShadowAliasTokens test appearanceOptions - dark 1`] = ` -{ - "shadow16": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000047", - "x": 0, - "y": 8, - }, - }, - "shadow16brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000040", - "x": 0, - "y": 8, - }, - }, - "shadow2": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000047", - "x": 0, - "y": 1, - }, - }, - "shadow28": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#0000007a", - "x": 0, - "y": 14, - }, - }, - "shadow28brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#00000040", - "x": 0, - "y": 14, - }, - }, - "shadow2brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000040", - "x": 0, - "y": 1, - }, - }, - "shadow4": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000047", - "x": 0, - "y": 2, - }, - }, - "shadow4brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000040", - "x": 0, - "y": 2, - }, - }, - "shadow64": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#0000007a", - "x": 0, - "y": 32, - }, - }, - "shadow64brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#00000040", - "x": 0, - "y": 32, - }, - }, - "shadow8": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000047", - "x": 0, - "y": 4, - }, - }, - "shadow8brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000040", - "x": 0, - "y": 4, - }, - }, -} -`; - -exports[`createShadowAliasTokens test appearanceOptions - highContrast 1`] = ` -{ - "shadow16": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000047", - "x": 0, - "y": 8, - }, - }, - "shadow16brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000040", - "x": 0, - "y": 8, - }, - }, - "shadow2": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000047", - "x": 0, - "y": 1, - }, - }, - "shadow28": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#0000007a", - "x": 0, - "y": 14, - }, - }, - "shadow28brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#00000040", - "x": 0, - "y": 14, - }, - }, - "shadow2brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000040", - "x": 0, - "y": 1, - }, - }, - "shadow4": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000047", - "x": 0, - "y": 2, - }, - }, - "shadow4brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000040", - "x": 0, - "y": 2, - }, - }, - "shadow64": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#0000007a", - "x": 0, - "y": 32, - }, - }, - "shadow64brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#00000040", - "x": 0, - "y": 32, - }, - }, - "shadow8": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000047", - "x": 0, - "y": 4, - }, - }, - "shadow8brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000040", - "x": 0, - "y": 4, - }, - }, -} -`; - -exports[`createShadowAliasTokens test appearanceOptions - light 1`] = ` -{ - "shadow16": { - "ambient": { - "blur": 2, - "color": "#0000001f", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000024", - "x": 0, - "y": 8, - }, - }, - "shadow16brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000040", - "x": 0, - "y": 8, - }, - }, - "shadow2": { - "ambient": { - "blur": 2, - "color": "#0000001f", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000024", - "x": 0, - "y": 1, - }, - }, - "shadow28": { - "ambient": { - "blur": 8, - "color": "#00000033", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#0000003d", - "x": 0, - "y": 14, - }, - }, - "shadow28brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#00000040", - "x": 0, - "y": 14, - }, - }, - "shadow2brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000040", - "x": 0, - "y": 1, - }, - }, - "shadow4": { - "ambient": { - "blur": 2, - "color": "#0000001f", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000024", - "x": 0, - "y": 2, - }, - }, - "shadow4brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000040", - "x": 0, - "y": 2, - }, - }, - "shadow64": { - "ambient": { - "blur": 8, - "color": "#00000033", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#0000003d", - "x": 0, - "y": 32, - }, - }, - "shadow64brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#00000040", - "x": 0, - "y": 32, - }, - }, - "shadow8": { - "ambient": { - "blur": 2, - "color": "#0000001f", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000024", - "x": 0, - "y": 4, - }, - }, - "shadow8brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000040", - "x": 0, - "y": 4, - }, - }, -} -`; - exports[`defaultFluentDarkTheme test 1`] = ` { "colors": { "accentButtonBackground": "#185abd", - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "actionLink": "#ffffff", + "background": "#292929", + "bodyDivider": "#525252", + "bodyFrameBackground": "#292929", + "bodyFrameDivider": "#525252", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", - "brandBackground": "#1651aa", - "brandBackground2": "#004578", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#185abd", - "brandBackgroundPressed": "#004578", + "brandBackground": "#185abd", + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#141414", + "brandBackgroundHover": "#1651aa", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#141414", + "brandBackgroundPressed": "#0e336a", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", - "brandForeground1": "#6794d7", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#aec6eb", - "brandForegroundLink": "#2e6ac5", - "brandForegroundLinkHover": "#aec6eb", - "brandForegroundLinkPressed": "#6794d7", - "brandForegroundLinkSelected": "#2e6ac5", - "brandStroke1": "#2e6ac5", - "brandStroke2": "#0e336a", - "brandedBackground": "#2e6ac5", - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandBackgroundTint": "#d2e0f4", + "brandForeground1": "#aec6eb", + "brandForeground1Disabled": "#5c5c5c", + "brandForeground1Pressed": "#aec6eb", + "brandForeground1Selected": "#aec6eb", + "brandForeground2": "#d2e0f4", + "brandForegroundDisabled1": "#5c5c5c", + "brandForegroundDisabled2": "#5c5c5c", + "brandForegroundLink": "#aec6eb", + "brandForegroundLinkHover": "#d2e0f4", + "brandForegroundLinkPressed": "#2e6ac5", + "brandForegroundLinkSelected": "#d2e0f4", + "brandForegroundTint": "#d2e0f4", + "brandStroke1": "#185abd", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", + "brandedBackground": "#185abd", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#292929", + "buttonBackgroundChecked": "#383838", + "buttonBackgroundDisabled": "#141414", + "buttonBackgroundHovered": "#3d3d3d", + "buttonBackgroundPressed": "#1f1f1f", + "buttonBorder": "#666666", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": "#2e6ac5", - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", - "compoundBrandBackground1": "#2e6ac5", - "compoundBrandBackground1Hover": "#6794d7", - "compoundBrandBackground1Pressed": "#185abd", - "compoundBrandForeground1": "#2e6ac5", - "compoundBrandForeground1Hover": "#6794d7", - "compoundBrandForeground1Pressed": "#185abd", - "compoundBrandStroke1": "#2e6ac5", - "compoundBrandStroke1Hover": "#6794d7", - "compoundBrandStroke1Pressed": "#185abd", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#185abd", + "checkboxBackgroundDisabled": "#141414", + "checkboxBorderColor": "#adadad", + "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#185abd", + "compoundBrandBackground1Hover": "#1651aa", + "compoundBrandBackground1Pressed": "#0e336a", + "compoundBrandForeground1": "#aec6eb", + "compoundBrandForeground1Hover": "#d2e0f4", + "compoundBrandForeground1Pressed": "#2e6ac5", + "compoundBrandStroke1": "#185abd", + "compoundBrandStroke1Hover": "#1651aa", + "compoundBrandStroke1Pressed": "#0e336a", "dangerBackground1": "#3f1011", "dangerBackground2": "#751d1f", "dangerBackground3": "#d13438", @@ -5317,83 +4696,84 @@ exports[`defaultFluentDarkTheme test 1`] = ` "dangerForeground2": "#f1bbbc", "dangerForeground3": "#e37d80", "dangerForegroundInverted": "#d13438", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "dangerStroke1": "#d13438", + "defaultBackground": "#292929", + "defaultBorder": "#666666", + "defaultCheckedBackground": "#383838", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#3d3d3d", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#141414", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#3d3d3d", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#3d3d3d", + "defaultHoveredBorder": "#757575", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#d6d6d6", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", + "defaultPressedBackground": "#1f1f1f", + "defaultPressedBorder": "#6b6b6b", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#d6d6d6", + "disabledBackground": "#141414", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": "#2e6ac5", - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": "#2e6ac5", - "linkHovered": "#82c7ff", - "linkPressed": "#aec6eb", - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": "#6794d7", - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#ffffff", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#d6d6d6", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#d6d6d6", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#292929", + "inputBorder": "#666666", + "inputFocusBorderAlt": "#185abd", + "inputPlaceholderText": "#999999", + "inputText": "#ffffff", + "link": "#aec6eb", + "linkHovered": "#d2e0f4", + "linkPressed": "#2e6ac5", + "listHeaderBackgroundHovered": "#3d3d3d", + "listHeaderBackgroundPressed": "#1f1f1f", + "menuBackground": "#292929", + "menuDivider": "#525252", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#3d3d3d", + "menuItemBackgroundPressed": "#1f1f1f", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", "neutralBackground1": "#292929", "neutralBackground1Hover": "#3d3d3d", "neutralBackground1Pressed": "#1f1f1f", @@ -5415,37 +4795,46 @@ exports[`defaultFluentDarkTheme test 1`] = ` "neutralBackground5Pressed": "#050505", "neutralBackground5Selected": "#0f0f0f", "neutralBackground6": "#333333", + "neutralBackgroundCanvas": "#292929", + "neutralBackgroundDarkStatic": "#3d3d3d", "neutralBackgroundDisabled": "#141414", "neutralBackgroundInverted": "#ffffff", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#141414", "neutralForeground1": "#ffffff", "neutralForeground1Hover": "#ffffff", "neutralForeground1Pressed": "#ffffff", "neutralForeground1Selected": "#ffffff", "neutralForeground2": "#d6d6d6", - "neutralForeground2BrandHover": "#6794d7", + "neutralForeground2BrandHover": "#d2e0f4", "neutralForeground2BrandPressed": "#2e6ac5", - "neutralForeground2BrandSelected": "#6794d7", + "neutralForeground2BrandSelected": "#d2e0f4", "neutralForeground2Hover": "#ffffff", "neutralForeground2Pressed": "#ffffff", "neutralForeground2Selected": "#ffffff", "neutralForeground3": "#adadad", - "neutralForeground3BrandHover": "#6794d7", + "neutralForeground3BrandHover": "#d2e0f4", "neutralForeground3BrandPressed": "#2e6ac5", - "neutralForeground3BrandSelected": "#6794d7", + "neutralForeground3BrandSelected": "#d2e0f4", "neutralForeground3Hover": "#d6d6d6", "neutralForeground3Pressed": "#d6d6d6", "neutralForeground3Selected": "#d6d6d6", "neutralForeground4": "#999999", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#5c5c5c", - "neutralForegroundInverted": "#242424", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundDisabled1": "#5c5c5c", + "neutralForegroundDisabled2": "#5c5c5c", + "neutralForegroundInverted": "#000000", + "neutralForegroundInvertedLink": "#292929", + "neutralForegroundInvertedLinkHover": "#292929", + "neutralForegroundInvertedLinkPressed": "#292929", + "neutralForegroundInvertedLinkSelected": "#292929", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#333333", "neutralStencil2": "#575757", "neutralStroke1": "#666666", @@ -5457,8 +4846,10 @@ exports[`defaultFluentDarkTheme test 1`] = ` "neutralStrokeAccessible": "#adadad", "neutralStrokeAccessibleHover": "#bdbdbd", "neutralStrokeAccessiblePressed": "#b3b3b3", - "neutralStrokeAccessibleSelected": "#6794d7", + "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#424242", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", "outofofficeBackground1": "#3a1136", "outofofficeBackground2": "#6d2064", "outofofficeBackground3": "#c239b3", @@ -5468,18 +4859,31 @@ exports[`defaultFluentDarkTheme test 1`] = ` "outofofficeForeground1": "#da7ed0", "outofofficeForeground2": "#edbbe7", "outofofficeForeground3": "#d161c4", - "personaActivityGlow": "#2e6ac5", - "personaActivityRing": "#1b1a19", - "primaryButtonBackground": "#2e6ac5", - "primaryButtonBackgroundDisabled": "#252423", - "primaryButtonBackgroundHovered": "#6794d7", - "primaryButtonBackgroundPressed": "#aec6eb", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "personaActivityGlow": "#185abd", + "personaActivityRing": "#292929", + "presenceAvailable": "#54b054", + "presenceAway": "#feee66", + "presenceDnd": "#e37d80", + "presenceOof": "#da7ed0", + "primaryButtonBackground": "#185abd", + "primaryButtonBackgroundDisabled": "#141414", + "primaryButtonBackgroundHovered": "#1651aa", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#751d1f", + "redBackground3": "#d13438", + "redBorder1": "#d13438", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#f1bbbc", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#7a2101", "severeBackground3": "#da3b01", @@ -5489,13 +4893,14 @@ exports[`defaultFluentDarkTheme test 1`] = ` "severeForeground1": "#e9835e", "severeForeground2": "#f4bfab", "severeForeground3": "#e9835e", + "severeStroke1": "#da3b01", "strokeFocus1": "#000000", "strokeFocus2": "#ffffff", - "subText": "#a19f9d", + "subText": "#d6d6d6", "subtleBackground": "#00000000", - "subtleBackgroundHover": "#383838", - "subtleBackgroundPressed": "#2e2e2e", - "subtleBackgroundSelected": "#333333", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", "successBackground1": "#052505", "successBackground2": "#094509", "successBackground3": "#107c10", @@ -5506,6 +4911,7 @@ exports[`defaultFluentDarkTheme test 1`] = ` "successForeground2": "#9fd89f", "successForeground3": "#9fd89f", "successForegroundInverted": "#107c10", + "successStroke1": "#107c10", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -5513,7 +4919,7 @@ exports[`defaultFluentDarkTheme test 1`] = ` "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#292827", + "variantBorder": "#525252", "warningBackground1": "#4c4400", "warningBackground2": "#817400", "warningBackground3": "#fde300", @@ -5524,6 +4930,7 @@ exports[`defaultFluentDarkTheme test 1`] = ` "warningForeground2": "#fef7b2", "warningForeground3": "#fdea3d", "warningForegroundInverted": "#817400", + "warningStroke1": "#fde300", }, "components": {}, "host": { @@ -5708,13 +5115,13 @@ exports[`defaultFluentDarkTheme test 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -5728,138 +5135,153 @@ exports[`defaultFluentDarkTheme test 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -5874,63 +5296,76 @@ exports[`defaultFluentTheme test 1`] = ` { "colors": { "accentButtonBackground": "#185abd", - "actionLink": "#323130", + "actionLink": "#242424", "background": "#ffffff", - "bodyDivider": "#edebe9", + "bodyDivider": "#e0e0e0", "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", - "bodyTextChecked": "#000000", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#fafafa", + "bodyText": "#242424", + "bodyTextChecked": "#242424", "brandBackground": "#185abd", - "brandBackground2": "#eff6fc", - "brandBackgroundDisabled": undefined, + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#f0f0f0", "brandBackgroundHover": "#1651aa", - "brandBackgroundPressed": "#004578", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", + "brandBackgroundPressed": "#0e336a", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", + "brandBackgroundTint": "#d2e0f4", "brandForeground1": "#185abd", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, + "brandForeground1Disabled": "#bdbdbd", + "brandForeground1Pressed": "#185abd", + "brandForeground1Selected": "#185abd", "brandForeground2": "#1651aa", - "brandForegroundLink": "#1651aa", - "brandForegroundLinkHover": "#13458f", - "brandForegroundLinkPressed": "#004578", - "brandForegroundLinkSelected": "#1651aa", + "brandForegroundDisabled1": "#bdbdbd", + "brandForegroundDisabled2": "#bdbdbd", + "brandForegroundLink": "#185abd", + "brandForegroundLinkHover": "#1651aa", + "brandForegroundLinkPressed": "#0e336a", + "brandForegroundLinkSelected": "#13458f", + "brandForegroundTint": "#1651aa", "brandStroke1": "#185abd", - "brandStroke2": "#d2e0f4", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", "brandedBackground": "#185abd", - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#f0f0f0", + "buttonBackgroundHovered": "#f5f5f5", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", "checkboxBackground": "#185abd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", "compoundBrandBackground1": "#185abd", "compoundBrandBackground1Hover": "#1651aa", - "compoundBrandBackground1Pressed": "#13458f", + "compoundBrandBackground1Pressed": "#0e336a", "compoundBrandForeground1": "#185abd", "compoundBrandForeground1Hover": "#1651aa", - "compoundBrandForeground1Pressed": "#13458f", + "compoundBrandForeground1Pressed": "#0e336a", "compoundBrandStroke1": "#185abd", "compoundBrandStroke1Hover": "#1651aa", - "compoundBrandStroke1Pressed": "#13458f", + "compoundBrandStroke1Pressed": "#0e336a", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#f1bbbc", "dangerBackground3": "#d13438", @@ -5941,83 +5376,84 @@ exports[`defaultFluentTheme test 1`] = ` "dangerForeground2": "#751d1f", "dangerForeground3": "#d13438", "dangerForegroundInverted": "#dc5e62", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", + "dangerStroke1": "#f1bbbc", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#f5f5f5", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#f0f0f0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#f5f5f5", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#f5f5f5", + "defaultHoveredBorder": "#c7c7c7", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#424242", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#b3b3b3", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#424242", + "disabledBackground": "#f0f0f0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#242424", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#242424", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#616161", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#424242", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#424242", + "ghostSecondaryContent": "#616161", "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", + "inputBorder": "#d1d1d1", "inputFocusBorderAlt": "#185abd", - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", + "inputPlaceholderText": "#707070", + "inputText": "#242424", "link": "#185abd", - "linkHovered": "#004578", - "linkPressed": "#13458f", - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", + "linkHovered": "#1651aa", + "linkPressed": "#0e336a", + "listHeaderBackgroundHovered": "#f5f5f5", + "listHeaderBackgroundPressed": "#e0e0e0", "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": "#185abd", - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", + "menuDivider": "#e0e0e0", + "menuIcon": "#424242", + "menuItemBackgroundHovered": "#f5f5f5", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", "neutralBackground1": "#ffffff", "neutralBackground1Hover": "#f5f5f5", "neutralBackground1Pressed": "#e0e0e0", @@ -6039,37 +5475,46 @@ exports[`defaultFluentTheme test 1`] = ` "neutralBackground5Pressed": "#f0f0f0", "neutralBackground5Selected": "#fafafa", "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", "neutralBackgroundDisabled": "#f0f0f0", "neutralBackgroundInverted": "#616161", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", "neutralForeground1": "#242424", "neutralForeground1Hover": "#242424", "neutralForeground1Pressed": "#242424", "neutralForeground1Selected": "#242424", "neutralForeground2": "#424242", - "neutralForeground2BrandHover": "#185abd", - "neutralForeground2BrandPressed": "#1651aa", - "neutralForeground2BrandSelected": "#185abd", + "neutralForeground2BrandHover": "#1651aa", + "neutralForeground2BrandPressed": "#0e336a", + "neutralForeground2BrandSelected": "#13458f", "neutralForeground2Hover": "#242424", "neutralForeground2Pressed": "#242424", "neutralForeground2Selected": "#242424", "neutralForeground3": "#616161", - "neutralForeground3BrandHover": "#185abd", - "neutralForeground3BrandPressed": "#1651aa", - "neutralForeground3BrandSelected": "#185abd", + "neutralForeground3BrandHover": "#1651aa", + "neutralForeground3BrandPressed": "#0e336a", + "neutralForeground3BrandSelected": "#13458f", "neutralForeground3Hover": "#424242", "neutralForeground3Pressed": "#424242", "neutralForeground3Selected": "#424242", "neutralForeground4": "#707070", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#bdbdbd", + "neutralForegroundDisabled1": "#bdbdbd", + "neutralForegroundDisabled2": "#bdbdbd", "neutralForegroundInverted": "#ffffff", "neutralForegroundInvertedLink": "#ffffff", "neutralForegroundInvertedLinkHover": "#ffffff", "neutralForegroundInvertedLinkPressed": "#ffffff", "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", "neutralStroke1": "#d1d1d1", @@ -6083,6 +5528,8 @@ exports[`defaultFluentTheme test 1`] = ` "neutralStrokeAccessiblePressed": "#4d4d4d", "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#e0e0e0", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", "outofofficeBackground1": "#fdf5fc", "outofofficeBackground2": "#edbbe7", "outofofficeBackground3": "#c239b3", @@ -6094,16 +5541,29 @@ exports[`defaultFluentTheme test 1`] = ` "outofofficeForeground3": "#c239b3", "personaActivityGlow": "#185abd", "personaActivityRing": "#ffffff", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", "primaryButtonBackground": "#185abd", - "primaryButtonBackgroundDisabled": "#f3f2f1", + "primaryButtonBackgroundDisabled": "#f0f0f0", "primaryButtonBackgroundHovered": "#1651aa", - "primaryButtonBackgroundPressed": "#13458f", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", + "primaryButtonTextDisabled": "#bdbdbd", "primaryButtonTextHovered": "#ffffff", "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#f4bfab", "severeBackground3": "#da3b01", @@ -6113,9 +5573,10 @@ exports[`defaultFluentTheme test 1`] = ` "severeForeground1": "#c43501", "severeForeground2": "#7a2101", "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", "strokeFocus1": "#ffffff", "strokeFocus2": "#000000", - "subText": "#605e5c", + "subText": "#424242", "subtleBackground": "#00000000", "subtleBackgroundHover": "#f5f5f5", "subtleBackgroundPressed": "#e0e0e0", @@ -6130,6 +5591,7 @@ exports[`defaultFluentTheme test 1`] = ` "successForeground2": "#094509", "successForeground3": "#107c10", "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -6137,7 +5599,7 @@ exports[`defaultFluentTheme test 1`] = ` "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#edebe9", + "variantBorder": "#e0e0e0", "warningBackground1": "#fffef5", "warningBackground2": "#fef7b2", "warningBackground3": "#fde300", @@ -6148,6 +5610,7 @@ exports[`defaultFluentTheme test 1`] = ` "warningForeground2": "#817400", "warningForeground3": "#fde300", "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", }, "components": {}, "host": { @@ -6332,13 +5795,13 @@ exports[`defaultFluentTheme test 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -6352,138 +5815,153 @@ exports[`defaultFluentTheme test 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { diff --git a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.android.ts.snap b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.android.ts.snap index f14380d03c2..78048a0794c 100644 --- a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.android.ts.snap +++ b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.android.ts.snap @@ -3,157 +3,183 @@ exports[`defaultFluentDarkTheme 1`] = ` { "colors": { - "accentButtonBackground": "#0c3b5e", - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "accentButtonBackground": "#479ef5", + "actionLink": "#ffffff", + "background": "#000000", + "bodyDivider": "#3d3d3d", + "bodyFrameBackground": "#000000", + "bodyFrameDivider": "#3d3d3d", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", "brandBackground": "#479ef5", - "brandBackground2": undefined, - "brandBackground2Pressed": undefined, - "brandBackground2Selected": undefined, - "brandBackground3": undefined, + "brandBackground2": "#479ef5", + "brandBackground2Pressed": "#96c6fa", + "brandBackground2Selected": "#77b7f7", + "brandBackground3": "#479ef5", "brandBackgroundDisabled": "#0c3b5e", + "brandBackgroundHover": "#479ef5", "brandBackgroundInverted": "#ffffff", "brandBackgroundInvertedDisabled": "#adadad", "brandBackgroundPressed": "#96c6fa", "brandBackgroundSelected": "#77b7f7", + "brandBackgroundStatic": "#479ef5", "brandBackgroundTint": "#0c3b5e", "brandForeground1": "#479ef5", + "brandForeground1Disabled": "#2886de", "brandForeground1Pressed": "#96c6fa", "brandForeground1Selected": "#77b7f7", + "brandForeground2": "#479ef5", "brandForegroundDisabled1": "#2886de", "brandForegroundDisabled2": "#0c3b5e", + "brandForegroundLink": "#479ef5", + "brandForegroundLinkHover": "#479ef5", + "brandForegroundLinkPressed": "#96c6fa", + "brandForegroundLinkSelected": "#77b7f7", "brandForegroundTint": "#96c6fa", "brandStroke1": "#479ef5", "brandStroke1Pressed": "#96c6fa", "brandStroke1Selected": "#77b7f7", - "brandedBackground": "#2886de", - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandStroke2": "#479ef5", + "brandStrokeTint": "#479ef5", + "brandedBackground": "#479ef5", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#000000", + "buttonBackground": "#000000", + "buttonBackgroundChecked": "#242424", + "buttonBackgroundDisabled": "#525252", + "buttonBackgroundHovered": "#000000", + "buttonBackgroundPressed": "#2e2e2e", + "buttonBorder": "#4d4d4d", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": "#2886de", - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#479ef5", + "checkboxBackgroundDisabled": "#525252", + "checkboxBorderColor": "#9e9e9e", + "checkmarkColor": "#000000", + "compoundBrandBackground1": "#479ef5", + "compoundBrandBackground1Hover": "#479ef5", + "compoundBrandBackground1Pressed": "#96c6fa", + "compoundBrandForeground1": "#479ef5", + "compoundBrandForeground1Hover": "#479ef5", + "compoundBrandForeground1Pressed": "#96c6fa", + "compoundBrandStroke1": "#479ef5", + "compoundBrandStroke1Hover": "#479ef5", + "compoundBrandStroke1Pressed": "#96c6fa", "dangerBackground1": "#3f1011", "dangerBackground2": "#bc2f32", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#dc5e62", + "dangerBorderActive": "#e37d80", "dangerForeground1": "#e37d80", "dangerForeground2": "#e37d80", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "dangerForeground3": "#e37d80", + "dangerForegroundInverted": "#d13438", + "dangerStroke1": "#dc5e62", + "defaultBackground": "#000000", + "defaultBorder": "#4d4d4d", + "defaultCheckedBackground": "#242424", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#000000", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#525252", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#000000", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#000000", + "defaultHoveredBorder": "#4d4d4d", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#adadad", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", - "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": "#2886de", - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": "#2886de", - "linkHovered": "#62abf5", - "linkPressed": "#479ef5", - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": "#479ef5", - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", + "defaultPressedBackground": "#2e2e2e", + "defaultPressedBorder": "#4d4d4d", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#adadad", + "disabledBackground": "#525252", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", + "ghostCheckedContent": "#d6d6d6", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#d6d6d6", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#adadad", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#adadad", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#000000", + "inputBorder": "#4d4d4d", + "inputFocusBorderAlt": "#479ef5", + "inputPlaceholderText": "#adadad", + "inputText": "#ffffff", + "link": "#479ef5", + "linkHovered": "#479ef5", + "linkPressed": "#96c6fa", + "listHeaderBackgroundHovered": "#000000", + "listHeaderBackgroundPressed": "#2e2e2e", + "menuBackground": "#000000", + "menuDivider": "#3d3d3d", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#000000", + "menuItemBackgroundPressed": "#2e2e2e", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", "neutralBackground1": "#000000", - "neutralBackground1Hover": undefined, + "neutralBackground1Hover": "#000000", "neutralBackground1Pressed": "#2e2e2e", "neutralBackground1Selected": "#242424", "neutralBackground2": "#1f1f1f", - "neutralBackground2Hover": undefined, + "neutralBackground2Hover": "#1f1f1f", "neutralBackground2Pressed": "#4d4d4d", "neutralBackground2Selected": "#424242", "neutralBackground3": "#292929", - "neutralBackground3Hover": undefined, + "neutralBackground3Hover": "#292929", "neutralBackground3Pressed": "#575757", "neutralBackground3Selected": "#4d4d4d", "neutralBackground4": "#333333", - "neutralBackground4Hover": undefined, + "neutralBackground4Hover": "#333333", "neutralBackground4Pressed": "#616161", "neutralBackground4Selected": "#575757", "neutralBackground5": "#3d3d3d", - "neutralBackground5Hover": undefined, + "neutralBackground5Hover": "#3d3d3d", "neutralBackground5Pressed": "#6b6b6b", "neutralBackground5Selected": "#616161", "neutralBackground6": "#5c5c5c", @@ -164,71 +190,135 @@ exports[`defaultFluentDarkTheme 1`] = ` "neutralBackgroundLightStatic": "#ffffff", "neutralBackgroundLightStaticDisabled": "#adadad", "neutralForeground1": "#ffffff", - "neutralForeground1Hover": undefined, - "neutralForeground1Pressed": undefined, - "neutralForeground1Selected": undefined, + "neutralForeground1Hover": "#ffffff", + "neutralForeground1Pressed": "#ffffff", + "neutralForeground1Selected": "#ffffff", "neutralForeground2": "#d6d6d6", - "neutralForeground2BrandHover": undefined, - "neutralForeground2BrandPressed": undefined, - "neutralForeground2BrandSelected": undefined, - "neutralForeground2Hover": undefined, - "neutralForeground2Pressed": undefined, - "neutralForeground2Selected": undefined, + "neutralForeground2BrandHover": "#d6d6d6", + "neutralForeground2BrandPressed": "#d6d6d6", + "neutralForeground2BrandSelected": "#d6d6d6", + "neutralForeground2Hover": "#d6d6d6", + "neutralForeground2Pressed": "#d6d6d6", + "neutralForeground2Selected": "#d6d6d6", "neutralForeground3": "#adadad", - "neutralForeground3BrandHover": undefined, - "neutralForeground3BrandPressed": undefined, - "neutralForeground3BrandSelected": undefined, - "neutralForeground3Hover": undefined, - "neutralForeground3Pressed": undefined, - "neutralForeground3Selected": undefined, + "neutralForeground3BrandHover": "#adadad", + "neutralForeground3BrandPressed": "#adadad", + "neutralForeground3BrandSelected": "#adadad", + "neutralForeground3Hover": "#adadad", + "neutralForeground3Pressed": "#adadad", + "neutralForeground3Selected": "#adadad", + "neutralForeground4": "#adadad", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#5c5c5c", "neutralForegroundDisabled1": "#5c5c5c", "neutralForegroundDisabled2": "#2e2e2e", "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#000000", + "neutralForegroundInvertedLinkPressed": "#000000", + "neutralForegroundInvertedLinkSelected": "#000000", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#000000", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", "neutralForegroundOnColor": "#000000", "neutralStencil1": "#575757", "neutralStencil2": "#333333", "neutralStroke1": "#4d4d4d", - "neutralStroke1Hover": undefined, - "neutralStroke1Pressed": undefined, - "neutralStroke1Selected": undefined, + "neutralStroke1Hover": "#4d4d4d", + "neutralStroke1Pressed": "#4d4d4d", + "neutralStroke1Selected": "#4d4d4d", "neutralStroke2": "#3d3d3d", + "neutralStroke3": "#3d3d3d", "neutralStrokeAccessible": "#9e9e9e", - "neutralStrokeAccessibleHover": undefined, - "neutralStrokeAccessiblePressed": undefined, - "neutralStrokeAccessibleSelected": undefined, + "neutralStrokeAccessibleHover": "#9e9e9e", + "neutralStrokeAccessiblePressed": "#9e9e9e", + "neutralStrokeAccessibleSelected": "#9e9e9e", "neutralStrokeDisabled": "#424242", "neutralStrokeFocus1": "#000000", "neutralStrokeFocus2": "#ffffff", - "personaActivityGlow": "#2886de", - "personaActivityRing": "#1b1a19", + "outofofficeBackground1": "#3a1136", + "outofofficeBackground2": "#6d2064", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#c239b3", + "outofofficeBorder2": "#d161c4", + "outofofficeBorderActive": "#da7ed0", + "outofofficeForeground1": "#da7ed0", + "outofofficeForeground2": "#edbbe7", + "outofofficeForeground3": "#d161c4", + "personaActivityGlow": "#479ef5", + "personaActivityRing": "#000000", "presenceAvailable": "#3db838", "presenceAway": "#eaa300", "presenceDnd": "#d7494c", "presenceOof": "#d161c4", - "primaryButtonBackground": "#2886de", - "primaryButtonBackgroundDisabled": "#252423", + "primaryButtonBackground": "#479ef5", + "primaryButtonBackgroundDisabled": "#525252", "primaryButtonBackgroundHovered": "#479ef5", - "primaryButtonBackgroundPressed": "#479ef5", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "primaryButtonBackgroundPressed": "#96c6fa", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#000000", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#bc2f32", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#e37d80", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#c43501", + "severeBackground3": "#da3b01", + "severeBorder1": "#e36537", + "severeBorder2": "#e9835e", + "severeBorderActive": "#e9835e", "severeForeground1": "#e9835e", "severeForeground2": "#e9835e", - "subText": "#a19f9d", + "severeForeground3": "#e9835e", + "severeStroke1": "#e36537", + "strokeFocus1": "#000000", + "strokeFocus2": "#ffffff", + "subText": "#d6d6d6", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", "successBackground1": "#052505", "successBackground2": "#0e700e", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#9fd89f", + "successBorderActive": "#54b054", "successForeground1": "#54b054", "successForeground2": "#54b054", - "variantBorder": "#292827", + "successForeground3": "#9fd89f", + "successForegroundInverted": "#107c10", + "successStroke1": "#359b35", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#3d3d3d", "warningBackground1": "#4c4400", "warningBackground2": "#e4cc00", + "warningBackground3": "#fde300", + "warningBorder1": "#c0ad00", + "warningBorder2": "#fdea3d", + "warningBorderActive": "#feee66", "warningForeground1": "#feee66", "warningForeground2": "#feee66", + "warningForeground3": "#fdea3d", + "warningForegroundInverted": "#817400", + "warningStroke1": "#c0ad00", }, "components": {}, "host": { @@ -413,13 +503,13 @@ exports[`defaultFluentDarkTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "Segoe UI", - "sansSerif": "System", - "secondary": "Segoe UI", - "serif": "System", + "cursive": "Roboto", + "monospace": "Roboto", + "numeric": "Roboto", + "primary": "Roboto", + "sansSerif": "Roboto", + "secondary": "Roboto", + "serif": "Roboto", }, "sizes": { "body": 14, @@ -432,139 +522,214 @@ exports[`defaultFluentDarkTheme 1`] = ` }, "variants": { "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", }, "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", }, "body2": { - "face": "primary", - "size": "body", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", }, "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", }, "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", }, "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", }, "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", }, "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "500", + }, + "caption2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", }, "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", }, "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", }, "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", }, "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", }, "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", }, "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", }, "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", }, "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", }, "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", }, "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", }, "secondaryStandard": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", }, "subheaderSemibold": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", }, "subheaderStandard": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, "subtitle1": { - "face": "primary", - "size": "header", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", }, "subtitle1Strong": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", }, "subtitle2": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, "subtitle2Strong": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", }, "title1": { - "face": "primary", - "size": "hero", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", }, "title1Strong": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", + }, + "title2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", + }, + "title3": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, }, "weights": { @@ -575,160 +740,186 @@ exports[`defaultFluentDarkTheme 1`] = ` } `; -exports[`defaultFluentHighConstrastTheme 1`] = ` +exports[`defaultFluentTheme 1`] = ` { "colors": { - "accentButtonBackground": "#000000", - "actionLink": "#ffff00", - "background": "#000000", - "bodyDivider": "#ffffff", - "bodyFrameBackground": "#000000", - "bodyFrameDivider": "#000000", - "bodyStandoutBackground": "#000000", - "bodyText": "#ffffff", - "bodyTextChecked": "#000000", + "accentButtonBackground": "#0f6cbd", + "actionLink": "#242424", + "background": "#ffffff", + "bodyDivider": "#e0e0e0", + "bodyFrameBackground": "#ffffff", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#ffffff", + "bodyText": "#242424", + "bodyTextChecked": "#242424", "brandBackground": "#0f6cbd", "brandBackground2": "#115ea3", "brandBackground2Pressed": "#0c3b5e", "brandBackground2Selected": "#0e4775", "brandBackground3": "#0f548c", "brandBackgroundDisabled": "#b4d6fa", + "brandBackgroundHover": "#0f6cbd", "brandBackgroundInverted": "#ffffff", "brandBackgroundInvertedDisabled": "#ffffff", "brandBackgroundPressed": "#0e4775", "brandBackgroundSelected": "#0f548c", + "brandBackgroundStatic": "#0f6cbd", "brandBackgroundTint": "#cfe4fa", "brandForeground1": "#0f6cbd", + "brandForeground1Disabled": "#2886de", "brandForeground1Pressed": "#0e4775", "brandForeground1Selected": "#0f548c", + "brandForeground2": "#0f6cbd", "brandForegroundDisabled1": "#2886de", "brandForegroundDisabled2": "#b4d6fa", + "brandForegroundLink": "#0f6cbd", + "brandForegroundLinkHover": "#0f6cbd", + "brandForegroundLinkPressed": "#0e4775", + "brandForegroundLinkSelected": "#0f548c", "brandForegroundTint": "#0f548c", "brandStroke1": "#0f6cbd", "brandStroke1Pressed": "#0e4775", "brandStroke1Selected": "#0f548c", - "brandedBackground": "#000000", - "brandedDisabledBorder": "#3ff23f", + "brandStroke2": "#2886de", + "brandStrokeTint": "#2886de", + "brandedBackground": "#0f6cbd", + "brandedDisabledBorder": "#00000000", "brandedFocusedSecondaryContent": "#ffffff", - "brandedHoveredSecondaryContent": "#000000", - "brandedPressedSecondaryContent": "#000000", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", "brandedSecondaryContent": "#ffffff", - "buttonBackground": "#000000", - "buttonBackgroundChecked": "#1aebff", - "buttonBackgroundDisabled": "#000000", - "buttonBackgroundHovered": "#1aebff", - "buttonBackgroundPressed": "#1aebff", - "buttonBorder": "#ffffff", - "buttonBorderDisabled": "#3ff23f", - "buttonBorderFocused": "#ffffff", - "buttonText": "#ffffff", - "buttonTextChecked": "#000000", - "buttonTextDisabled": "#3ff23f", - "buttonTextHovered": "#000000", - "buttonTextPressed": "#000000", - "checkboxBackground": "#000000", - "checkboxBackgroundDisabled": "#000000", - "checkboxBorderColor": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#e0e0e0", + "buttonBackgroundHovered": "#ffffff", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", + "checkboxBackground": "#0f6cbd", + "checkboxBackgroundDisabled": "#e0e0e0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#0f6cbd", + "compoundBrandBackground1Hover": "#0f6cbd", + "compoundBrandBackground1Pressed": "#0e4775", + "compoundBrandForeground1": "#0f6cbd", + "compoundBrandForeground1Hover": "#0f6cbd", + "compoundBrandForeground1Pressed": "#0e4775", + "compoundBrandStroke1": "#0f6cbd", + "compoundBrandStroke1Hover": "#0f6cbd", + "compoundBrandStroke1Pressed": "#0e4775", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#d13438", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#d13438", + "dangerBorderActive": "#d13438", "dangerForeground1": "#bc2f32", "dangerForeground2": "#d13438", - "defaultBackground": "#000000", - "defaultBorder": "#ffffff", - "defaultCheckedBackground": "#1aebff", - "defaultCheckedContent": "#000000", - "defaultCheckedHoveredBackground": "#1aebff", - "defaultCheckedHoveredContent": "#000000", - "defaultContent": "#ffffff", - "defaultDisabledBackground": "#000000", - "defaultDisabledBorder": "#3ff23f", - "defaultDisabledContent": "#3ff23f", - "defaultDisabledIcon": "#3ff23f", - "defaultFocusedBackground": "#000000", - "defaultFocusedBorder": "#ffffff", - "defaultFocusedContent": "#ffffff", - "defaultFocusedIcon": "#ffffff", - "defaultHoveredBackground": "#1aebff", - "defaultHoveredBorder": "#1aebff", - "defaultHoveredContent": "#000000", - "defaultHoveredIcon": "#000000", - "defaultHoveredSecondaryContent": "#000000", - "defaultIcon": "#ffffff", - "defaultPressedBackground": "#1aebff", - "defaultPressedBorder": "#1aebff", - "defaultPressedContent": "#000000", - "defaultPressedIcon": "#000000", - "defaultPressedSecondaryContent": "#000000", - "disabledBackground": "#000000", - "disabledBodyText": "#3ff23f", - "disabledText": "#3ff23f", - "errorText": "#ffffff", - "focusBorder": "#ffffff", - "ghostBackground": "#000000", - "ghostBorder": "#000000", - "ghostCheckedBackground": "#1aebff", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#1aebff", - "ghostCheckedHoveredBorder": "#000000", - "ghostCheckedHoveredContent": "#000000", - "ghostContent": "#ffffff", - "ghostDisabledBackground": "#000000", - "ghostDisabledBorder": "#000000", - "ghostDisabledContent": "#3ff23f", - "ghostDisabledIcon": "#3ff23f", - "ghostFocusedBackground": "#000000", - "ghostFocusedBorder": "#ffffff", - "ghostFocusedContent": "#ffffff", - "ghostFocusedIcon": "#ffffff", - "ghostFocusedSecondaryContent": "#ffffff", - "ghostHoveredBackground": "#1aebff", - "ghostHoveredBorder": "#1aebff", - "ghostHoveredContent": "#000000", - "ghostHoveredIcon": "#000000", - "ghostHoveredSecondaryContent": "#000000", - "ghostIcon": "#ffffff", - "ghostPressedBackground": "#1aebff", - "ghostPressedBorder": "#1aebff", - "ghostPressedContent": "#000000", - "ghostPressedIcon": "#000000", - "ghostPressedSecondaryContent": "#000000", - "ghostSecondaryContent": "#ffffff", - "inputBackground": "#000000", - "inputBorder": "#ffffff", - "inputFocusBorderAlt": "#ffffff", - "inputPlaceholderText": "#ffffff", - "inputText": "#ffffff", - "link": "#ffff00", - "linkHovered": "#ffffff", - "linkPressed": "#ffffff", - "listHeaderBackgroundHovered": "#1aebff", - "listHeaderBackgroundPressed": "#1aebff", - "menuBackground": "#000000", - "menuDivider": "#ffffff", - "menuIcon": "#ffffff", - "menuItemBackgroundHovered": "#1aebff", - "menuItemBackgroundPressed": "#1aebff", - "menuItemText": "#ffffff", - "menuItemTextHovered": "#000000", + "dangerForeground3": "#d13438", + "dangerForegroundInverted": "#dc5e62", + "dangerStroke1": "#dc5e62", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#ffffff", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#e0e0e0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#ffffff", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#ffffff", + "defaultHoveredBorder": "#d1d1d1", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#808080", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#d1d1d1", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#808080", + "disabledBackground": "#e0e0e0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#616161", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#616161", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#808080", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#808080", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#808080", + "ghostSecondaryContent": "#808080", + "inputBackground": "#ffffff", + "inputBorder": "#d1d1d1", + "inputFocusBorderAlt": "#0f6cbd", + "inputPlaceholderText": "#808080", + "inputText": "#242424", + "link": "#0f6cbd", + "linkHovered": "#0f6cbd", + "linkPressed": "#0e4775", + "listHeaderBackgroundHovered": "#ffffff", + "listHeaderBackgroundPressed": "#e0e0e0", + "menuBackground": "#ffffff", + "menuDivider": "#e0e0e0", + "menuIcon": "#616161", + "menuItemBackgroundHovered": "#ffffff", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", "neutralBackground1": "#ffffff", - "neutralBackground1Hover": undefined, + "neutralBackground1Hover": "#ffffff", "neutralBackground1Pressed": "#e0e0e0", "neutralBackground1Selected": "#ebebeb", "neutralBackground2": "#ffffff", - "neutralBackground2Hover": undefined, + "neutralBackground2Hover": "#ffffff", "neutralBackground2Pressed": "#e0e0e0", "neutralBackground2Selected": "#ebebeb", "neutralBackground3": "#ffffff", - "neutralBackground3Hover": undefined, + "neutralBackground3Hover": "#ffffff", "neutralBackground3Pressed": "#e0e0e0", "neutralBackground3Selected": "#ebebeb", "neutralBackground4": "#fafafa", - "neutralBackground4Hover": undefined, + "neutralBackground4Hover": "#fafafa", "neutralBackground4Pressed": "#dbdbdb", "neutralBackground4Selected": "#e6e6e6", "neutralBackground5": "#f0f0f0", - "neutralBackground5Hover": undefined, + "neutralBackground5Hover": "#f0f0f0", "neutralBackground5Pressed": "#d1d1d1", "neutralBackground5Selected": "#dbdbdb", "neutralBackground6": "#d1d1d1", @@ -739,71 +930,875 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` "neutralBackgroundLightStatic": "#ffffff", "neutralBackgroundLightStaticDisabled": "#ffffff", "neutralForeground1": "#242424", - "neutralForeground1Hover": undefined, - "neutralForeground1Pressed": undefined, - "neutralForeground1Selected": undefined, + "neutralForeground1Hover": "#242424", + "neutralForeground1Pressed": "#242424", + "neutralForeground1Selected": "#242424", "neutralForeground2": "#616161", - "neutralForeground2BrandHover": undefined, - "neutralForeground2BrandPressed": undefined, - "neutralForeground2BrandSelected": undefined, - "neutralForeground2Hover": undefined, - "neutralForeground2Pressed": undefined, - "neutralForeground2Selected": undefined, + "neutralForeground2BrandHover": "#616161", + "neutralForeground2BrandPressed": "#616161", + "neutralForeground2BrandSelected": "#616161", + "neutralForeground2Hover": "#616161", + "neutralForeground2Pressed": "#616161", + "neutralForeground2Selected": "#616161", "neutralForeground3": "#808080", - "neutralForeground3BrandHover": undefined, - "neutralForeground3BrandPressed": undefined, - "neutralForeground3BrandSelected": undefined, - "neutralForeground3Hover": undefined, - "neutralForeground3Pressed": undefined, - "neutralForeground3Selected": undefined, + "neutralForeground3BrandHover": "#808080", + "neutralForeground3BrandPressed": "#808080", + "neutralForeground3BrandSelected": "#808080", + "neutralForeground3Hover": "#808080", + "neutralForeground3Pressed": "#808080", + "neutralForeground3Selected": "#808080", + "neutralForeground4": "#808080", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#bdbdbd", "neutralForegroundDisabled1": "#bdbdbd", "neutralForegroundDisabled2": "#ffffff", "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#ffffff", + "neutralForegroundInvertedLinkPressed": "#ffffff", + "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", "neutralStroke1": "#d1d1d1", - "neutralStroke1Hover": undefined, - "neutralStroke1Pressed": undefined, - "neutralStroke1Selected": undefined, + "neutralStroke1Hover": "#d1d1d1", + "neutralStroke1Pressed": "#d1d1d1", + "neutralStroke1Selected": "#d1d1d1", "neutralStroke2": "#e0e0e0", + "neutralStroke3": "#e0e0e0", "neutralStrokeAccessible": "#616161", - "neutralStrokeAccessibleHover": undefined, - "neutralStrokeAccessiblePressed": undefined, - "neutralStrokeAccessibleSelected": undefined, + "neutralStrokeAccessibleHover": "#616161", + "neutralStrokeAccessiblePressed": "#616161", + "neutralStrokeAccessibleSelected": "#616161", "neutralStrokeDisabled": "#e0e0e0", "neutralStrokeFocus1": "#ffffff", "neutralStrokeFocus2": "#000000", - "personaActivityGlow": "transparent", + "outofofficeBackground1": "#fdf5fc", + "outofofficeBackground2": "#edbbe7", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#edbbe7", + "outofofficeBorder2": "#c239b3", + "outofofficeBorderActive": "#c239b3", + "outofofficeForeground1": "#af33a1", + "outofofficeForeground2": "#6d2064", + "outofofficeForeground3": "#c239b3", + "personaActivityGlow": "#0f6cbd", "personaActivityRing": "#ffffff", "presenceAvailable": "#13a10e", "presenceAway": "#eaa300", "presenceDnd": "#d13438", "presenceOof": "#c239b3", - "primaryButtonBackground": "#000000", - "primaryButtonBackgroundDisabled": "#000000", - "primaryButtonBackgroundHovered": "#1aebff", - "primaryButtonBackgroundPressed": "#1aebff", - "primaryButtonBorder": "#ffffff", - "primaryButtonBorderFocused": "#ffffff", + "primaryButtonBackground": "#0f6cbd", + "primaryButtonBackgroundDisabled": "#e0e0e0", + "primaryButtonBackgroundHovered": "#0f6cbd", + "primaryButtonBackgroundPressed": "#0e4775", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#3ff23f", - "primaryButtonTextHovered": "#000000", - "primaryButtonTextPressed": "#000000", + "primaryButtonTextDisabled": "#bdbdbd", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#d13438", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#d13438", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#da3b01", + "severeBackground3": "#da3b01", + "severeBorder1": "#de501c", + "severeBorder2": "#da3b01", + "severeBorderActive": "#da3b01", "severeForeground1": "#c43501", "severeForeground2": "#c43501", - "subText": "#ffffff", + "severeForeground3": "#da3b01", + "severeStroke1": "#de501c", + "strokeFocus1": "#ffffff", + "strokeFocus2": "#000000", + "subText": "#616161", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#f5f5f5", + "subtleBackgroundPressed": "#e0e0e0", + "subtleBackgroundSelected": "#ebebeb", "successBackground1": "#f1faf1", "successBackground2": "#107c10", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#107c10", + "successBorderActive": "#107c10", "successForeground1": "#0e700e", "successForeground2": "#107c10", - "variantBorder": "#ffffff", + "successForeground3": "#107c10", + "successForegroundInverted": "#359b35", + "successStroke1": "#359b35", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#e0e0e0", "warningBackground1": "#fffef5", "warningBackground2": "#fde300", + "warningBackground3": "#fde300", + "warningBorder1": "#817400", + "warningBorder2": "#fde300", + "warningBorderActive": "#fde300", "warningForeground1": "#817400", "warningForeground2": "#817400", + "warningForeground3": "#fde300", + "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#817400", + }, + "components": {}, + "host": { + "appearance": "light", + }, + "shadows": { + "shadow16": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000024", + "x": 0, + "y": 8, + }, + }, + "shadow16brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000040", + "x": 0, + "y": 8, + }, + }, + "shadow2": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000024", + "x": 0, + "y": 1, + }, + }, + "shadow28": { + "ambient": { + "blur": 8, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000024", + "x": 0, + "y": 14, + }, + }, + "shadow28brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000040", + "x": 0, + "y": 14, + }, + }, + "shadow2brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000040", + "x": 0, + "y": 1, + }, + }, + "shadow4": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000024", + "x": 0, + "y": 2, + }, + }, + "shadow4brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000040", + "x": 0, + "y": 2, + }, + }, + "shadow64": { + "ambient": { + "blur": 8, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000024", + "x": 0, + "y": 32, + }, + }, + "shadow64brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000040", + "x": 0, + "y": 32, + }, + }, + "shadow8": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000024", + "x": 0, + "y": 4, + }, + }, + "shadow8brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000040", + "x": 0, + "y": 4, + }, + }, + }, + "spacing": { + "l1": "20px", + "l2": "32px", + "m": "16px", + "s1": "8px", + "s2": "4px", + }, + "typography": { + "families": { + "cursive": "Roboto", + "monospace": "Roboto", + "numeric": "Roboto", + "primary": "Roboto", + "sansSerif": "Roboto", + "secondary": "Roboto", + "serif": "Roboto", + }, + "sizes": { + "body": 14, + "caption": 12, + "header": 18, + "hero": 24, + "heroLarge": 60, + "secondary": 13, + "subheader": 16, + }, + "variants": { + "body1": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", + }, + "body1Strong": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", + }, + "body2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", + }, + "body2Strong": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", + }, + "bodySemibold": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", + }, + "bodyStandard": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", + }, + "caption1": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", + }, + "caption1Strong": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "500", + }, + "caption2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", + }, + "captionStandard": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", + }, + "display": { + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", + }, + "headerSemibold": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", + }, + "headerStandard": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", + }, + "heroLargeSemibold": { + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", + }, + "heroLargeStandard": { + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", + }, + "heroSemibold": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", + }, + "heroStandard": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", + }, + "largeTitle": { + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", + }, + "secondarySemibold": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", + }, + "secondaryStandard": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", + }, + "subheaderSemibold": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", + }, + "subheaderStandard": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", + }, + "subtitle1": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", + }, + "subtitle1Strong": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", + }, + "subtitle2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", + }, + "subtitle2Strong": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", + }, + "title1": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", + }, + "title1Strong": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", + }, + "title2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", + }, + "title3": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", + }, + }, + "weights": { + "regular": "400", + "semiBold": "600", + }, + }, +} +`; + +exports[`high contrast dark theme 1`] = ` +{ + "colors": { + "accentButtonBackground": "#479ef5", + "actionLink": "#ffffff", + "background": "#000000", + "bodyDivider": "#3d3d3d", + "bodyFrameBackground": "#000000", + "bodyFrameDivider": "#3d3d3d", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", + "bodyTextChecked": "#ffffff", + "brandBackground": "#479ef5", + "brandBackground2": "#479ef5", + "brandBackground2Pressed": "#96c6fa", + "brandBackground2Selected": "#77b7f7", + "brandBackground3": "#479ef5", + "brandBackgroundDisabled": "#0c3b5e", + "brandBackgroundHover": "#479ef5", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#adadad", + "brandBackgroundPressed": "#96c6fa", + "brandBackgroundSelected": "#77b7f7", + "brandBackgroundStatic": "#479ef5", + "brandBackgroundTint": "#0c3b5e", + "brandForeground1": "#479ef5", + "brandForeground1Disabled": "#2886de", + "brandForeground1Pressed": "#96c6fa", + "brandForeground1Selected": "#77b7f7", + "brandForeground2": "#479ef5", + "brandForegroundDisabled1": "#2886de", + "brandForegroundDisabled2": "#0c3b5e", + "brandForegroundLink": "#479ef5", + "brandForegroundLinkHover": "#479ef5", + "brandForegroundLinkPressed": "#96c6fa", + "brandForegroundLinkSelected": "#77b7f7", + "brandForegroundTint": "#96c6fa", + "brandStroke1": "#479ef5", + "brandStroke1Pressed": "#96c6fa", + "brandStroke1Selected": "#77b7f7", + "brandStroke2": "#479ef5", + "brandStrokeTint": "#479ef5", + "brandedBackground": "#479ef5", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#000000", + "buttonBackground": "#000000", + "buttonBackgroundChecked": "#242424", + "buttonBackgroundDisabled": "#525252", + "buttonBackgroundHovered": "#000000", + "buttonBackgroundPressed": "#2e2e2e", + "buttonBorder": "#4d4d4d", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", + "buttonText": "#ffffff", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#479ef5", + "checkboxBackgroundDisabled": "#525252", + "checkboxBorderColor": "#9e9e9e", + "checkmarkColor": "#000000", + "compoundBrandBackground1": "#479ef5", + "compoundBrandBackground1Hover": "#479ef5", + "compoundBrandBackground1Pressed": "#96c6fa", + "compoundBrandForeground1": "#479ef5", + "compoundBrandForeground1Hover": "#479ef5", + "compoundBrandForeground1Pressed": "#96c6fa", + "compoundBrandStroke1": "#479ef5", + "compoundBrandStroke1Hover": "#479ef5", + "compoundBrandStroke1Pressed": "#96c6fa", + "dangerBackground1": "#3f1011", + "dangerBackground2": "#bc2f32", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#dc5e62", + "dangerBorderActive": "#e37d80", + "dangerForeground1": "#e37d80", + "dangerForeground2": "#e37d80", + "dangerForeground3": "#e37d80", + "dangerForegroundInverted": "#d13438", + "dangerStroke1": "#dc5e62", + "defaultBackground": "#000000", + "defaultBorder": "#4d4d4d", + "defaultCheckedBackground": "#242424", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#000000", + "defaultCheckedHoveredContent": "#ffffff", + "defaultContent": "#ffffff", + "defaultDisabledBackground": "#525252", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#000000", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#000000", + "defaultHoveredBorder": "#4d4d4d", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#adadad", + "defaultIcon": "#ffffff", + "defaultPressedBackground": "#2e2e2e", + "defaultPressedBorder": "#4d4d4d", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#adadad", + "disabledBackground": "#525252", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", + "ghostCheckedContent": "#d6d6d6", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#d6d6d6", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#adadad", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#adadad", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#000000", + "inputBorder": "#4d4d4d", + "inputFocusBorderAlt": "#479ef5", + "inputPlaceholderText": "#adadad", + "inputText": "#ffffff", + "link": "#479ef5", + "linkHovered": "#479ef5", + "linkPressed": "#96c6fa", + "listHeaderBackgroundHovered": "#000000", + "listHeaderBackgroundPressed": "#2e2e2e", + "menuBackground": "#000000", + "menuDivider": "#3d3d3d", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#000000", + "menuItemBackgroundPressed": "#2e2e2e", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", + "neutralBackground1": "#000000", + "neutralBackground1Hover": "#000000", + "neutralBackground1Pressed": "#2e2e2e", + "neutralBackground1Selected": "#242424", + "neutralBackground2": "#1f1f1f", + "neutralBackground2Hover": "#1f1f1f", + "neutralBackground2Pressed": "#4d4d4d", + "neutralBackground2Selected": "#424242", + "neutralBackground3": "#292929", + "neutralBackground3Hover": "#292929", + "neutralBackground3Pressed": "#575757", + "neutralBackground3Selected": "#4d4d4d", + "neutralBackground4": "#333333", + "neutralBackground4Hover": "#333333", + "neutralBackground4Pressed": "#616161", + "neutralBackground4Selected": "#575757", + "neutralBackground5": "#3d3d3d", + "neutralBackground5Hover": "#3d3d3d", + "neutralBackground5Pressed": "#6b6b6b", + "neutralBackground5Selected": "#616161", + "neutralBackground6": "#5c5c5c", + "neutralBackgroundCanvas": "#141414", + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": "#525252", + "neutralBackgroundInverted": "#b8b8b8", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#adadad", + "neutralForeground1": "#ffffff", + "neutralForeground1Hover": "#ffffff", + "neutralForeground1Pressed": "#ffffff", + "neutralForeground1Selected": "#ffffff", + "neutralForeground2": "#d6d6d6", + "neutralForeground2BrandHover": "#d6d6d6", + "neutralForeground2BrandPressed": "#d6d6d6", + "neutralForeground2BrandSelected": "#d6d6d6", + "neutralForeground2Hover": "#d6d6d6", + "neutralForeground2Pressed": "#d6d6d6", + "neutralForeground2Selected": "#d6d6d6", + "neutralForeground3": "#adadad", + "neutralForeground3BrandHover": "#adadad", + "neutralForeground3BrandPressed": "#adadad", + "neutralForeground3BrandSelected": "#adadad", + "neutralForeground3Hover": "#adadad", + "neutralForeground3Pressed": "#adadad", + "neutralForeground3Selected": "#adadad", + "neutralForeground4": "#adadad", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#5c5c5c", + "neutralForegroundDisabled1": "#5c5c5c", + "neutralForegroundDisabled2": "#2e2e2e", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#000000", + "neutralForegroundInvertedLinkPressed": "#000000", + "neutralForegroundInvertedLinkSelected": "#000000", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#000000", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#000000", + "neutralStencil1": "#575757", + "neutralStencil2": "#333333", + "neutralStroke1": "#4d4d4d", + "neutralStroke1Hover": "#4d4d4d", + "neutralStroke1Pressed": "#4d4d4d", + "neutralStroke1Selected": "#4d4d4d", + "neutralStroke2": "#3d3d3d", + "neutralStroke3": "#3d3d3d", + "neutralStrokeAccessible": "#9e9e9e", + "neutralStrokeAccessibleHover": "#9e9e9e", + "neutralStrokeAccessiblePressed": "#9e9e9e", + "neutralStrokeAccessibleSelected": "#9e9e9e", + "neutralStrokeDisabled": "#424242", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", + "outofofficeBackground1": "#3a1136", + "outofofficeBackground2": "#6d2064", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#c239b3", + "outofofficeBorder2": "#d161c4", + "outofofficeBorderActive": "#da7ed0", + "outofofficeForeground1": "#da7ed0", + "outofofficeForeground2": "#edbbe7", + "outofofficeForeground3": "#d161c4", + "personaActivityGlow": "#479ef5", + "personaActivityRing": "#000000", + "presenceAvailable": "#3db838", + "presenceAway": "#eaa300", + "presenceDnd": "#d7494c", + "presenceOof": "#d161c4", + "primaryButtonBackground": "#479ef5", + "primaryButtonBackgroundDisabled": "#525252", + "primaryButtonBackgroundHovered": "#479ef5", + "primaryButtonBackgroundPressed": "#96c6fa", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#000000", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#bc2f32", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#e37d80", + "redForeground3": "#e37d80", + "severeBackground1": "#411200", + "severeBackground2": "#c43501", + "severeBackground3": "#da3b01", + "severeBorder1": "#e36537", + "severeBorder2": "#e9835e", + "severeBorderActive": "#e9835e", + "severeForeground1": "#e9835e", + "severeForeground2": "#e9835e", + "severeForeground3": "#e9835e", + "severeStroke1": "#e36537", + "strokeFocus1": "#000000", + "strokeFocus2": "#ffffff", + "subText": "#d6d6d6", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", + "successBackground1": "#052505", + "successBackground2": "#0e700e", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#9fd89f", + "successBorderActive": "#54b054", + "successForeground1": "#54b054", + "successForeground2": "#54b054", + "successForeground3": "#9fd89f", + "successForegroundInverted": "#107c10", + "successStroke1": "#359b35", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#3d3d3d", + "warningBackground1": "#4c4400", + "warningBackground2": "#e4cc00", + "warningBackground3": "#fde300", + "warningBorder1": "#c0ad00", + "warningBorder2": "#fdea3d", + "warningBorderActive": "#feee66", + "warningForeground1": "#feee66", + "warningForeground2": "#feee66", + "warningForeground3": "#fdea3d", + "warningForegroundInverted": "#817400", + "warningStroke1": "#c0ad00", }, "components": {}, "host": { @@ -988,13 +1983,13 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "Segoe UI", - "sansSerif": "System", - "secondary": "Segoe UI", - "serif": "System", + "cursive": "Roboto", + "monospace": "Roboto", + "numeric": "Roboto", + "primary": "Roboto", + "sansSerif": "Roboto", + "secondary": "Roboto", + "serif": "Roboto", }, "sizes": { "body": 14, @@ -1007,139 +2002,214 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` }, "variants": { "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", }, "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", }, "body2": { - "face": "primary", - "size": "body", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", }, "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", }, "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", }, "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", }, "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", }, "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "500", + }, + "caption2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", }, "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", }, "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", }, "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", }, "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", }, "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", }, "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", }, "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", }, "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", }, "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", }, "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", }, "secondaryStandard": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", }, "subheaderSemibold": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", }, "subheaderStandard": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, "subtitle1": { - "face": "primary", - "size": "header", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", }, "subtitle1Strong": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", }, "subtitle2": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, "subtitle2Strong": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", }, "title1": { - "face": "primary", - "size": "hero", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", }, "title1Strong": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", + }, + "title2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", + }, + "title3": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, }, "weights": { @@ -1150,160 +2220,186 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` } `; -exports[`defaultFluentTheme 1`] = ` +exports[`high contrast light theme 1`] = ` { "colors": { "accentButtonBackground": "#0f6cbd", - "actionLink": "#323130", + "actionLink": "#242424", "background": "#ffffff", - "bodyDivider": "#edebe9", + "bodyDivider": "#e0e0e0", "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", - "bodyTextChecked": "#000000", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#ffffff", + "bodyText": "#242424", + "bodyTextChecked": "#242424", "brandBackground": "#0f6cbd", "brandBackground2": "#115ea3", "brandBackground2Pressed": "#0c3b5e", "brandBackground2Selected": "#0e4775", "brandBackground3": "#0f548c", "brandBackgroundDisabled": "#b4d6fa", + "brandBackgroundHover": "#0f6cbd", "brandBackgroundInverted": "#ffffff", "brandBackgroundInvertedDisabled": "#ffffff", "brandBackgroundPressed": "#0e4775", "brandBackgroundSelected": "#0f548c", + "brandBackgroundStatic": "#0f6cbd", "brandBackgroundTint": "#cfe4fa", "brandForeground1": "#0f6cbd", + "brandForeground1Disabled": "#2886de", "brandForeground1Pressed": "#0e4775", "brandForeground1Selected": "#0f548c", + "brandForeground2": "#0f6cbd", "brandForegroundDisabled1": "#2886de", "brandForegroundDisabled2": "#b4d6fa", + "brandForegroundLink": "#0f6cbd", + "brandForegroundLinkHover": "#0f6cbd", + "brandForegroundLinkPressed": "#0e4775", + "brandForegroundLinkSelected": "#0f548c", "brandForegroundTint": "#0f548c", "brandStroke1": "#0f6cbd", "brandStroke1Pressed": "#0e4775", "brandStroke1Selected": "#0f548c", + "brandStroke2": "#2886de", + "brandStrokeTint": "#2886de", "brandedBackground": "#0f6cbd", - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#e0e0e0", + "buttonBackgroundHovered": "#ffffff", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", "checkboxBackground": "#0f6cbd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", + "checkboxBackgroundDisabled": "#e0e0e0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#0f6cbd", + "compoundBrandBackground1Hover": "#0f6cbd", + "compoundBrandBackground1Pressed": "#0e4775", + "compoundBrandForeground1": "#0f6cbd", + "compoundBrandForeground1Hover": "#0f6cbd", + "compoundBrandForeground1Pressed": "#0e4775", + "compoundBrandStroke1": "#0f6cbd", + "compoundBrandStroke1Hover": "#0f6cbd", + "compoundBrandStroke1Pressed": "#0e4775", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#d13438", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#d13438", + "dangerBorderActive": "#d13438", "dangerForeground1": "#bc2f32", "dangerForeground2": "#d13438", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", + "dangerForeground3": "#d13438", + "dangerForegroundInverted": "#dc5e62", + "dangerStroke1": "#dc5e62", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#ffffff", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#e0e0e0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#ffffff", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#ffffff", + "defaultHoveredBorder": "#d1d1d1", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#808080", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#d1d1d1", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#808080", + "disabledBackground": "#e0e0e0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#616161", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#616161", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#808080", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#808080", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#808080", + "ghostSecondaryContent": "#808080", "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", + "inputBorder": "#d1d1d1", "inputFocusBorderAlt": "#0f6cbd", - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", + "inputPlaceholderText": "#808080", + "inputText": "#242424", "link": "#0f6cbd", - "linkHovered": "#0c3b5e", - "linkPressed": "#0f548c", - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", + "linkHovered": "#0f6cbd", + "linkPressed": "#0e4775", + "listHeaderBackgroundHovered": "#ffffff", + "listHeaderBackgroundPressed": "#e0e0e0", "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": "#0f6cbd", - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", + "menuDivider": "#e0e0e0", + "menuIcon": "#616161", + "menuItemBackgroundHovered": "#ffffff", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", "neutralBackground1": "#ffffff", - "neutralBackground1Hover": undefined, + "neutralBackground1Hover": "#ffffff", "neutralBackground1Pressed": "#e0e0e0", "neutralBackground1Selected": "#ebebeb", "neutralBackground2": "#ffffff", - "neutralBackground2Hover": undefined, + "neutralBackground2Hover": "#ffffff", "neutralBackground2Pressed": "#e0e0e0", "neutralBackground2Selected": "#ebebeb", "neutralBackground3": "#ffffff", - "neutralBackground3Hover": undefined, + "neutralBackground3Hover": "#ffffff", "neutralBackground3Pressed": "#e0e0e0", "neutralBackground3Selected": "#ebebeb", "neutralBackground4": "#fafafa", - "neutralBackground4Hover": undefined, + "neutralBackground4Hover": "#fafafa", "neutralBackground4Pressed": "#dbdbdb", "neutralBackground4Selected": "#e6e6e6", "neutralBackground5": "#f0f0f0", - "neutralBackground5Hover": undefined, + "neutralBackground5Hover": "#f0f0f0", "neutralBackground5Pressed": "#d1d1d1", "neutralBackground5Selected": "#dbdbdb", "neutralBackground6": "#d1d1d1", @@ -1314,41 +2410,63 @@ exports[`defaultFluentTheme 1`] = ` "neutralBackgroundLightStatic": "#ffffff", "neutralBackgroundLightStaticDisabled": "#ffffff", "neutralForeground1": "#242424", - "neutralForeground1Hover": undefined, - "neutralForeground1Pressed": undefined, - "neutralForeground1Selected": undefined, + "neutralForeground1Hover": "#242424", + "neutralForeground1Pressed": "#242424", + "neutralForeground1Selected": "#242424", "neutralForeground2": "#616161", - "neutralForeground2BrandHover": undefined, - "neutralForeground2BrandPressed": undefined, - "neutralForeground2BrandSelected": undefined, - "neutralForeground2Hover": undefined, - "neutralForeground2Pressed": undefined, - "neutralForeground2Selected": undefined, + "neutralForeground2BrandHover": "#616161", + "neutralForeground2BrandPressed": "#616161", + "neutralForeground2BrandSelected": "#616161", + "neutralForeground2Hover": "#616161", + "neutralForeground2Pressed": "#616161", + "neutralForeground2Selected": "#616161", "neutralForeground3": "#808080", - "neutralForeground3BrandHover": undefined, - "neutralForeground3BrandPressed": undefined, - "neutralForeground3BrandSelected": undefined, - "neutralForeground3Hover": undefined, - "neutralForeground3Pressed": undefined, - "neutralForeground3Selected": undefined, + "neutralForeground3BrandHover": "#808080", + "neutralForeground3BrandPressed": "#808080", + "neutralForeground3BrandSelected": "#808080", + "neutralForeground3Hover": "#808080", + "neutralForeground3Pressed": "#808080", + "neutralForeground3Selected": "#808080", + "neutralForeground4": "#808080", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#bdbdbd", "neutralForegroundDisabled1": "#bdbdbd", "neutralForegroundDisabled2": "#ffffff", "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#ffffff", + "neutralForegroundInvertedLinkPressed": "#ffffff", + "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", "neutralStroke1": "#d1d1d1", - "neutralStroke1Hover": undefined, - "neutralStroke1Pressed": undefined, - "neutralStroke1Selected": undefined, + "neutralStroke1Hover": "#d1d1d1", + "neutralStroke1Pressed": "#d1d1d1", + "neutralStroke1Selected": "#d1d1d1", "neutralStroke2": "#e0e0e0", + "neutralStroke3": "#e0e0e0", "neutralStrokeAccessible": "#616161", - "neutralStrokeAccessibleHover": undefined, - "neutralStrokeAccessiblePressed": undefined, - "neutralStrokeAccessibleSelected": undefined, + "neutralStrokeAccessibleHover": "#616161", + "neutralStrokeAccessiblePressed": "#616161", + "neutralStrokeAccessibleSelected": "#616161", "neutralStrokeDisabled": "#e0e0e0", "neutralStrokeFocus1": "#ffffff", "neutralStrokeFocus2": "#000000", + "outofofficeBackground1": "#fdf5fc", + "outofofficeBackground2": "#edbbe7", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#edbbe7", + "outofofficeBorder2": "#c239b3", + "outofofficeBorderActive": "#c239b3", + "outofofficeForeground1": "#af33a1", + "outofofficeForeground2": "#6d2064", + "outofofficeForeground3": "#c239b3", "personaActivityGlow": "#0f6cbd", "personaActivityRing": "#ffffff", "presenceAvailable": "#13a10e", @@ -1356,33 +2474,75 @@ exports[`defaultFluentTheme 1`] = ` "presenceDnd": "#d13438", "presenceOof": "#c239b3", "primaryButtonBackground": "#0f6cbd", - "primaryButtonBackgroundDisabled": "#f3f2f1", - "primaryButtonBackgroundHovered": "#115ea3", - "primaryButtonBackgroundPressed": "#0f548c", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", + "primaryButtonBackgroundDisabled": "#e0e0e0", + "primaryButtonBackgroundHovered": "#0f6cbd", + "primaryButtonBackgroundPressed": "#0e4775", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", + "primaryButtonTextDisabled": "#bdbdbd", "primaryButtonTextHovered": "#ffffff", "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#d13438", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#d13438", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#da3b01", + "severeBackground3": "#da3b01", + "severeBorder1": "#de501c", + "severeBorder2": "#da3b01", + "severeBorderActive": "#da3b01", "severeForeground1": "#c43501", "severeForeground2": "#c43501", - "subText": "#605e5c", + "severeForeground3": "#da3b01", + "severeStroke1": "#de501c", + "strokeFocus1": "#ffffff", + "strokeFocus2": "#000000", + "subText": "#616161", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#f5f5f5", + "subtleBackgroundPressed": "#e0e0e0", + "subtleBackgroundSelected": "#ebebeb", "successBackground1": "#f1faf1", "successBackground2": "#107c10", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#107c10", + "successBorderActive": "#107c10", "successForeground1": "#0e700e", "successForeground2": "#107c10", - "variantBorder": "#edebe9", + "successForeground3": "#107c10", + "successForegroundInverted": "#359b35", + "successStroke1": "#359b35", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#e0e0e0", "warningBackground1": "#fffef5", "warningBackground2": "#fde300", + "warningBackground3": "#fde300", + "warningBorder1": "#817400", + "warningBorder2": "#fde300", + "warningBorderActive": "#fde300", "warningForeground1": "#817400", "warningForeground2": "#817400", + "warningForeground3": "#fde300", + "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#817400", }, "components": {}, "host": { - "appearance": "light", + "appearance": "highContrast", }, "shadows": { "shadow16": { @@ -1563,13 +2723,13 @@ exports[`defaultFluentTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "Segoe UI", - "sansSerif": "System", - "secondary": "Segoe UI", - "serif": "System", + "cursive": "Roboto", + "monospace": "Roboto", + "numeric": "Roboto", + "primary": "Roboto", + "sansSerif": "Roboto", + "secondary": "Roboto", + "serif": "Roboto", }, "sizes": { "body": 14, @@ -1582,139 +2742,214 @@ exports[`defaultFluentTheme 1`] = ` }, "variants": { "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", }, "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", }, "body2": { - "face": "primary", - "size": "body", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", }, "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", }, "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "500", }, "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 18, + "size": 14, + "weight": "400", }, "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", }, "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "500", + }, + "caption2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", }, "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 16, + "size": 13, + "weight": "400", }, "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", }, "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", }, "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", }, "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": -0.5, + "lineHeight": 72, + "size": 60, + "weight": "400", }, "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", }, "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", }, "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", }, "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "face": "Roboto", + "letterSpacing": -0.25, + "lineHeight": 48, + "size": 34, + "weight": "400", }, "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "500", }, "secondaryStandard": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 16, + "weight": "400", }, "subheaderSemibold": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", }, "subheaderStandard": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, "subtitle1": { - "face": "primary", - "size": "header", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", }, "subtitle1Strong": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "600", }, "subtitle2": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, "subtitle2Strong": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "600", }, "title1": { - "face": "primary", - "size": "hero", - "weight": "regular", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "400", }, "title1Strong": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 32, + "size": 24, + "weight": "600", + }, + "title2": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 20, + "weight": "500", + }, + "title3": { + "face": "Roboto", + "letterSpacing": 0, + "lineHeight": 24, + "size": 18, + "weight": "500", }, }, "weights": { diff --git a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.ios.ts.snap b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.ios.ts.snap index 19baf088fdf..2dd1fb957d9 100644 --- a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.ios.ts.snap +++ b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.ios.ts.snap @@ -3,152 +3,183 @@ exports[`defaultFluentDarkTheme 1`] = ` { "colors": { - "accentButtonBackground": "#0c3b5e", - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "accentButtonBackground": "#479ef5", + "actionLink": "#ffffff", + "background": "#000000", + "bodyDivider": "#3d3d3d", + "bodyFrameBackground": "#000000", + "bodyFrameDivider": "#3d3d3d", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", "brandBackground": "#479ef5", - "brandBackground2": undefined, - "brandBackground2Pressed": undefined, - "brandBackground2Selected": undefined, - "brandBackground3": undefined, + "brandBackground2": "#479ef5", + "brandBackground2Pressed": "#96c6fa", + "brandBackground2Selected": "#77b7f7", + "brandBackground3": "#479ef5", "brandBackgroundDisabled": "#0c3b5e", + "brandBackgroundHover": "#479ef5", + "brandBackgroundInverted": "#b8b8b8", + "brandBackgroundInvertedDisabled": "#525252", "brandBackgroundPressed": "#96c6fa", "brandBackgroundSelected": "#77b7f7", + "brandBackgroundStatic": "#479ef5", "brandBackgroundTint": "#0c3b5e", "brandForeground1": "#479ef5", + "brandForeground1Disabled": "#2886de", "brandForeground1Pressed": "#96c6fa", "brandForeground1Selected": "#77b7f7", + "brandForeground2": "#479ef5", "brandForegroundDisabled1": "#2886de", "brandForegroundDisabled2": "#0c3b5e", + "brandForegroundLink": "#479ef5", + "brandForegroundLinkHover": "#479ef5", + "brandForegroundLinkPressed": "#96c6fa", + "brandForegroundLinkSelected": "#77b7f7", "brandForegroundTint": "#96c6fa", "brandStroke1": "#479ef5", "brandStroke1Pressed": "#96c6fa", "brandStroke1Selected": "#77b7f7", + "brandStroke2": "#479ef5", "brandStrokeTint": "#479ef5", - "brandedBackground": "#2886de", - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandedBackground": "#479ef5", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#000000", + "buttonBackground": "#000000", + "buttonBackgroundChecked": "#242424", + "buttonBackgroundDisabled": "#525252", + "buttonBackgroundHovered": "#000000", + "buttonBackgroundPressed": "#2e2e2e", + "buttonBorder": "#4d4d4d", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": "#2886de", - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#479ef5", + "checkboxBackgroundDisabled": "#525252", + "checkboxBorderColor": "#9e9e9e", + "checkmarkColor": "#000000", + "compoundBrandBackground1": "#479ef5", + "compoundBrandBackground1Hover": "#479ef5", + "compoundBrandBackground1Pressed": "#96c6fa", + "compoundBrandForeground1": "#479ef5", + "compoundBrandForeground1Hover": "#479ef5", + "compoundBrandForeground1Pressed": "#96c6fa", + "compoundBrandStroke1": "#479ef5", + "compoundBrandStroke1Hover": "#479ef5", + "compoundBrandStroke1Pressed": "#96c6fa", "dangerBackground1": "#3f1011", "dangerBackground2": "#bc2f32", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#dc5e62", + "dangerBorderActive": "#e37d80", "dangerForeground1": "#e37d80", "dangerForeground2": "#e37d80", + "dangerForeground3": "#e37d80", + "dangerForegroundInverted": "#d13438", "dangerStroke1": "#dc5e62", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "defaultBackground": "#000000", + "defaultBorder": "#4d4d4d", + "defaultCheckedBackground": "#242424", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#000000", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#525252", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#000000", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#000000", + "defaultHoveredBorder": "#4d4d4d", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#adadad", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", - "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": "#2886de", - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": "#2886de", - "linkHovered": "#62abf5", - "linkPressed": "#479ef5", - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": "#479ef5", - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", + "defaultPressedBackground": "#2e2e2e", + "defaultPressedBorder": "#4d4d4d", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#adadad", + "disabledBackground": "#525252", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", + "ghostCheckedContent": "#d6d6d6", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#d6d6d6", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#adadad", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#adadad", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#000000", + "inputBorder": "#4d4d4d", + "inputFocusBorderAlt": "#479ef5", + "inputPlaceholderText": "#adadad", + "inputText": "#ffffff", + "link": "#479ef5", + "linkHovered": "#479ef5", + "linkPressed": "#96c6fa", + "listHeaderBackgroundHovered": "#000000", + "listHeaderBackgroundPressed": "#2e2e2e", + "menuBackground": "#000000", + "menuDivider": "#3d3d3d", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#000000", + "menuItemBackgroundPressed": "#2e2e2e", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", "neutralBackground1": "#000000", + "neutralBackground1Hover": "#000000", "neutralBackground1Pressed": "#2e2e2e", "neutralBackground1Selected": "#242424", "neutralBackground2": "#1f1f1f", + "neutralBackground2Hover": "#1f1f1f", "neutralBackground2Pressed": "#4d4d4d", "neutralBackground2Selected": "#424242", "neutralBackground3": "#292929", + "neutralBackground3Hover": "#292929", "neutralBackground3Pressed": "#575757", "neutralBackground3Selected": "#4d4d4d", "neutralBackground4": "#333333", + "neutralBackground4Hover": "#333333", "neutralBackground4Pressed": "#616161", "neutralBackground4Selected": "#575757", "neutralBackground5": "#3d3d3d", + "neutralBackground5Hover": "#3d3d3d", "neutralBackground5Pressed": "#6b6b6b", "neutralBackground5Selected": "#616161", "neutralBackground6": "#5c5c5c", @@ -159,53 +190,134 @@ exports[`defaultFluentDarkTheme 1`] = ` "neutralBackgroundLightStatic": "#ffffff", "neutralBackgroundLightStaticDisabled": "#adadad", "neutralForeground1": "#ffffff", + "neutralForeground1Hover": "#ffffff", + "neutralForeground1Pressed": "#ffffff", + "neutralForeground1Selected": "#ffffff", "neutralForeground2": "#d6d6d6", + "neutralForeground2BrandHover": "#d6d6d6", + "neutralForeground2BrandPressed": "#d6d6d6", + "neutralForeground2BrandSelected": "#d6d6d6", + "neutralForeground2Hover": "#d6d6d6", + "neutralForeground2Pressed": "#d6d6d6", + "neutralForeground2Selected": "#d6d6d6", "neutralForeground3": "#adadad", + "neutralForeground3BrandHover": "#adadad", + "neutralForeground3BrandPressed": "#adadad", + "neutralForeground3BrandSelected": "#adadad", + "neutralForeground3Hover": "#adadad", + "neutralForeground3Pressed": "#adadad", + "neutralForeground3Selected": "#adadad", + "neutralForeground4": "#adadad", "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#5c5c5c", "neutralForegroundDisabled1": "#5c5c5c", "neutralForegroundDisabled2": "#2e2e2e", + "neutralForegroundInverted": "#000000", + "neutralForegroundInvertedLink": "#000000", + "neutralForegroundInvertedLinkHover": "#000000", + "neutralForegroundInvertedLinkPressed": "#000000", + "neutralForegroundInvertedLinkSelected": "#000000", "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#000000", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", "neutralForegroundOnColor": "#000000", "neutralStencil1": "#575757", "neutralStencil2": "#333333", "neutralStroke1": "#4d4d4d", + "neutralStroke1Hover": "#4d4d4d", + "neutralStroke1Pressed": "#4d4d4d", + "neutralStroke1Selected": "#4d4d4d", "neutralStroke2": "#3d3d3d", + "neutralStroke3": "#3d3d3d", "neutralStrokeAccessible": "#9e9e9e", + "neutralStrokeAccessibleHover": "#9e9e9e", + "neutralStrokeAccessiblePressed": "#9e9e9e", + "neutralStrokeAccessibleSelected": "#9e9e9e", "neutralStrokeDisabled": "#424242", "neutralStrokeFocus1": "#000000", "neutralStrokeFocus2": "#ffffff", - "personaActivityGlow": "#2886de", - "personaActivityRing": "#1b1a19", + "outofofficeBackground1": "#3a1136", + "outofofficeBackground2": "#6d2064", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#c239b3", + "outofofficeBorder2": "#d161c4", + "outofofficeBorderActive": "#da7ed0", + "outofofficeForeground1": "#da7ed0", + "outofofficeForeground2": "#edbbe7", + "outofofficeForeground3": "#d161c4", + "personaActivityGlow": "#479ef5", + "personaActivityRing": "#000000", "presenceAvailable": "#3db838", "presenceAway": "#eaa300", "presenceDnd": "#d7494c", "presenceOof": "#d161c4", - "primaryButtonBackground": "#2886de", - "primaryButtonBackgroundDisabled": "#252423", + "primaryButtonBackground": "#479ef5", + "primaryButtonBackgroundDisabled": "#525252", "primaryButtonBackgroundHovered": "#479ef5", - "primaryButtonBackgroundPressed": "#479ef5", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "primaryButtonBackgroundPressed": "#96c6fa", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#000000", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#bc2f32", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#e37d80", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#c43501", + "severeBackground3": "#da3b01", + "severeBorder1": "#e36537", + "severeBorder2": "#e9835e", + "severeBorderActive": "#e9835e", "severeForeground1": "#e9835e", "severeForeground2": "#e9835e", + "severeForeground3": "#e9835e", "severeStroke1": "#e36537", - "subText": "#a19f9d", + "strokeFocus1": "#000000", + "strokeFocus2": "#ffffff", + "subText": "#d6d6d6", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", "successBackground1": "#052505", "successBackground2": "#0e700e", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#9fd89f", + "successBorderActive": "#54b054", "successForeground1": "#54b054", "successForeground2": "#54b054", + "successForeground3": "#9fd89f", + "successForegroundInverted": "#107c10", "successStroke1": "#359b35", - "variantBorder": "#292827", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#3d3d3d", "warningBackground1": "#4c4400", "warningBackground2": "#e4cc00", + "warningBackground3": "#fde300", + "warningBorder1": "#c0ad00", + "warningBorder2": "#fdea3d", + "warningBorderActive": "#feee66", "warningForeground1": "#feee66", "warningForeground2": "#feee66", + "warningForeground3": "#fdea3d", + "warningForegroundInverted": "#817400", "warningStroke1": "#c0ad00", }, "components": {}, @@ -410,139 +522,244 @@ exports[`defaultFluentDarkTheme 1`] = ` }, "variants": { "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", }, "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", }, "body2": { - "face": "primary", - "size": "body", - "weight": "regular", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", }, "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", }, "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", }, "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", }, "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", }, "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "600", + }, + "caption2": { + "dynamicTypeRamp": "caption1", + "face": "System", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", }, "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", }, "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", }, "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", }, "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", }, "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", }, "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", }, "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", }, "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", }, "secondaryStandard": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", }, "subheaderSemibold": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subheaderStandard": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subtitle1": { - "face": "primary", - "size": "header", - "weight": "regular", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "subtitle1Strong": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "subtitle2": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subtitle2Strong": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "title1": { - "face": "primary", - "size": "hero", - "weight": "regular", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", }, "title1Strong": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", + }, + "title2": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "title3": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, }, "weights": { @@ -553,155 +770,186 @@ exports[`defaultFluentDarkTheme 1`] = ` } `; -exports[`defaultFluentHighConstrastTheme 1`] = ` +exports[`defaultFluentTheme 1`] = ` { "colors": { - "accentButtonBackground": "#000000", - "actionLink": "#ffff00", - "background": "#000000", - "bodyDivider": "#ffffff", - "bodyFrameBackground": "#000000", - "bodyFrameDivider": "#000000", - "bodyStandoutBackground": "#000000", - "bodyText": "#ffffff", - "bodyTextChecked": "#000000", + "accentButtonBackground": "#0f6cbd", + "actionLink": "#242424", + "background": "#ffffff", + "bodyDivider": "#e0e0e0", + "bodyFrameBackground": "#ffffff", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#ffffff", + "bodyText": "#242424", + "bodyTextChecked": "#242424", "brandBackground": "#0f6cbd", "brandBackground2": "#115ea3", "brandBackground2Pressed": "#0c3b5e", "brandBackground2Selected": "#0e4775", "brandBackground3": "#0f548c", "brandBackgroundDisabled": "#b4d6fa", + "brandBackgroundHover": "#0f6cbd", + "brandBackgroundInverted": "#757575", + "brandBackgroundInvertedDisabled": "#e0e0e0", "brandBackgroundPressed": "#0e4775", "brandBackgroundSelected": "#0f548c", + "brandBackgroundStatic": "#0f6cbd", "brandBackgroundTint": "#cfe4fa", "brandForeground1": "#0f6cbd", + "brandForeground1Disabled": "#2886de", "brandForeground1Pressed": "#0e4775", "brandForeground1Selected": "#0f548c", + "brandForeground2": "#0f6cbd", "brandForegroundDisabled1": "#2886de", "brandForegroundDisabled2": "#b4d6fa", + "brandForegroundLink": "#0f6cbd", + "brandForegroundLinkHover": "#0f6cbd", + "brandForegroundLinkPressed": "#0e4775", + "brandForegroundLinkSelected": "#0f548c", "brandForegroundTint": "#0f548c", "brandStroke1": "#0f6cbd", "brandStroke1Pressed": "#0e4775", "brandStroke1Selected": "#0f548c", + "brandStroke2": "#2886de", "brandStrokeTint": "#2886de", - "brandedBackground": "#000000", - "brandedDisabledBorder": "#3ff23f", + "brandedBackground": "#0f6cbd", + "brandedDisabledBorder": "#00000000", "brandedFocusedSecondaryContent": "#ffffff", - "brandedHoveredSecondaryContent": "#000000", - "brandedPressedSecondaryContent": "#000000", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", "brandedSecondaryContent": "#ffffff", - "buttonBackground": "#000000", - "buttonBackgroundChecked": "#1aebff", - "buttonBackgroundDisabled": "#000000", - "buttonBackgroundHovered": "#1aebff", - "buttonBackgroundPressed": "#1aebff", - "buttonBorder": "#ffffff", - "buttonBorderDisabled": "#3ff23f", - "buttonBorderFocused": "#ffffff", - "buttonText": "#ffffff", - "buttonTextChecked": "#000000", - "buttonTextDisabled": "#3ff23f", - "buttonTextHovered": "#000000", - "buttonTextPressed": "#000000", - "checkboxBackground": "#000000", - "checkboxBackgroundDisabled": "#000000", - "checkboxBorderColor": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#e0e0e0", + "buttonBackgroundHovered": "#ffffff", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", + "checkboxBackground": "#0f6cbd", + "checkboxBackgroundDisabled": "#e0e0e0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#0f6cbd", + "compoundBrandBackground1Hover": "#0f6cbd", + "compoundBrandBackground1Pressed": "#0e4775", + "compoundBrandForeground1": "#0f6cbd", + "compoundBrandForeground1Hover": "#0f6cbd", + "compoundBrandForeground1Pressed": "#0e4775", + "compoundBrandStroke1": "#0f6cbd", + "compoundBrandStroke1Hover": "#0f6cbd", + "compoundBrandStroke1Pressed": "#0e4775", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#d13438", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#d13438", + "dangerBorderActive": "#d13438", "dangerForeground1": "#bc2f32", "dangerForeground2": "#d13438", + "dangerForeground3": "#d13438", + "dangerForegroundInverted": "#dc5e62", "dangerStroke1": "#dc5e62", - "defaultBackground": "#000000", - "defaultBorder": "#ffffff", - "defaultCheckedBackground": "#1aebff", - "defaultCheckedContent": "#000000", - "defaultCheckedHoveredBackground": "#1aebff", - "defaultCheckedHoveredContent": "#000000", - "defaultContent": "#ffffff", - "defaultDisabledBackground": "#000000", - "defaultDisabledBorder": "#3ff23f", - "defaultDisabledContent": "#3ff23f", - "defaultDisabledIcon": "#3ff23f", - "defaultFocusedBackground": "#000000", - "defaultFocusedBorder": "#ffffff", - "defaultFocusedContent": "#ffffff", - "defaultFocusedIcon": "#ffffff", - "defaultHoveredBackground": "#1aebff", - "defaultHoveredBorder": "#1aebff", - "defaultHoveredContent": "#000000", - "defaultHoveredIcon": "#000000", - "defaultHoveredSecondaryContent": "#000000", - "defaultIcon": "#ffffff", - "defaultPressedBackground": "#1aebff", - "defaultPressedBorder": "#1aebff", - "defaultPressedContent": "#000000", - "defaultPressedIcon": "#000000", - "defaultPressedSecondaryContent": "#000000", - "disabledBackground": "#000000", - "disabledBodyText": "#3ff23f", - "disabledText": "#3ff23f", - "errorText": "#ffffff", - "focusBorder": "#ffffff", - "ghostBackground": "#000000", - "ghostBorder": "#000000", - "ghostCheckedBackground": "#1aebff", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#1aebff", - "ghostCheckedHoveredBorder": "#000000", - "ghostCheckedHoveredContent": "#000000", - "ghostContent": "#ffffff", - "ghostDisabledBackground": "#000000", - "ghostDisabledBorder": "#000000", - "ghostDisabledContent": "#3ff23f", - "ghostDisabledIcon": "#3ff23f", - "ghostFocusedBackground": "#000000", - "ghostFocusedBorder": "#ffffff", - "ghostFocusedContent": "#ffffff", - "ghostFocusedIcon": "#ffffff", - "ghostFocusedSecondaryContent": "#ffffff", - "ghostHoveredBackground": "#1aebff", - "ghostHoveredBorder": "#1aebff", - "ghostHoveredContent": "#000000", - "ghostHoveredIcon": "#000000", - "ghostHoveredSecondaryContent": "#000000", - "ghostIcon": "#ffffff", - "ghostPressedBackground": "#1aebff", - "ghostPressedBorder": "#1aebff", - "ghostPressedContent": "#000000", - "ghostPressedIcon": "#000000", - "ghostPressedSecondaryContent": "#000000", - "ghostSecondaryContent": "#ffffff", - "inputBackground": "#000000", - "inputBorder": "#ffffff", - "inputFocusBorderAlt": "#ffffff", - "inputPlaceholderText": "#ffffff", - "inputText": "#ffffff", - "link": "#ffff00", - "linkHovered": "#ffffff", - "linkPressed": "#ffffff", - "listHeaderBackgroundHovered": "#1aebff", - "listHeaderBackgroundPressed": "#1aebff", - "menuBackground": "#000000", - "menuDivider": "#ffffff", - "menuIcon": "#ffffff", - "menuItemBackgroundHovered": "#1aebff", - "menuItemBackgroundPressed": "#1aebff", - "menuItemText": "#ffffff", - "menuItemTextHovered": "#000000", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#ffffff", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#e0e0e0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#ffffff", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#ffffff", + "defaultHoveredBorder": "#d1d1d1", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#808080", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#d1d1d1", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#808080", + "disabledBackground": "#e0e0e0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#616161", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#616161", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#808080", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#808080", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#808080", + "ghostSecondaryContent": "#808080", + "inputBackground": "#ffffff", + "inputBorder": "#d1d1d1", + "inputFocusBorderAlt": "#0f6cbd", + "inputPlaceholderText": "#808080", + "inputText": "#242424", + "link": "#0f6cbd", + "linkHovered": "#0f6cbd", + "linkPressed": "#0e4775", + "listHeaderBackgroundHovered": "#ffffff", + "listHeaderBackgroundPressed": "#e0e0e0", + "menuBackground": "#ffffff", + "menuDivider": "#e0e0e0", + "menuIcon": "#616161", + "menuItemBackgroundHovered": "#ffffff", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", "neutralBackground1": "#ffffff", + "neutralBackground1Hover": "#ffffff", "neutralBackground1Pressed": "#e0e0e0", "neutralBackground1Selected": "#ebebeb", "neutralBackground2": "#ffffff", + "neutralBackground2Hover": "#ffffff", "neutralBackground2Pressed": "#e0e0e0", "neutralBackground2Selected": "#ebebeb", "neutralBackground3": "#ffffff", + "neutralBackground3Hover": "#ffffff", "neutralBackground3Pressed": "#e0e0e0", "neutralBackground3Selected": "#ebebeb", "neutralBackground4": "#fafafa", + "neutralBackground4Hover": "#fafafa", "neutralBackground4Pressed": "#dbdbdb", "neutralBackground4Selected": "#e6e6e6", "neutralBackground5": "#f0f0f0", + "neutralBackground5Hover": "#f0f0f0", "neutralBackground5Pressed": "#d1d1d1", "neutralBackground5Selected": "#dbdbdb", "neutralBackground6": "#d1d1d1", @@ -712,58 +960,139 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` "neutralBackgroundLightStatic": "#ffffff", "neutralBackgroundLightStaticDisabled": "#ffffff", "neutralForeground1": "#242424", + "neutralForeground1Hover": "#242424", + "neutralForeground1Pressed": "#242424", + "neutralForeground1Selected": "#242424", "neutralForeground2": "#616161", + "neutralForeground2BrandHover": "#616161", + "neutralForeground2BrandPressed": "#616161", + "neutralForeground2BrandSelected": "#616161", + "neutralForeground2Hover": "#616161", + "neutralForeground2Pressed": "#616161", + "neutralForeground2Selected": "#616161", "neutralForeground3": "#808080", + "neutralForeground3BrandHover": "#808080", + "neutralForeground3BrandPressed": "#808080", + "neutralForeground3BrandSelected": "#808080", + "neutralForeground3Hover": "#808080", + "neutralForeground3Pressed": "#808080", + "neutralForeground3Selected": "#808080", + "neutralForeground4": "#808080", "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#bdbdbd", "neutralForegroundDisabled1": "#bdbdbd", "neutralForegroundDisabled2": "#ffffff", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#ffffff", + "neutralForegroundInvertedLinkPressed": "#ffffff", + "neutralForegroundInvertedLinkSelected": "#ffffff", "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", "neutralStroke1": "#d1d1d1", + "neutralStroke1Hover": "#d1d1d1", + "neutralStroke1Pressed": "#d1d1d1", + "neutralStroke1Selected": "#d1d1d1", "neutralStroke2": "#e0e0e0", + "neutralStroke3": "#e0e0e0", "neutralStrokeAccessible": "#616161", + "neutralStrokeAccessibleHover": "#616161", + "neutralStrokeAccessiblePressed": "#616161", + "neutralStrokeAccessibleSelected": "#616161", "neutralStrokeDisabled": "#e0e0e0", "neutralStrokeFocus1": "#ffffff", "neutralStrokeFocus2": "#000000", - "personaActivityGlow": "transparent", + "outofofficeBackground1": "#fdf5fc", + "outofofficeBackground2": "#edbbe7", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#edbbe7", + "outofofficeBorder2": "#c239b3", + "outofofficeBorderActive": "#c239b3", + "outofofficeForeground1": "#af33a1", + "outofofficeForeground2": "#6d2064", + "outofofficeForeground3": "#c239b3", + "personaActivityGlow": "#0f6cbd", "personaActivityRing": "#ffffff", "presenceAvailable": "#13a10e", "presenceAway": "#eaa300", "presenceDnd": "#d13438", "presenceOof": "#c239b3", - "primaryButtonBackground": "#000000", - "primaryButtonBackgroundDisabled": "#000000", - "primaryButtonBackgroundHovered": "#1aebff", - "primaryButtonBackgroundPressed": "#1aebff", - "primaryButtonBorder": "#ffffff", - "primaryButtonBorderFocused": "#ffffff", + "primaryButtonBackground": "#0f6cbd", + "primaryButtonBackgroundDisabled": "#e0e0e0", + "primaryButtonBackgroundHovered": "#0f6cbd", + "primaryButtonBackgroundPressed": "#0e4775", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#3ff23f", - "primaryButtonTextHovered": "#000000", - "primaryButtonTextPressed": "#000000", + "primaryButtonTextDisabled": "#bdbdbd", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#d13438", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#d13438", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#da3b01", + "severeBackground3": "#da3b01", + "severeBorder1": "#de501c", + "severeBorder2": "#da3b01", + "severeBorderActive": "#da3b01", "severeForeground1": "#c43501", "severeForeground2": "#a62d01", + "severeForeground3": "#da3b01", "severeStroke1": "#de501c", - "subText": "#ffffff", + "strokeFocus1": "#ffffff", + "strokeFocus2": "#000000", + "subText": "#616161", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#f5f5f5", + "subtleBackgroundPressed": "#e0e0e0", + "subtleBackgroundSelected": "#ebebeb", "successBackground1": "#f1faf1", "successBackground2": "#107c10", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#107c10", + "successBorderActive": "#107c10", "successForeground1": "#0e700e", "successForeground2": "#107c10", + "successForeground3": "#107c10", + "successForegroundInverted": "#359b35", "successStroke1": "#359b35", - "variantBorder": "#ffffff", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#e0e0e0", "warningBackground1": "#fffef5", "warningBackground2": "#fde300", + "warningBackground3": "#fde300", + "warningBorder1": "#817400", + "warningBorder2": "#fde300", + "warningBorderActive": "#fde300", "warningForeground1": "#817400", "warningForeground2": "#817400", + "warningForeground3": "#fde300", + "warningForegroundInverted": "#fef7b2", "warningStroke1": "#817400", }, "components": {}, "host": { - "appearance": "highContrast", + "appearance": "light", }, "shadows": { "shadow16": { @@ -963,139 +1292,244 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` }, "variants": { "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", }, "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", }, "body2": { - "face": "primary", - "size": "body", - "weight": "regular", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", }, "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", }, "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", }, "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", }, "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", }, "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "600", + }, + "caption2": { + "dynamicTypeRamp": "caption1", + "face": "System", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", }, "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", }, "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", }, "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", }, "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", }, "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", }, "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", }, "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", }, "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", }, "secondaryStandard": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", }, "subheaderSemibold": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subheaderStandard": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subtitle1": { - "face": "primary", - "size": "header", - "weight": "regular", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "subtitle1Strong": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "subtitle2": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subtitle2Strong": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "title1": { - "face": "primary", - "size": "hero", - "weight": "regular", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", }, "title1Strong": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", + }, + "title2": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "title3": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, }, "weights": { @@ -1106,155 +1540,956 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` } `; -exports[`defaultFluentTheme 1`] = ` +exports[`high contrast dark theme 1`] = ` +{ + "colors": { + "accentButtonBackground": "#479ef5", + "actionLink": "#ffffff", + "background": "#000000", + "bodyDivider": "#3d3d3d", + "bodyFrameBackground": "#000000", + "bodyFrameDivider": "#3d3d3d", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", + "bodyTextChecked": "#ffffff", + "brandBackground": "#479ef5", + "brandBackground2": "#479ef5", + "brandBackground2Pressed": "#96c6fa", + "brandBackground2Selected": "#77b7f7", + "brandBackground3": "#479ef5", + "brandBackgroundDisabled": "#0c3b5e", + "brandBackgroundHover": "#479ef5", + "brandBackgroundInverted": "#b8b8b8", + "brandBackgroundInvertedDisabled": "#525252", + "brandBackgroundPressed": "#96c6fa", + "brandBackgroundSelected": "#77b7f7", + "brandBackgroundStatic": "#479ef5", + "brandBackgroundTint": "#0c3b5e", + "brandForeground1": "#479ef5", + "brandForeground1Disabled": "#2886de", + "brandForeground1Pressed": "#96c6fa", + "brandForeground1Selected": "#77b7f7", + "brandForeground2": "#479ef5", + "brandForegroundDisabled1": "#2886de", + "brandForegroundDisabled2": "#0c3b5e", + "brandForegroundLink": "#479ef5", + "brandForegroundLinkHover": "#479ef5", + "brandForegroundLinkPressed": "#96c6fa", + "brandForegroundLinkSelected": "#77b7f7", + "brandForegroundTint": "#96c6fa", + "brandStroke1": "#479ef5", + "brandStroke1Pressed": "#96c6fa", + "brandStroke1Selected": "#77b7f7", + "brandStroke2": "#479ef5", + "brandStrokeTint": "#479ef5", + "brandedBackground": "#479ef5", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#000000", + "buttonBackground": "#000000", + "buttonBackgroundChecked": "#242424", + "buttonBackgroundDisabled": "#525252", + "buttonBackgroundHovered": "#000000", + "buttonBackgroundPressed": "#2e2e2e", + "buttonBorder": "#4d4d4d", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", + "buttonText": "#ffffff", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#479ef5", + "checkboxBackgroundDisabled": "#525252", + "checkboxBorderColor": "#9e9e9e", + "checkmarkColor": "#000000", + "compoundBrandBackground1": "#479ef5", + "compoundBrandBackground1Hover": "#479ef5", + "compoundBrandBackground1Pressed": "#96c6fa", + "compoundBrandForeground1": "#479ef5", + "compoundBrandForeground1Hover": "#479ef5", + "compoundBrandForeground1Pressed": "#96c6fa", + "compoundBrandStroke1": "#479ef5", + "compoundBrandStroke1Hover": "#479ef5", + "compoundBrandStroke1Pressed": "#96c6fa", + "dangerBackground1": "#3f1011", + "dangerBackground2": "#bc2f32", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#dc5e62", + "dangerBorderActive": "#e37d80", + "dangerForeground1": "#e37d80", + "dangerForeground2": "#e37d80", + "dangerForeground3": "#e37d80", + "dangerForegroundInverted": "#d13438", + "dangerStroke1": "#dc5e62", + "defaultBackground": "#000000", + "defaultBorder": "#4d4d4d", + "defaultCheckedBackground": "#242424", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#000000", + "defaultCheckedHoveredContent": "#ffffff", + "defaultContent": "#ffffff", + "defaultDisabledBackground": "#525252", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#000000", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#000000", + "defaultHoveredBorder": "#4d4d4d", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#adadad", + "defaultIcon": "#ffffff", + "defaultPressedBackground": "#2e2e2e", + "defaultPressedBorder": "#4d4d4d", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#adadad", + "disabledBackground": "#525252", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", + "ghostCheckedContent": "#d6d6d6", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#d6d6d6", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#adadad", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#adadad", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#000000", + "inputBorder": "#4d4d4d", + "inputFocusBorderAlt": "#479ef5", + "inputPlaceholderText": "#adadad", + "inputText": "#ffffff", + "link": "#479ef5", + "linkHovered": "#479ef5", + "linkPressed": "#96c6fa", + "listHeaderBackgroundHovered": "#000000", + "listHeaderBackgroundPressed": "#2e2e2e", + "menuBackground": "#000000", + "menuDivider": "#3d3d3d", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#000000", + "menuItemBackgroundPressed": "#2e2e2e", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", + "neutralBackground1": "#000000", + "neutralBackground1Hover": "#000000", + "neutralBackground1Pressed": "#2e2e2e", + "neutralBackground1Selected": "#242424", + "neutralBackground2": "#1f1f1f", + "neutralBackground2Hover": "#1f1f1f", + "neutralBackground2Pressed": "#4d4d4d", + "neutralBackground2Selected": "#424242", + "neutralBackground3": "#292929", + "neutralBackground3Hover": "#292929", + "neutralBackground3Pressed": "#575757", + "neutralBackground3Selected": "#4d4d4d", + "neutralBackground4": "#333333", + "neutralBackground4Hover": "#333333", + "neutralBackground4Pressed": "#616161", + "neutralBackground4Selected": "#575757", + "neutralBackground5": "#3d3d3d", + "neutralBackground5Hover": "#3d3d3d", + "neutralBackground5Pressed": "#6b6b6b", + "neutralBackground5Selected": "#616161", + "neutralBackground6": "#5c5c5c", + "neutralBackgroundCanvas": "#141414", + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": "#525252", + "neutralBackgroundInverted": "#b8b8b8", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#adadad", + "neutralForeground1": "#ffffff", + "neutralForeground1Hover": "#ffffff", + "neutralForeground1Pressed": "#ffffff", + "neutralForeground1Selected": "#ffffff", + "neutralForeground2": "#d6d6d6", + "neutralForeground2BrandHover": "#d6d6d6", + "neutralForeground2BrandPressed": "#d6d6d6", + "neutralForeground2BrandSelected": "#d6d6d6", + "neutralForeground2Hover": "#d6d6d6", + "neutralForeground2Pressed": "#d6d6d6", + "neutralForeground2Selected": "#d6d6d6", + "neutralForeground3": "#adadad", + "neutralForeground3BrandHover": "#adadad", + "neutralForeground3BrandPressed": "#adadad", + "neutralForeground3BrandSelected": "#adadad", + "neutralForeground3Hover": "#adadad", + "neutralForeground3Pressed": "#adadad", + "neutralForeground3Selected": "#adadad", + "neutralForeground4": "#adadad", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#5c5c5c", + "neutralForegroundDisabled1": "#5c5c5c", + "neutralForegroundDisabled2": "#2e2e2e", + "neutralForegroundInverted": "#000000", + "neutralForegroundInvertedLink": "#000000", + "neutralForegroundInvertedLinkHover": "#000000", + "neutralForegroundInvertedLinkPressed": "#000000", + "neutralForegroundInvertedLinkSelected": "#000000", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#000000", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#000000", + "neutralStencil1": "#575757", + "neutralStencil2": "#333333", + "neutralStroke1": "#4d4d4d", + "neutralStroke1Hover": "#4d4d4d", + "neutralStroke1Pressed": "#4d4d4d", + "neutralStroke1Selected": "#4d4d4d", + "neutralStroke2": "#3d3d3d", + "neutralStroke3": "#3d3d3d", + "neutralStrokeAccessible": "#9e9e9e", + "neutralStrokeAccessibleHover": "#9e9e9e", + "neutralStrokeAccessiblePressed": "#9e9e9e", + "neutralStrokeAccessibleSelected": "#9e9e9e", + "neutralStrokeDisabled": "#424242", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", + "outofofficeBackground1": "#3a1136", + "outofofficeBackground2": "#6d2064", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#c239b3", + "outofofficeBorder2": "#d161c4", + "outofofficeBorderActive": "#da7ed0", + "outofofficeForeground1": "#da7ed0", + "outofofficeForeground2": "#edbbe7", + "outofofficeForeground3": "#d161c4", + "personaActivityGlow": "#479ef5", + "personaActivityRing": "#000000", + "presenceAvailable": "#3db838", + "presenceAway": "#eaa300", + "presenceDnd": "#d7494c", + "presenceOof": "#d161c4", + "primaryButtonBackground": "#479ef5", + "primaryButtonBackgroundDisabled": "#525252", + "primaryButtonBackgroundHovered": "#479ef5", + "primaryButtonBackgroundPressed": "#96c6fa", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#000000", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#bc2f32", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#e37d80", + "redForeground3": "#e37d80", + "severeBackground1": "#411200", + "severeBackground2": "#c43501", + "severeBackground3": "#da3b01", + "severeBorder1": "#e36537", + "severeBorder2": "#e9835e", + "severeBorderActive": "#e9835e", + "severeForeground1": "#e9835e", + "severeForeground2": "#e9835e", + "severeForeground3": "#e9835e", + "severeStroke1": "#e36537", + "strokeFocus1": "#000000", + "strokeFocus2": "#ffffff", + "subText": "#d6d6d6", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", + "successBackground1": "#052505", + "successBackground2": "#0e700e", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#9fd89f", + "successBorderActive": "#54b054", + "successForeground1": "#54b054", + "successForeground2": "#54b054", + "successForeground3": "#9fd89f", + "successForegroundInverted": "#107c10", + "successStroke1": "#359b35", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#3d3d3d", + "warningBackground1": "#4c4400", + "warningBackground2": "#e4cc00", + "warningBackground3": "#fde300", + "warningBorder1": "#c0ad00", + "warningBorder2": "#fdea3d", + "warningBorderActive": "#feee66", + "warningForeground1": "#feee66", + "warningForeground2": "#feee66", + "warningForeground3": "#fdea3d", + "warningForegroundInverted": "#817400", + "warningStroke1": "#c0ad00", + }, + "components": {}, + "host": { + "appearance": "highContrast", + }, + "shadows": { + "shadow16": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000047", + "x": 0, + "y": 8, + }, + }, + "shadow16brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000040", + "x": 0, + "y": 8, + }, + }, + "shadow2": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000047", + "x": 0, + "y": 1, + }, + }, + "shadow28": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#0000007a", + "x": 0, + "y": 14, + }, + }, + "shadow28brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000040", + "x": 0, + "y": 14, + }, + }, + "shadow2brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000040", + "x": 0, + "y": 1, + }, + }, + "shadow4": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000047", + "x": 0, + "y": 2, + }, + }, + "shadow4brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000040", + "x": 0, + "y": 2, + }, + }, + "shadow64": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#0000007a", + "x": 0, + "y": 32, + }, + }, + "shadow64brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000040", + "x": 0, + "y": 32, + }, + }, + "shadow8": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000047", + "x": 0, + "y": 4, + }, + }, + "shadow8brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000040", + "x": 0, + "y": 4, + }, + }, + }, + "spacing": { + "l1": "20px", + "l2": "32px", + "m": "16px", + "s1": "8px", + "s2": "4px", + }, + "typography": { + "families": { + "cursive": "System", + "monospace": "System", + "numeric": "System", + "primary": "System", + "sansSerif": "System", + "secondary": "System", + "serif": "System", + }, + "sizes": { + "body": 15, + "caption": 12, + "header": 20, + "hero": 28, + "heroLarge": 60, + "secondary": 13, + "subheader": 17, + }, + "variants": { + "body1": { + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", + }, + "body1Strong": { + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", + }, + "body2": { + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", + }, + "body2Strong": { + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", + }, + "bodySemibold": { + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", + }, + "bodyStandard": { + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", + }, + "caption1": { + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", + }, + "caption1Strong": { + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "600", + }, + "caption2": { + "dynamicTypeRamp": "caption1", + "face": "System", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", + }, + "captionStandard": { + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", + }, + "display": { + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", + }, + "headerSemibold": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "headerStandard": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "heroLargeSemibold": { + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", + }, + "heroLargeStandard": { + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", + }, + "heroSemibold": { + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", + }, + "heroStandard": { + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", + }, + "largeTitle": { + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", + }, + "secondarySemibold": { + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", + }, + "secondaryStandard": { + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", + }, + "subheaderSemibold": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", + }, + "subheaderStandard": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", + }, + "subtitle1": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "subtitle1Strong": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "subtitle2": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", + }, + "subtitle2Strong": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", + }, + "title1": { + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", + }, + "title1Strong": { + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", + }, + "title2": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "title3": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", + }, + }, + "weights": { + "regular": "400", + "semiBold": "600", + }, + }, +} +`; + +exports[`high contrast light theme 1`] = ` { "colors": { "accentButtonBackground": "#0f6cbd", - "actionLink": "#323130", + "actionLink": "#242424", "background": "#ffffff", - "bodyDivider": "#edebe9", + "bodyDivider": "#e0e0e0", "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", - "bodyTextChecked": "#000000", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#ffffff", + "bodyText": "#242424", + "bodyTextChecked": "#242424", "brandBackground": "#0f6cbd", "brandBackground2": "#115ea3", "brandBackground2Pressed": "#0c3b5e", "brandBackground2Selected": "#0e4775", "brandBackground3": "#0f548c", "brandBackgroundDisabled": "#b4d6fa", + "brandBackgroundHover": "#0f6cbd", + "brandBackgroundInverted": "#757575", + "brandBackgroundInvertedDisabled": "#e0e0e0", "brandBackgroundPressed": "#0e4775", "brandBackgroundSelected": "#0f548c", + "brandBackgroundStatic": "#0f6cbd", "brandBackgroundTint": "#cfe4fa", "brandForeground1": "#0f6cbd", + "brandForeground1Disabled": "#2886de", "brandForeground1Pressed": "#0e4775", "brandForeground1Selected": "#0f548c", + "brandForeground2": "#0f6cbd", "brandForegroundDisabled1": "#2886de", "brandForegroundDisabled2": "#b4d6fa", + "brandForegroundLink": "#0f6cbd", + "brandForegroundLinkHover": "#0f6cbd", + "brandForegroundLinkPressed": "#0e4775", + "brandForegroundLinkSelected": "#0f548c", "brandForegroundTint": "#0f548c", "brandStroke1": "#0f6cbd", "brandStroke1Pressed": "#0e4775", "brandStroke1Selected": "#0f548c", + "brandStroke2": "#2886de", "brandStrokeTint": "#2886de", "brandedBackground": "#0f6cbd", - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#e0e0e0", + "buttonBackgroundHovered": "#ffffff", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", "checkboxBackground": "#0f6cbd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", + "checkboxBackgroundDisabled": "#e0e0e0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#0f6cbd", + "compoundBrandBackground1Hover": "#0f6cbd", + "compoundBrandBackground1Pressed": "#0e4775", + "compoundBrandForeground1": "#0f6cbd", + "compoundBrandForeground1Hover": "#0f6cbd", + "compoundBrandForeground1Pressed": "#0e4775", + "compoundBrandStroke1": "#0f6cbd", + "compoundBrandStroke1Hover": "#0f6cbd", + "compoundBrandStroke1Pressed": "#0e4775", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#d13438", + "dangerBackground3": "#d13438", + "dangerBorder1": "#dc5e62", + "dangerBorder2": "#d13438", + "dangerBorderActive": "#d13438", "dangerForeground1": "#bc2f32", "dangerForeground2": "#d13438", + "dangerForeground3": "#d13438", + "dangerForegroundInverted": "#dc5e62", "dangerStroke1": "#dc5e62", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#ffffff", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#e0e0e0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#ffffff", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#ffffff", + "defaultHoveredBorder": "#d1d1d1", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#808080", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#d1d1d1", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#808080", + "disabledBackground": "#e0e0e0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#616161", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#616161", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#808080", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#808080", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#808080", + "ghostSecondaryContent": "#808080", "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", + "inputBorder": "#d1d1d1", "inputFocusBorderAlt": "#0f6cbd", - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", + "inputPlaceholderText": "#808080", + "inputText": "#242424", "link": "#0f6cbd", - "linkHovered": "#0c3b5e", - "linkPressed": "#0f548c", - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", + "linkHovered": "#0f6cbd", + "linkPressed": "#0e4775", + "listHeaderBackgroundHovered": "#ffffff", + "listHeaderBackgroundPressed": "#e0e0e0", "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": "#0f6cbd", - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", + "menuDivider": "#e0e0e0", + "menuIcon": "#616161", + "menuItemBackgroundHovered": "#ffffff", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", "neutralBackground1": "#ffffff", + "neutralBackground1Hover": "#ffffff", "neutralBackground1Pressed": "#e0e0e0", "neutralBackground1Selected": "#ebebeb", "neutralBackground2": "#ffffff", + "neutralBackground2Hover": "#ffffff", "neutralBackground2Pressed": "#e0e0e0", "neutralBackground2Selected": "#ebebeb", "neutralBackground3": "#ffffff", + "neutralBackground3Hover": "#ffffff", "neutralBackground3Pressed": "#e0e0e0", "neutralBackground3Selected": "#ebebeb", "neutralBackground4": "#fafafa", + "neutralBackground4Hover": "#fafafa", "neutralBackground4Pressed": "#dbdbdb", "neutralBackground4Selected": "#e6e6e6", "neutralBackground5": "#f0f0f0", + "neutralBackground5Hover": "#f0f0f0", "neutralBackground5Pressed": "#d1d1d1", "neutralBackground5Selected": "#dbdbdb", "neutralBackground6": "#d1d1d1", @@ -1265,21 +2500,63 @@ exports[`defaultFluentTheme 1`] = ` "neutralBackgroundLightStatic": "#ffffff", "neutralBackgroundLightStaticDisabled": "#ffffff", "neutralForeground1": "#242424", + "neutralForeground1Hover": "#242424", + "neutralForeground1Pressed": "#242424", + "neutralForeground1Selected": "#242424", "neutralForeground2": "#616161", + "neutralForeground2BrandHover": "#616161", + "neutralForeground2BrandPressed": "#616161", + "neutralForeground2BrandSelected": "#616161", + "neutralForeground2Hover": "#616161", + "neutralForeground2Pressed": "#616161", + "neutralForeground2Selected": "#616161", "neutralForeground3": "#808080", + "neutralForeground3BrandHover": "#808080", + "neutralForeground3BrandPressed": "#808080", + "neutralForeground3BrandSelected": "#808080", + "neutralForeground3Hover": "#808080", + "neutralForeground3Pressed": "#808080", + "neutralForeground3Selected": "#808080", + "neutralForeground4": "#808080", "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#bdbdbd", "neutralForegroundDisabled1": "#bdbdbd", "neutralForegroundDisabled2": "#ffffff", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#ffffff", + "neutralForegroundInvertedLinkPressed": "#ffffff", + "neutralForegroundInvertedLinkSelected": "#ffffff", "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", "neutralStroke1": "#d1d1d1", + "neutralStroke1Hover": "#d1d1d1", + "neutralStroke1Pressed": "#d1d1d1", + "neutralStroke1Selected": "#d1d1d1", "neutralStroke2": "#e0e0e0", + "neutralStroke3": "#e0e0e0", "neutralStrokeAccessible": "#616161", + "neutralStrokeAccessibleHover": "#616161", + "neutralStrokeAccessiblePressed": "#616161", + "neutralStrokeAccessibleSelected": "#616161", "neutralStrokeDisabled": "#e0e0e0", "neutralStrokeFocus1": "#ffffff", "neutralStrokeFocus2": "#000000", + "outofofficeBackground1": "#fdf5fc", + "outofofficeBackground2": "#edbbe7", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#edbbe7", + "outofofficeBorder2": "#c239b3", + "outofofficeBorderActive": "#c239b3", + "outofofficeForeground1": "#af33a1", + "outofofficeForeground2": "#6d2064", + "outofofficeForeground3": "#c239b3", "personaActivityGlow": "#0f6cbd", "personaActivityRing": "#ffffff", "presenceAvailable": "#13a10e", @@ -1287,48 +2564,87 @@ exports[`defaultFluentTheme 1`] = ` "presenceDnd": "#d13438", "presenceOof": "#c239b3", "primaryButtonBackground": "#0f6cbd", - "primaryButtonBackgroundDisabled": "#f3f2f1", - "primaryButtonBackgroundHovered": "#115ea3", - "primaryButtonBackgroundPressed": "#0f548c", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", + "primaryButtonBackgroundDisabled": "#e0e0e0", + "primaryButtonBackgroundHovered": "#0f6cbd", + "primaryButtonBackgroundPressed": "#0e4775", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", + "primaryButtonTextDisabled": "#bdbdbd", "primaryButtonTextHovered": "#ffffff", "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#d13438", + "redBackground3": "#d13438", + "redBorder1": "#dc5e62", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#d13438", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#da3b01", + "severeBackground3": "#da3b01", + "severeBorder1": "#de501c", + "severeBorder2": "#da3b01", + "severeBorderActive": "#da3b01", "severeForeground1": "#c43501", "severeForeground2": "#a62d01", + "severeForeground3": "#da3b01", "severeStroke1": "#de501c", - "subText": "#605e5c", + "strokeFocus1": "#ffffff", + "strokeFocus2": "#000000", + "subText": "#616161", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#f5f5f5", + "subtleBackgroundPressed": "#e0e0e0", + "subtleBackgroundSelected": "#ebebeb", "successBackground1": "#f1faf1", "successBackground2": "#107c10", + "successBackground3": "#107c10", + "successBorder1": "#359b35", + "successBorder2": "#107c10", + "successBorderActive": "#107c10", "successForeground1": "#0e700e", "successForeground2": "#107c10", + "successForeground3": "#107c10", + "successForegroundInverted": "#359b35", "successStroke1": "#359b35", - "variantBorder": "#edebe9", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#e0e0e0", "warningBackground1": "#fffef5", "warningBackground2": "#fde300", + "warningBackground3": "#fde300", + "warningBorder1": "#817400", + "warningBorder2": "#fde300", + "warningBorderActive": "#fde300", "warningForeground1": "#817400", "warningForeground2": "#817400", + "warningForeground3": "#fde300", + "warningForegroundInverted": "#fef7b2", "warningStroke1": "#817400", }, "components": {}, "host": { - "appearance": "light", + "appearance": "highContrast", }, "shadows": { "shadow16": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 16, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 8, }, @@ -1350,13 +2666,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow2": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 2, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 1, }, @@ -1364,13 +2680,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow28": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 28, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 14, }, @@ -1406,13 +2722,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow4": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 4, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 2, }, @@ -1434,13 +2750,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow64": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 64, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 32, }, @@ -1462,13 +2778,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow8": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 8, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 4, }, @@ -1516,139 +2832,244 @@ exports[`defaultFluentTheme 1`] = ` }, "variants": { "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", }, "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", }, "body2": { - "face": "primary", - "size": "body", - "weight": "regular", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", }, "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", }, "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "600", }, "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", + "dynamicTypeRamp": "subheadline", + "face": "System", + "letterSpacing": -0.23, + "lineHeight": 20, + "size": 15, + "weight": "400", }, "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", }, "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "600", + }, + "caption2": { + "dynamicTypeRamp": "caption1", + "face": "System", + "letterSpacing": 0, + "lineHeight": 16, + "size": 12, + "weight": "400", }, "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", + "dynamicTypeRamp": "footnote", + "face": "System", + "letterSpacing": -0.08, + "lineHeight": 18, + "size": 13, + "weight": "400", }, "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", }, "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.26, + "lineHeight": 70, + "size": 60, + "weight": "700", }, "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", }, "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", }, "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", }, "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", + "dynamicTypeRamp": "largeTitle", + "face": "System", + "letterSpacing": 0.4, + "lineHeight": 41, + "size": 34, + "weight": "700", }, "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "600", }, "secondaryStandard": { - "face": "primary", - "size": "secondary", - "weight": "regular", + "dynamicTypeRamp": "body", + "face": "System", + "letterSpacing": -0.43, + "lineHeight": 22, + "size": 17, + "weight": "400", }, "subheaderSemibold": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subheaderStandard": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subtitle1": { - "face": "primary", - "size": "header", - "weight": "regular", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "subtitle1Strong": { - "face": "primary", - "size": "header", - "weight": "semiBold", + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", }, "subtitle2": { - "face": "primary", - "size": "subheader", - "weight": "regular", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "subtitle2Strong": { - "face": "primary", - "size": "subheader", - "weight": "semiBold", + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, "title1": { - "face": "primary", - "size": "hero", - "weight": "regular", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "700", }, "title1Strong": { - "face": "primary", - "size": "hero", - "weight": "semiBold", + "dynamicTypeRamp": "title1", + "face": "System", + "letterSpacing": 0.38, + "lineHeight": 34, + "size": 28, + "weight": "600", + }, + "title2": { + "dynamicTypeRamp": "title2", + "face": "System", + "letterSpacing": -0.26, + "lineHeight": 28, + "size": 22, + "weight": "600", + }, + "title3": { + "dynamicTypeRamp": "title3", + "face": "System", + "letterSpacing": -0.45, + "lineHeight": 25, + "size": 20, + "weight": "600", }, }, "weights": { diff --git a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.macos.ts.snap b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.macos.ts.snap index 861be6b0a4f..7516a1ccb24 100644 --- a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.macos.ts.snap +++ b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.macos.ts.snap @@ -3,64 +3,77 @@ exports[`defaultFluentDarkTheme 1`] = ` { "colors": { - "accentButtonBackground": "#185abd", - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "accentButtonBackground": "#0086f0", + "actionLink": "#ffffff", + "background": "#000000", + "bodyDivider": "#575757", + "bodyFrameBackground": "#000000", + "bodyFrameDivider": "#575757", + "bodyStandoutBackground": "#575757", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", - "brandBackground": "#1651aa", - "brandBackground2": "#004578", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#185abd", - "brandBackgroundPressed": "#004578", - "brandBackgroundSelected": "#13458f", - "brandBackgroundStatic": "#185abd", - "brandForeground1": "#6794d7", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#aec6eb", - "brandForegroundLink": "#2e6ac5", - "brandForegroundLinkHover": "#aec6eb", - "brandForegroundLinkPressed": "#6794d7", - "brandForegroundLinkSelected": "#2e6ac5", - "brandStroke1": "#2e6ac5", - "brandStroke2": "#0e336a", - "brandedBackground": "#2e6ac5", - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandBackground": "#0086f0", + "brandBackground2": "#092c47", + "brandBackground2Pressed": "#1890f1", + "brandBackground2Selected": "#3aa0f3", + "brandBackground3": "#092c47", + "brandBackgroundDisabled": "#575757", + "brandBackgroundHover": "#1890f1", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#575757", + "brandBackgroundPressed": "#1890f1", + "brandBackgroundSelected": "#3aa0f3", + "brandBackgroundStatic": "#0086f0", + "brandBackgroundTint": "#092c47", + "brandForeground1": "#0086f0", + "brandForeground1Disabled": "#c2c2c2", + "brandForeground1Pressed": "#6cb8f6", + "brandForeground1Selected": "#3aa0f3", + "brandForeground2": "#092c47", + "brandForegroundDisabled1": "#c2c2c2", + "brandForegroundDisabled2": "#c2c2c2", + "brandForegroundLink": "#043862", + "brandForegroundLinkHover": "#092c47", + "brandForegroundLinkPressed": "#0078d4", + "brandForegroundLinkSelected": "#092c47", + "brandForegroundTint": "#092c47", + "brandStroke1": "#0086f0", + "brandStroke1Pressed": "#6cb8f6", + "brandStroke1Selected": "#3aa0f3", + "brandStroke2": "#004c87", + "brandStrokeTint": "#004c87", + "brandedBackground": "#0086f0", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#000000", + "buttonBackgroundChecked": "#383838", + "buttonBackgroundDisabled": "#575757", + "buttonBackgroundHovered": "#3d3d3d", + "buttonBackgroundPressed": "#5c5c5c", + "buttonBorder": "#3d3d3d", + "buttonBorderDisabled": "#525252", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": "#2e6ac5", - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", - "compoundBrandBackground1": "#2e6ac5", - "compoundBrandBackground1Hover": "#6794d7", - "compoundBrandBackground1Pressed": "#185abd", - "compoundBrandForeground1": "#2e6ac5", - "compoundBrandForeground1Hover": "#6794d7", - "compoundBrandForeground1Pressed": "#185abd", - "compoundBrandStroke1": "#2e6ac5", - "compoundBrandStroke1Hover": "#6794d7", - "compoundBrandStroke1Pressed": "#185abd", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#b8b8b8", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#0086f0", + "checkboxBackgroundDisabled": "#575757", + "checkboxBorderColor": "#adadad", + "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#0086f0", + "compoundBrandBackground1Hover": "#1890f1", + "compoundBrandBackground1Pressed": "#6cb8f6", + "compoundBrandForeground1": "#043862", + "compoundBrandForeground1Hover": "#092c47", + "compoundBrandForeground1Pressed": "#0078d4", + "compoundBrandStroke1": "#0086f0", + "compoundBrandStroke1Hover": "#1890f1", + "compoundBrandStroke1Pressed": "#6cb8f6", "dangerBackground1": "#3f1011", "dangerBackground2": "#751d1f", "dangerBackground3": "#d13438", @@ -71,148 +84,160 @@ exports[`defaultFluentDarkTheme 1`] = ` "dangerForeground2": "#f1bbbc", "dangerForeground3": "#e37d80", "dangerForegroundInverted": "#d13438", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "dangerStroke1": "#d13438", + "defaultBackground": "#000000", + "defaultBorder": "#3d3d3d", + "defaultCheckedBackground": "#383838", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#3d3d3d", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#575757", + "defaultDisabledBorder": "#525252", + "defaultDisabledContent": "#b8b8b8", + "defaultDisabledIcon": "#b8b8b8", + "defaultFocusedBackground": "#3d3d3d", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#3d3d3d", + "defaultHoveredBorder": "#757575", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#d6d6d6", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", + "defaultPressedBackground": "#5c5c5c", + "defaultPressedBorder": "#6b6b6b", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#d6d6d6", + "disabledBackground": "#575757", + "disabledBodyText": "#b8b8b8", + "disabledText": "#b8b8b8", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": "#2e6ac5", - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": "#2e6ac5", - "linkHovered": "#82c7ff", - "linkPressed": "#aec6eb", - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": "#6794d7", - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", - "neutralBackground1": "#292929", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#ffffff", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#b8b8b8", + "ghostDisabledIcon": "#b8b8b8", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#d6d6d6", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#d6d6d6", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#000000", + "inputBorder": "#3d3d3d", + "inputFocusBorderAlt": "#0086f0", + "inputPlaceholderText": "#858585", + "inputText": "#ffffff", + "link": "#043862", + "linkHovered": "#092c47", + "linkPressed": "#0078d4", + "listHeaderBackgroundHovered": "#3d3d3d", + "listHeaderBackgroundPressed": "#5c5c5c", + "menuBackground": "#000000", + "menuDivider": "#575757", + "menuIcon": "#ffffff", + "menuItemBackgroundHovered": "#3d3d3d", + "menuItemBackgroundPressed": "#5c5c5c", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", + "neutralBackground1": "#000000", "neutralBackground1Hover": "#3d3d3d", - "neutralBackground1Pressed": "#1f1f1f", + "neutralBackground1Pressed": "#5c5c5c", "neutralBackground1Selected": "#383838", - "neutralBackground2": "#1f1f1f", + "neutralBackground2": "#575757", "neutralBackground2Hover": "#333333", - "neutralBackground2Pressed": "#141414", + "neutralBackground2Pressed": "#707070", "neutralBackground2Selected": "#2e2e2e", - "neutralBackground3": "#141414", + "neutralBackground3": "#575757", "neutralBackground3Hover": "#292929", "neutralBackground3Pressed": "#0a0a0a", "neutralBackground3Selected": "#242424", - "neutralBackground4": "#0a0a0a", + "neutralBackground4": "#1f1f1f", "neutralBackground4Hover": "#1f1f1f", "neutralBackground4Pressed": "#000000", "neutralBackground4Selected": "#1a1a1a", - "neutralBackground5": "#000000", + "neutralBackground5": "#5c5c5c", "neutralBackground5Hover": "#141414", "neutralBackground5Pressed": "#050505", "neutralBackground5Selected": "#0f0f0f", "neutralBackground6": "#333333", - "neutralBackgroundDisabled": "#141414", + "neutralBackgroundCanvas": "#000000", + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": "#575757", "neutralBackgroundInverted": "#ffffff", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#575757", "neutralForeground1": "#ffffff", "neutralForeground1Hover": "#ffffff", "neutralForeground1Pressed": "#ffffff", "neutralForeground1Selected": "#ffffff", - "neutralForeground2": "#d6d6d6", - "neutralForeground2BrandHover": "#6794d7", - "neutralForeground2BrandPressed": "#2e6ac5", - "neutralForeground2BrandSelected": "#6794d7", + "neutralForeground2": "#ffffff", + "neutralForeground2BrandHover": "#092c47", + "neutralForeground2BrandPressed": "#0078d4", + "neutralForeground2BrandSelected": "#092c47", "neutralForeground2Hover": "#ffffff", "neutralForeground2Pressed": "#ffffff", "neutralForeground2Selected": "#ffffff", "neutralForeground3": "#adadad", - "neutralForeground3BrandHover": "#6794d7", - "neutralForeground3BrandPressed": "#2e6ac5", - "neutralForeground3BrandSelected": "#6794d7", + "neutralForeground3BrandHover": "#092c47", + "neutralForeground3BrandPressed": "#0078d4", + "neutralForeground3BrandSelected": "#092c47", "neutralForeground3Hover": "#d6d6d6", "neutralForeground3Pressed": "#d6d6d6", "neutralForeground3Selected": "#d6d6d6", - "neutralForeground4": "#999999", - "neutralForegroundDisabled": "#5c5c5c", - "neutralForegroundInverted": "#242424", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForeground4": "#858585", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#b8b8b8", + "neutralForegroundDisabled1": "#b8b8b8", + "neutralForegroundDisabled2": "#b8b8b8", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#292929", + "neutralForegroundInvertedLinkHover": "#292929", + "neutralForegroundInvertedLinkPressed": "#292929", + "neutralForegroundInvertedLinkSelected": "#292929", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#333333", "neutralStencil2": "#575757", - "neutralStroke1": "#666666", + "neutralStroke1": "#3d3d3d", "neutralStroke1Hover": "#757575", "neutralStroke1Pressed": "#6b6b6b", "neutralStroke1Selected": "#707070", - "neutralStroke2": "#525252", - "neutralStroke3": "#3d3d3d", + "neutralStroke2": "#575757", + "neutralStroke3": "#666666", "neutralStrokeAccessible": "#adadad", "neutralStrokeAccessibleHover": "#bdbdbd", "neutralStrokeAccessiblePressed": "#b3b3b3", - "neutralStrokeAccessibleSelected": "#6794d7", - "neutralStrokeDisabled": "#424242", + "neutralStrokeAccessibleSelected": "#0086f0", + "neutralStrokeDisabled": "#525252", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", "outofofficeBackground1": "#3a1136", "outofofficeBackground2": "#6d2064", "outofofficeBackground3": "#c239b3", @@ -222,18 +247,31 @@ exports[`defaultFluentDarkTheme 1`] = ` "outofofficeForeground1": "#da7ed0", "outofofficeForeground2": "#edbbe7", "outofofficeForeground3": "#d161c4", - "personaActivityGlow": "#2e6ac5", - "personaActivityRing": "#1b1a19", - "primaryButtonBackground": "#2e6ac5", - "primaryButtonBackgroundDisabled": "#252423", - "primaryButtonBackgroundHovered": "#6794d7", - "primaryButtonBackgroundPressed": "#aec6eb", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "personaActivityGlow": "#0086f0", + "personaActivityRing": "#000000", + "presenceAvailable": "#54b054", + "presenceAway": "#feee66", + "presenceDnd": "#e37d80", + "presenceOof": "#da7ed0", + "primaryButtonBackground": "#0086f0", + "primaryButtonBackgroundDisabled": "#575757", + "primaryButtonBackgroundHovered": "#1890f1", + "primaryButtonBackgroundPressed": "#1890f1", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#b8b8b8", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#751d1f", + "redBackground3": "#d13438", + "redBorder1": "#d13438", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#f1bbbc", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#7a2101", "severeBackground3": "#da3b01", @@ -243,23 +281,705 @@ exports[`defaultFluentDarkTheme 1`] = ` "severeForeground1": "#e9835e", "severeForeground2": "#f4bfab", "severeForeground3": "#e9835e", + "severeStroke1": "#da3b01", "strokeFocus1": "#000000", "strokeFocus2": "#ffffff", - "subText": "#a19f9d", + "subText": "#ffffff", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", + "successBackground1": "#052505", + "successBackground2": "#094509", + "successBackground3": "#107c10", + "successBorder1": "#107c10", + "successBorder2": "#9fd89f", + "successBorderActive": "#54b054", + "successForeground1": "#54b054", + "successForeground2": "#9fd89f", + "successForeground3": "#9fd89f", + "successForegroundInverted": "#107c10", + "successStroke1": "#107c10", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#575757", + "warningBackground1": "#4c4400", + "warningBackground2": "#817400", + "warningBackground3": "#fde300", + "warningBorder1": "#fde300", + "warningBorder2": "#fdea3d", + "warningBorderActive": "#feee66", + "warningForeground1": "#feee66", + "warningForeground2": "#fef7b2", + "warningForeground3": "#fdea3d", + "warningForegroundInverted": "#817400", + "warningStroke1": "#fde300", + }, + "components": {}, + "host": { + "appearance": "dark", + }, + "shadows": { + "shadow16": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000047", + "x": 0, + "y": 8, + }, + }, + "shadow16brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000040", + "x": 0, + "y": 8, + }, + }, + "shadow2": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000047", + "x": 0, + "y": 1, + }, + }, + "shadow28": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#0000007a", + "x": 0, + "y": 14, + }, + }, + "shadow28brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000040", + "x": 0, + "y": 14, + }, + }, + "shadow2brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000040", + "x": 0, + "y": 1, + }, + }, + "shadow4": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000047", + "x": 0, + "y": 2, + }, + }, + "shadow4brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000040", + "x": 0, + "y": 2, + }, + }, + "shadow64": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#0000007a", + "x": 0, + "y": 32, + }, + }, + "shadow64brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000040", + "x": 0, + "y": 32, + }, + }, + "shadow8": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000047", + "x": 0, + "y": 4, + }, + }, + "shadow8brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000040", + "x": 0, + "y": 4, + }, + }, + }, + "spacing": { + "l1": "20px", + "l2": "32px", + "m": "16px", + "s1": "8px", + "s2": "4px", + }, + "typography": { + "families": { + "cursive": "Helvetica Neue", + "monospace": "Courier New", + "numeric": "Helvetica Neue", + "primary": "Helvetica Neue", + "sansSerif": "Helvetica Neue", + "secondary": "Helvetica Neue", + "serif": "Helvetica Neue", + }, + "sizes": { + "body": 14, + "caption": 10, + "header": 20, + "hero": 28, + "heroLarge": 40, + "secondary": 12, + "subheader": 16, + }, + "variants": { + "body1": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "body1Strong": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "body2": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "body2Strong": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodySemibold": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodyStandard": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "caption1": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "caption1Strong": { + "face": "primary", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "captionStandard": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "display": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "headerSemibold": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "headerStandard": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "heroLargeSemibold": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "heroLargeStandard": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "heroSemibold": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "heroStandard": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "largeTitle": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "secondarySemibold": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "secondaryStandard": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "subheaderSemibold": { + "face": "primary", + "size": 16, + "weight": "600", + }, + "subheaderStandard": { + "face": "primary", + "size": 16, + "weight": "400", + }, + "subtitle1": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "subtitle1Strong": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "subtitle2": { + "face": "primary", + "size": 16, + "weight": "400", + }, + "subtitle2Strong": { + "face": "primary", + "size": 16, + "weight": "600", + }, + "title1": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "title1Strong": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", + }, + }, + "weights": { + "regular": "400", + "semiBold": "600", + }, + }, +} +`; + +exports[`defaultFluentTheme 1`] = ` +{ + "colors": { + "accentButtonBackground": "#0078d4", + "actionLink": "#242424", + "background": "#ffffff", + "bodyDivider": "#d6d6d6", + "bodyFrameBackground": "#ffffff", + "bodyFrameDivider": "#d6d6d6", + "bodyStandoutBackground": "#ffffff", + "bodyText": "#242424", + "bodyTextChecked": "#242424", + "brandBackground": "#0078d4", + "brandBackground2": "#eff6fc", + "brandBackground2Pressed": "#106ebe", + "brandBackground2Selected": "#005a9e", + "brandBackground3": "#eff6fc", + "brandBackgroundDisabled": "#d1d1d1", + "brandBackgroundHover": "#106ebe", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", + "brandBackgroundPressed": "#106ebe", + "brandBackgroundSelected": "#005a9e", + "brandBackgroundStatic": "#0078d4", + "brandBackgroundTint": "#eff6fc", + "brandForeground1": "#0078d4", + "brandForeground1Disabled": "#757575", + "brandForeground1Pressed": "#004578", + "brandForeground1Selected": "#005a9e", + "brandForeground2": "#106ebe", + "brandForegroundDisabled1": "#757575", + "brandForegroundDisabled2": "#757575", + "brandForegroundLink": "#0078d4", + "brandForegroundLinkHover": "#106ebe", + "brandForegroundLinkPressed": "#004578", + "brandForegroundLinkSelected": "#005a9e", + "brandForegroundTint": "#106ebe", + "brandStroke1": "#0078d4", + "brandStroke1Pressed": "#004578", + "brandStroke1Selected": "#005a9e", + "brandStroke2": "#c7e0f4", + "brandStrokeTint": "#c7e0f4", + "brandedBackground": "#0078d4", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#f0f0f0", + "buttonBackgroundHovered": "#f5f5f5", + "buttonBackgroundPressed": "#ebebeb", + "buttonBorder": "#f0f0f0", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#757575", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", + "checkboxBackground": "#0078d4", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#616161", + "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#0078d4", + "compoundBrandBackground1Hover": "#106ebe", + "compoundBrandBackground1Pressed": "#004578", + "compoundBrandForeground1": "#0078d4", + "compoundBrandForeground1Hover": "#106ebe", + "compoundBrandForeground1Pressed": "#004578", + "compoundBrandStroke1": "#0078d4", + "compoundBrandStroke1Hover": "#106ebe", + "compoundBrandStroke1Pressed": "#004578", + "dangerBackground1": "#fdf6f6", + "dangerBackground2": "#f1bbbc", + "dangerBackground3": "#d13438", + "dangerBorder1": "#f1bbbc", + "dangerBorder2": "#d13438", + "dangerBorderActive": "#d13438", + "dangerForeground1": "#bc2f32", + "dangerForeground2": "#751d1f", + "dangerForeground3": "#d13438", + "dangerForegroundInverted": "#dc5e62", + "dangerStroke1": "#f1bbbc", + "defaultBackground": "#ffffff", + "defaultBorder": "#f0f0f0", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#f5f5f5", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#f0f0f0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#757575", + "defaultDisabledIcon": "#757575", + "defaultFocusedBackground": "#f5f5f5", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#f5f5f5", + "defaultHoveredBorder": "#c7c7c7", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#424242", + "defaultIcon": "#242424", + "defaultPressedBackground": "#ebebeb", + "defaultPressedBorder": "#b3b3b3", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#424242", + "disabledBackground": "#f0f0f0", + "disabledBodyText": "#757575", + "disabledText": "#757575", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#242424", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#242424", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#757575", + "ghostDisabledIcon": "#757575", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#616161", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#424242", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#424242", + "ghostSecondaryContent": "#616161", + "inputBackground": "#ffffff", + "inputBorder": "#f0f0f0", + "inputFocusBorderAlt": "#0078d4", + "inputPlaceholderText": "#808080", + "inputText": "#242424", + "link": "#0078d4", + "linkHovered": "#106ebe", + "linkPressed": "#004578", + "listHeaderBackgroundHovered": "#f5f5f5", + "listHeaderBackgroundPressed": "#ebebeb", + "menuBackground": "#ffffff", + "menuDivider": "#d6d6d6", + "menuIcon": "#000000", + "menuItemBackgroundHovered": "#f5f5f5", + "menuItemBackgroundPressed": "#ebebeb", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", + "neutralBackground1": "#ffffff", + "neutralBackground1Hover": "#f5f5f5", + "neutralBackground1Pressed": "#ebebeb", + "neutralBackground1Selected": "#ebebeb", + "neutralBackground2": "#ffffff", + "neutralBackground2Hover": "#f0f0f0", + "neutralBackground2Pressed": "#ebebeb", + "neutralBackground2Selected": "#e6e6e6", + "neutralBackground3": "#f5f5f5", + "neutralBackground3Hover": "#ebebeb", + "neutralBackground3Pressed": "#d6d6d6", + "neutralBackground3Selected": "#e0e0e0", + "neutralBackground4": "#f0f0f0", + "neutralBackground4Hover": "#fafafa", + "neutralBackground4Pressed": "#f5f5f5", + "neutralBackground4Selected": "#ffffff", + "neutralBackground5": "#ebebeb", + "neutralBackground5Hover": "#f5f5f5", + "neutralBackground5Pressed": "#f0f0f0", + "neutralBackground5Selected": "#fafafa", + "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", + "neutralBackgroundDisabled": "#f0f0f0", + "neutralBackgroundInverted": "#616161", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", + "neutralForeground1": "#242424", + "neutralForeground1Hover": "#242424", + "neutralForeground1Pressed": "#242424", + "neutralForeground1Selected": "#242424", + "neutralForeground2": "#000000", + "neutralForeground2BrandHover": "#106ebe", + "neutralForeground2BrandPressed": "#004578", + "neutralForeground2BrandSelected": "#005a9e", + "neutralForeground2Hover": "#242424", + "neutralForeground2Pressed": "#242424", + "neutralForeground2Selected": "#242424", + "neutralForeground3": "#616161", + "neutralForeground3BrandHover": "#106ebe", + "neutralForeground3BrandPressed": "#004578", + "neutralForeground3BrandSelected": "#005a9e", + "neutralForeground3Hover": "#424242", + "neutralForeground3Pressed": "#424242", + "neutralForeground3Selected": "#424242", + "neutralForeground4": "#808080", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#757575", + "neutralForegroundDisabled1": "#757575", + "neutralForegroundDisabled2": "#757575", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#ffffff", + "neutralForegroundInvertedLinkPressed": "#ffffff", + "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", + "neutralStencil1": "#e6e6e6", + "neutralStencil2": "#fafafa", + "neutralStroke1": "#f0f0f0", + "neutralStroke1Hover": "#c7c7c7", + "neutralStroke1Pressed": "#b3b3b3", + "neutralStroke1Selected": "#bdbdbd", + "neutralStroke2": "#d6d6d6", + "neutralStroke3": "#f0f0f0", + "neutralStrokeAccessible": "#616161", + "neutralStrokeAccessibleHover": "#575757", + "neutralStrokeAccessiblePressed": "#4d4d4d", + "neutralStrokeAccessibleSelected": "#0078d4", + "neutralStrokeDisabled": "#e0e0e0", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", + "outofofficeBackground1": "#fdf5fc", + "outofofficeBackground2": "#edbbe7", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#edbbe7", + "outofofficeBorder2": "#c239b3", + "outofofficeBorderActive": "#c239b3", + "outofofficeForeground1": "#af33a1", + "outofofficeForeground2": "#6d2064", + "outofofficeForeground3": "#c239b3", + "personaActivityGlow": "#0078d4", + "personaActivityRing": "#ffffff", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", + "primaryButtonBackground": "#0078d4", + "primaryButtonBackgroundDisabled": "#f0f0f0", + "primaryButtonBackgroundHovered": "#106ebe", + "primaryButtonBackgroundPressed": "#106ebe", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#757575", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", + "severeBackground1": "#fdf6f3", + "severeBackground2": "#f4bfab", + "severeBackground3": "#da3b01", + "severeBorder1": "#f4bfab", + "severeBorder2": "#da3b01", + "severeBorderActive": "#da3b01", + "severeForeground1": "#c43501", + "severeForeground2": "#7a2101", + "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", + "strokeFocus1": "#ffffff", + "strokeFocus2": "#000000", + "subText": "#000000", "subtleBackground": "#00000000", - "subtleBackgroundHover": "#383838", - "subtleBackgroundPressed": "#2e2e2e", - "subtleBackgroundSelected": "#333333", - "successBackground1": "#052505", - "successBackground2": "#094509", + "subtleBackgroundHover": "#f5f5f5", + "subtleBackgroundPressed": "#e0e0e0", + "subtleBackgroundSelected": "#ebebeb", + "successBackground1": "#f1faf1", + "successBackground2": "#9fd89f", "successBackground3": "#107c10", - "successBorder1": "#107c10", - "successBorder2": "#9fd89f", - "successBorderActive": "#54b054", - "successForeground1": "#54b054", - "successForeground2": "#9fd89f", - "successForeground3": "#9fd89f", - "successForegroundInverted": "#107c10", + "successBorder1": "#9fd89f", + "successBorder2": "#107c10", + "successBorderActive": "#107c10", + "successForeground1": "#0e700e", + "successForeground2": "#094509", + "successForeground3": "#107c10", + "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -267,33 +987,34 @@ exports[`defaultFluentDarkTheme 1`] = ` "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#292827", - "warningBackground1": "#4c4400", - "warningBackground2": "#817400", + "variantBorder": "#d6d6d6", + "warningBackground1": "#fffef5", + "warningBackground2": "#fef7b2", "warningBackground3": "#fde300", - "warningBorder1": "#fde300", - "warningBorder2": "#fdea3d", - "warningBorderActive": "#feee66", - "warningForeground1": "#feee66", - "warningForeground2": "#fef7b2", - "warningForeground3": "#fdea3d", - "warningForegroundInverted": "#817400", + "warningBorder1": "#fef7b2", + "warningBorder2": "#fde300", + "warningBorderActive": "#fde300", + "warningForeground1": "#817400", + "warningForeground2": "#817400", + "warningForeground3": "#fde300", + "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", }, "components": {}, "host": { - "appearance": "dark", + "appearance": "light", }, "shadows": { "shadow16": { "ambient": { "blur": 2, - "color": "#0000003d", + "color": "#0000001f", "x": 0, "y": 0, }, "key": { "blur": 16, - "color": "#00000047", + "color": "#00000024", "x": 0, "y": 8, }, @@ -315,13 +1036,13 @@ exports[`defaultFluentDarkTheme 1`] = ` "shadow2": { "ambient": { "blur": 2, - "color": "#0000003d", + "color": "#0000001f", "x": 0, "y": 0, }, "key": { "blur": 2, - "color": "#00000047", + "color": "#00000024", "x": 0, "y": 1, }, @@ -329,13 +1050,13 @@ exports[`defaultFluentDarkTheme 1`] = ` "shadow28": { "ambient": { "blur": 8, - "color": "#00000066", + "color": "#00000033", "x": 0, "y": 0, }, "key": { "blur": 28, - "color": "#0000007a", + "color": "#0000003d", "x": 0, "y": 14, }, @@ -371,13 +1092,13 @@ exports[`defaultFluentDarkTheme 1`] = ` "shadow4": { "ambient": { "blur": 2, - "color": "#0000003d", + "color": "#0000001f", "x": 0, "y": 0, }, "key": { "blur": 4, - "color": "#00000047", + "color": "#00000024", "x": 0, "y": 2, }, @@ -399,13 +1120,13 @@ exports[`defaultFluentDarkTheme 1`] = ` "shadow64": { "ambient": { "blur": 8, - "color": "#00000066", + "color": "#00000033", "x": 0, "y": 0, }, "key": { "blur": 64, - "color": "#0000007a", + "color": "#0000003d", "x": 0, "y": 32, }, @@ -427,13 +1148,13 @@ exports[`defaultFluentDarkTheme 1`] = ` "shadow8": { "ambient": { "blur": 2, - "color": "#0000003d", + "color": "#0000001f", "x": 0, "y": 0, }, "key": { "blur": 8, - "color": "#00000047", + "color": "#00000024", "x": 0, "y": 4, }, @@ -462,13 +1183,13 @@ exports[`defaultFluentDarkTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "System", - "sansSerif": "System", - "secondary": "System", - "serif": "System", + "cursive": "Helvetica Neue", + "monospace": "Courier New", + "numeric": "Helvetica Neue", + "primary": "Helvetica Neue", + "sansSerif": "Helvetica Neue", + "secondary": "Helvetica Neue", + "serif": "Helvetica Neue", }, "sizes": { "body": 14, @@ -482,138 +1203,153 @@ exports[`defaultFluentDarkTheme 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -624,852 +1360,325 @@ exports[`defaultFluentDarkTheme 1`] = ` } `; -exports[`defaultFluentHighConstrastTheme 1`] = ` +exports[`high contrast dark theme 1`] = ` { "colors": { - "accentButtonBackground": "#000000", - "actionLink": "#ffff00", + "accentButtonBackground": "#0086f0", + "actionLink": "#ffffff", "background": "#000000", - "bodyDivider": "#ffffff", + "bodyDivider": "#a8a8a8", "bodyFrameBackground": "#000000", - "bodyFrameDivider": "#000000", - "bodyStandoutBackground": "#000000", + "bodyFrameDivider": "#a8a8a8", + "bodyStandoutBackground": "#575757", "bodyText": "#ffffff", - "bodyTextChecked": "#000000", - "brandBackground": { - "semantic": [ - "SystemColorButtonFaceColor", - ], - }, - "brandBackground2": { - "semantic": [ - "SystemColorButtonFaceColor", - ], - }, - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "brandBackgroundPressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "brandBackgroundSelected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "brandBackgroundStatic": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "brandForeground1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": { - "semantic": [ - "SystemColorButtonTextColor", - ], - }, - "brandForegroundLink": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "brandForegroundLinkHover": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "brandForegroundLinkPressed": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "brandForegroundLinkSelected": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "brandStroke1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "brandStroke2": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "brandedBackground": "#000000", - "brandedDisabledBorder": "#3ff23f", + "bodyTextChecked": "#ffffff", + "brandBackground": "#0086f0", + "brandBackground2": "#092c47", + "brandBackground2Pressed": "#1890f1", + "brandBackground2Selected": "#3aa0f3", + "brandBackground3": "#092c47", + "brandBackgroundDisabled": "#575757", + "brandBackgroundHover": "#1890f1", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#575757", + "brandBackgroundPressed": "#1890f1", + "brandBackgroundSelected": "#3aa0f3", + "brandBackgroundStatic": "#0086f0", + "brandBackgroundTint": "#092c47", + "brandForeground1": "#0086f0", + "brandForeground1Disabled": "#c2c2c2", + "brandForeground1Pressed": "#6cb8f6", + "brandForeground1Selected": "#3aa0f3", + "brandForeground2": "#092c47", + "brandForegroundDisabled1": "#c2c2c2", + "brandForegroundDisabled2": "#c2c2c2", + "brandForegroundLink": "#043862", + "brandForegroundLinkHover": "#092c47", + "brandForegroundLinkPressed": "#0078d4", + "brandForegroundLinkSelected": "#092c47", + "brandForegroundTint": "#092c47", + "brandStroke1": "#0086f0", + "brandStroke1Pressed": "#6cb8f6", + "brandStroke1Selected": "#3aa0f3", + "brandStroke2": "#004c87", + "brandStrokeTint": "#004c87", + "brandedBackground": "#0086f0", + "brandedDisabledBorder": "#d6d6d6", "brandedFocusedSecondaryContent": "#ffffff", - "brandedHoveredSecondaryContent": "#000000", - "brandedPressedSecondaryContent": "#000000", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", "brandedSecondaryContent": "#ffffff", "buttonBackground": "#000000", - "buttonBackgroundChecked": "#1aebff", - "buttonBackgroundDisabled": "#000000", - "buttonBackgroundHovered": "#1aebff", - "buttonBackgroundPressed": "#1aebff", - "buttonBorder": "#ffffff", - "buttonBorderDisabled": "#3ff23f", + "buttonBackgroundChecked": "#383838", + "buttonBackgroundDisabled": "#575757", + "buttonBackgroundHovered": "#3d3d3d", + "buttonBackgroundPressed": "#5c5c5c", + "buttonBorder": "#adadad", + "buttonBorderDisabled": "#525252", "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#000000", - "buttonTextDisabled": "#3ff23f", - "buttonTextHovered": "#000000", - "buttonTextPressed": "#000000", - "checkboxBackground": "#000000", - "checkboxBackgroundDisabled": "#000000", - "checkboxBorderColor": "#ffffff", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#b8b8b8", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#0086f0", + "checkboxBackgroundDisabled": "#575757", + "checkboxBorderColor": "#d6d6d6", "checkmarkColor": "#ffffff", - "compoundBrandBackground1": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandBackground1Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandBackground1Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandForeground1": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandForeground1Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandForeground1Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandStroke1": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandStroke1Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandStroke1Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "dangerBackground1": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "dangerBackground2": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "dangerBackground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "dangerBorder1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "dangerBorder2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "dangerBorderActive": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "dangerForeground1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "dangerForeground2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "dangerForeground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "dangerForegroundInverted": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, + "compoundBrandBackground1": "#0086f0", + "compoundBrandBackground1Hover": "#1890f1", + "compoundBrandBackground1Pressed": "#6cb8f6", + "compoundBrandForeground1": "#043862", + "compoundBrandForeground1Hover": "#092c47", + "compoundBrandForeground1Pressed": "#0078d4", + "compoundBrandStroke1": "#0086f0", + "compoundBrandStroke1Hover": "#1890f1", + "compoundBrandStroke1Pressed": "#6cb8f6", + "dangerBackground1": "#3f1011", + "dangerBackground2": "#751d1f", + "dangerBackground3": "#d13438", + "dangerBorder1": "#d13438", + "dangerBorder2": "#dc5e62", + "dangerBorderActive": "#e37d80", + "dangerForeground1": "#e37d80", + "dangerForeground2": "#f1bbbc", + "dangerForeground3": "#e37d80", + "dangerForegroundInverted": "#d13438", + "dangerStroke1": "#d13438", "defaultBackground": "#000000", - "defaultBorder": "#ffffff", - "defaultCheckedBackground": "#1aebff", - "defaultCheckedContent": "#000000", - "defaultCheckedHoveredBackground": "#1aebff", - "defaultCheckedHoveredContent": "#000000", + "defaultBorder": "#adadad", + "defaultCheckedBackground": "#383838", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#3d3d3d", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#000000", - "defaultDisabledBorder": "#3ff23f", - "defaultDisabledContent": "#3ff23f", - "defaultDisabledIcon": "#3ff23f", - "defaultFocusedBackground": "#000000", + "defaultDisabledBackground": "#575757", + "defaultDisabledBorder": "#525252", + "defaultDisabledContent": "#b8b8b8", + "defaultDisabledIcon": "#b8b8b8", + "defaultFocusedBackground": "#3d3d3d", "defaultFocusedBorder": "#ffffff", "defaultFocusedContent": "#ffffff", "defaultFocusedIcon": "#ffffff", - "defaultHoveredBackground": "#1aebff", - "defaultHoveredBorder": "#1aebff", - "defaultHoveredContent": "#000000", - "defaultHoveredIcon": "#000000", - "defaultHoveredSecondaryContent": "#000000", + "defaultHoveredBackground": "#3d3d3d", + "defaultHoveredBorder": "#757575", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#d6d6d6", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#1aebff", - "defaultPressedBorder": "#1aebff", - "defaultPressedContent": "#000000", - "defaultPressedIcon": "#000000", - "defaultPressedSecondaryContent": "#000000", - "disabledBackground": "#000000", - "disabledBodyText": "#3ff23f", - "disabledText": "#3ff23f", - "errorText": "#ffffff", + "defaultPressedBackground": "#5c5c5c", + "defaultPressedBorder": "#6b6b6b", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#d6d6d6", + "disabledBackground": "#575757", + "disabledBodyText": "#b8b8b8", + "disabledText": "#b8b8b8", + "errorText": "#e37d80", "focusBorder": "#ffffff", - "ghostBackground": "#000000", - "ghostBorder": "#000000", - "ghostCheckedBackground": "#1aebff", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#1aebff", - "ghostCheckedHoveredBorder": "#000000", - "ghostCheckedHoveredContent": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#3aa0f3", + "ghostCheckedBackground": "#383838", + "ghostCheckedContent": "#ffffff", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#3aa0f3", + "ghostCheckedHoveredContent": "#ffffff", "ghostContent": "#ffffff", - "ghostDisabledBackground": "#000000", - "ghostDisabledBorder": "#000000", - "ghostDisabledContent": "#3ff23f", - "ghostDisabledIcon": "#3ff23f", - "ghostFocusedBackground": "#000000", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#d6d6d6", + "ghostDisabledContent": "#b8b8b8", + "ghostDisabledIcon": "#b8b8b8", + "ghostFocusedBackground": "#3d3d3d", "ghostFocusedBorder": "#ffffff", "ghostFocusedContent": "#ffffff", "ghostFocusedIcon": "#ffffff", - "ghostFocusedSecondaryContent": "#ffffff", - "ghostHoveredBackground": "#1aebff", - "ghostHoveredBorder": "#1aebff", - "ghostHoveredContent": "#000000", - "ghostHoveredIcon": "#000000", - "ghostHoveredSecondaryContent": "#000000", + "ghostFocusedSecondaryContent": "#d6d6d6", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#3aa0f3", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#d6d6d6", "ghostIcon": "#ffffff", - "ghostPressedBackground": "#1aebff", - "ghostPressedBorder": "#1aebff", - "ghostPressedContent": "#000000", - "ghostPressedIcon": "#000000", - "ghostPressedSecondaryContent": "#000000", - "ghostSecondaryContent": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#3aa0f3", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#d6d6d6", + "ghostSecondaryContent": "#d6d6d6", "inputBackground": "#000000", - "inputBorder": "#ffffff", - "inputFocusBorderAlt": "#ffffff", - "inputPlaceholderText": "#ffffff", + "inputBorder": "#adadad", + "inputFocusBorderAlt": "#0086f0", + "inputPlaceholderText": "#d6d6d6", "inputText": "#ffffff", - "link": "#ffff00", - "linkHovered": "#ffffff", - "linkPressed": "#ffffff", - "listHeaderBackgroundHovered": "#1aebff", - "listHeaderBackgroundPressed": "#1aebff", + "link": "#043862", + "linkHovered": "#092c47", + "linkPressed": "#0078d4", + "listHeaderBackgroundHovered": "#3d3d3d", + "listHeaderBackgroundPressed": "#5c5c5c", "menuBackground": "#000000", - "menuDivider": "#ffffff", + "menuDivider": "#a8a8a8", "menuIcon": "#ffffff", - "menuItemBackgroundHovered": "#1aebff", - "menuItemBackgroundPressed": "#1aebff", + "menuItemBackgroundHovered": "#3d3d3d", + "menuItemBackgroundPressed": "#5c5c5c", "menuItemText": "#ffffff", - "menuItemTextHovered": "#000000", - "neutralBackground1": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralBackground1Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground1Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground1Selected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground2": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralBackground2Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground2Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground2Selected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground3": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralBackground3Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground3Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground3Selected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground4": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralBackground4Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground4Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground4Selected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground5": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralBackground5Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground5Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground5Selected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground6": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralBackgroundDisabled": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralBackgroundInverted": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralForeground1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralForeground1Hover": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground1Pressed": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground1Selected": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralForeground2BrandHover": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground2BrandPressed": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground2BrandSelected": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground2Hover": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground2Pressed": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground2Selected": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralForeground3BrandHover": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground3BrandPressed": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground3BrandSelected": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground3Hover": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground3Pressed": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground3Selected": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForeground4": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralForegroundDisabled": { - "semantic": [ - "SystemColorGrayTextColor", - ], - }, - "neutralForegroundInverted": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "neutralForegroundInvertedLink": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "neutralForegroundInvertedLinkHover": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "neutralForegroundInvertedLinkPressed": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "neutralForegroundInvertedLinkSelected": { - "semantic": [ - "SystemColorHotlightColor", - ], - }, - "neutralForegroundOnBrand": { - "semantic": [ - "SystemColorButtonTextColor", - ], - }, - "neutralForegroundOnBrandHover": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForegroundOnBrandPressed": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralForegroundOnBrandSelected": { - "semantic": [ - "SystemColorHighlightTextColor", - ], - }, - "neutralStencil1": "#141414", - "neutralStencil2": "#858585", - "neutralStroke1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralStroke1Hover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralStroke1Pressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralStroke1Selected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralStroke2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralStroke3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralStrokeAccessible": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "neutralStrokeAccessibleHover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralStrokeAccessiblePressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralStrokeAccessibleSelected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "neutralStrokeDisabled": { - "semantic": [ - "SystemColorGrayTextColor", - ], - }, - "outofofficeBackground1": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "outofofficeBackground2": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "outofofficeBackground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "outofofficeBorder1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "outofofficeBorder2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "outofofficeBorderActive": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "outofofficeForeground1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "outofofficeForeground2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "outofofficeForeground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "personaActivityGlow": "transparent", - "personaActivityRing": "#ffffff", - "primaryButtonBackground": "#000000", - "primaryButtonBackgroundDisabled": "#000000", - "primaryButtonBackgroundHovered": "#1aebff", - "primaryButtonBackgroundPressed": "#1aebff", - "primaryButtonBorder": "#ffffff", + "menuItemTextHovered": "#ffffff", + "neutralBackground1": "#000000", + "neutralBackground1Hover": "#3d3d3d", + "neutralBackground1Pressed": "#5c5c5c", + "neutralBackground1Selected": "#383838", + "neutralBackground2": "#575757", + "neutralBackground2Hover": "#333333", + "neutralBackground2Pressed": "#707070", + "neutralBackground2Selected": "#2e2e2e", + "neutralBackground3": "#575757", + "neutralBackground3Hover": "#292929", + "neutralBackground3Pressed": "#0a0a0a", + "neutralBackground3Selected": "#242424", + "neutralBackground4": "#1f1f1f", + "neutralBackground4Hover": "#1f1f1f", + "neutralBackground4Pressed": "#000000", + "neutralBackground4Selected": "#1a1a1a", + "neutralBackground5": "#5c5c5c", + "neutralBackground5Hover": "#141414", + "neutralBackground5Pressed": "#050505", + "neutralBackground5Selected": "#0f0f0f", + "neutralBackground6": "#333333", + "neutralBackgroundCanvas": "#000000", + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": "#575757", + "neutralBackgroundInverted": "#ffffff", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#575757", + "neutralForeground1": "#ffffff", + "neutralForeground1Hover": "#ffffff", + "neutralForeground1Pressed": "#ffffff", + "neutralForeground1Selected": "#ffffff", + "neutralForeground2": "#ffffff", + "neutralForeground2BrandHover": "#092c47", + "neutralForeground2BrandPressed": "#0078d4", + "neutralForeground2BrandSelected": "#092c47", + "neutralForeground2Hover": "#ffffff", + "neutralForeground2Pressed": "#ffffff", + "neutralForeground2Selected": "#ffffff", + "neutralForeground3": "#d6d6d6", + "neutralForeground3BrandHover": "#092c47", + "neutralForeground3BrandPressed": "#0078d4", + "neutralForeground3BrandSelected": "#092c47", + "neutralForeground3Hover": "#d6d6d6", + "neutralForeground3Pressed": "#d6d6d6", + "neutralForeground3Selected": "#d6d6d6", + "neutralForeground4": "#d6d6d6", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#b8b8b8", + "neutralForegroundDisabled1": "#b8b8b8", + "neutralForegroundDisabled2": "#b8b8b8", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#292929", + "neutralForegroundInvertedLinkHover": "#292929", + "neutralForegroundInvertedLinkPressed": "#292929", + "neutralForegroundInvertedLinkSelected": "#292929", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", + "neutralStencil1": "#333333", + "neutralStencil2": "#575757", + "neutralStroke1": "#adadad", + "neutralStroke1Hover": "#757575", + "neutralStroke1Pressed": "#6b6b6b", + "neutralStroke1Selected": "#707070", + "neutralStroke2": "#a8a8a8", + "neutralStroke3": "#adadad", + "neutralStrokeAccessible": "#d6d6d6", + "neutralStrokeAccessibleHover": "#bdbdbd", + "neutralStrokeAccessiblePressed": "#b3b3b3", + "neutralStrokeAccessibleSelected": "#0086f0", + "neutralStrokeDisabled": "#525252", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", + "outofofficeBackground1": "#3a1136", + "outofofficeBackground2": "#6d2064", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#c239b3", + "outofofficeBorder2": "#d161c4", + "outofofficeBorderActive": "#da7ed0", + "outofofficeForeground1": "#da7ed0", + "outofofficeForeground2": "#edbbe7", + "outofofficeForeground3": "#d161c4", + "personaActivityGlow": "#0086f0", + "personaActivityRing": "#000000", + "presenceAvailable": "#54b054", + "presenceAway": "#feee66", + "presenceDnd": "#e37d80", + "presenceOof": "#da7ed0", + "primaryButtonBackground": "#0086f0", + "primaryButtonBackgroundDisabled": "#575757", + "primaryButtonBackgroundHovered": "#1890f1", + "primaryButtonBackgroundPressed": "#1890f1", + "primaryButtonBorder": "#3aa0f3", "primaryButtonBorderFocused": "#ffffff", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#3ff23f", - "primaryButtonTextHovered": "#000000", - "primaryButtonTextPressed": "#000000", - "severeBackground1": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "severeBackground2": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "severeBackground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "severeBorder1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "severeBorder2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "severeBorderActive": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "severeForeground1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "severeForeground2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "severeForeground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "strokeFocus1": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "strokeFocus2": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, + "primaryButtonTextDisabled": "#b8b8b8", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#751d1f", + "redBackground3": "#d13438", + "redBorder1": "#d13438", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#f1bbbc", + "redForeground3": "#e37d80", + "severeBackground1": "#411200", + "severeBackground2": "#7a2101", + "severeBackground3": "#da3b01", + "severeBorder1": "#da3b01", + "severeBorder2": "#e9835e", + "severeBorderActive": "#e9835e", + "severeForeground1": "#e9835e", + "severeForeground2": "#f4bfab", + "severeForeground3": "#e9835e", + "severeStroke1": "#da3b01", + "strokeFocus1": "#000000", + "strokeFocus2": "#ffffff", "subText": "#ffffff", "subtleBackground": "#00000000", - "subtleBackgroundHover": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "subtleBackgroundPressed": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "subtleBackgroundSelected": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "successBackground1": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "successBackground2": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "successBackground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "successBorder1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "successBorder2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "successBorderActive": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "successForeground1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "successForeground2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "successForeground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "successForegroundInverted": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", + "successBackground1": "#052505", + "successBackground2": "#094509", + "successBackground3": "#107c10", + "successBorder1": "#107c10", + "successBorder2": "#9fd89f", + "successBorderActive": "#54b054", + "successForeground1": "#54b054", + "successForeground2": "#9fd89f", + "successForeground3": "#9fd89f", + "successForegroundInverted": "#107c10", + "successStroke1": "#107c10", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", "transparentBackgroundSelected": "#00000000", - "transparentStroke": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "transparentStrokeDisabled": { - "semantic": [ - "SystemColorGrayTextColor", - ], - }, - "transparentStrokeInteractive": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "variantBorder": "#ffffff", - "warningBackground1": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "warningBackground2": { - "semantic": [ - "SystemColorWindowColor", - ], - }, - "warningBackground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "warningBorder1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "warningBorder2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "warningBorderActive": { - "semantic": [ - "SystemColorHighlightColor", - ], - }, - "warningForeground1": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "warningForeground2": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "warningForeground3": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, - "warningForegroundInverted": { - "semantic": [ - "SystemColorWindowTextColor", - ], - }, + "transparentStroke": "#3aa0f3", + "transparentStrokeDisabled": "#d6d6d6", + "transparentStrokeInteractive": "#a8a8a8", + "variantBorder": "#a8a8a8", + "warningBackground1": "#4c4400", + "warningBackground2": "#817400", + "warningBackground3": "#fde300", + "warningBorder1": "#fde300", + "warningBorder2": "#fdea3d", + "warningBorderActive": "#feee66", + "warningForeground1": "#feee66", + "warningForeground2": "#fef7b2", + "warningForeground3": "#fdea3d", + "warningForegroundInverted": "#817400", + "warningStroke1": "#fde300", }, "components": {}, "host": { @@ -1654,13 +1863,13 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "System", - "sansSerif": "System", - "secondary": "System", - "serif": "System", + "cursive": "Helvetica Neue", + "monospace": "Courier New", + "numeric": "Helvetica Neue", + "primary": "Helvetica Neue", + "sansSerif": "Helvetica Neue", + "secondary": "Helvetica Neue", + "serif": "Helvetica Neue", }, "sizes": { "body": 14, @@ -1674,138 +1883,153 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -1816,67 +2040,80 @@ exports[`defaultFluentHighConstrastTheme 1`] = ` } `; -exports[`defaultFluentTheme 1`] = ` +exports[`high contrast light theme 1`] = ` { "colors": { - "accentButtonBackground": "#185abd", - "actionLink": "#323130", + "accentButtonBackground": "#0078d4", + "actionLink": "#000000", "background": "#ffffff", - "bodyDivider": "#edebe9", + "bodyDivider": "#000000", "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", + "bodyFrameDivider": "#000000", + "bodyStandoutBackground": "#ffffff", + "bodyText": "#000000", "bodyTextChecked": "#000000", - "brandBackground": "#185abd", + "brandBackground": "#0078d4", "brandBackground2": "#eff6fc", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#1651aa", - "brandBackgroundPressed": "#004578", - "brandBackgroundSelected": "#13458f", - "brandBackgroundStatic": "#185abd", - "brandForeground1": "#185abd", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#1651aa", - "brandForegroundLink": "#1651aa", - "brandForegroundLinkHover": "#13458f", + "brandBackground2Pressed": "#106ebe", + "brandBackground2Selected": "#005a9e", + "brandBackground3": "#eff6fc", + "brandBackgroundDisabled": "#d1d1d1", + "brandBackgroundHover": "#106ebe", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", + "brandBackgroundPressed": "#106ebe", + "brandBackgroundSelected": "#005a9e", + "brandBackgroundStatic": "#0078d4", + "brandBackgroundTint": "#eff6fc", + "brandForeground1": "#0078d4", + "brandForeground1Disabled": "#757575", + "brandForeground1Pressed": "#004578", + "brandForeground1Selected": "#005a9e", + "brandForeground2": "#106ebe", + "brandForegroundDisabled1": "#757575", + "brandForegroundDisabled2": "#757575", + "brandForegroundLink": "#0078d4", + "brandForegroundLinkHover": "#106ebe", "brandForegroundLinkPressed": "#004578", - "brandForegroundLinkSelected": "#1651aa", - "brandStroke1": "#185abd", - "brandStroke2": "#d2e0f4", - "brandedBackground": "#185abd", - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", - "checkboxBackground": "#185abd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", + "brandForegroundLinkSelected": "#005a9e", + "brandForegroundTint": "#106ebe", + "brandStroke1": "#0078d4", + "brandStroke1Pressed": "#004578", + "brandStroke1Selected": "#005a9e", + "brandStroke2": "#c7e0f4", + "brandStrokeTint": "#c7e0f4", + "brandedBackground": "#0078d4", + "brandedDisabledBorder": "#bdbdbd", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#f0f0f0", + "buttonBackgroundHovered": "#f5f5f5", + "buttonBackgroundPressed": "#ebebeb", + "buttonBorder": "#616161", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#000000", + "buttonTextChecked": "#000000", + "buttonTextDisabled": "#757575", + "buttonTextHovered": "#000000", + "buttonTextPressed": "#000000", + "checkboxBackground": "#0078d4", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#242424", "checkmarkColor": "#ffffff", - "compoundBrandBackground1": "#185abd", - "compoundBrandBackground1Hover": "#1651aa", - "compoundBrandBackground1Pressed": "#13458f", - "compoundBrandForeground1": "#185abd", - "compoundBrandForeground1Hover": "#1651aa", - "compoundBrandForeground1Pressed": "#13458f", - "compoundBrandStroke1": "#185abd", - "compoundBrandStroke1Hover": "#1651aa", - "compoundBrandStroke1Pressed": "#13458f", + "compoundBrandBackground1": "#0078d4", + "compoundBrandBackground1Hover": "#106ebe", + "compoundBrandBackground1Pressed": "#004578", + "compoundBrandForeground1": "#0078d4", + "compoundBrandForeground1Hover": "#106ebe", + "compoundBrandForeground1Pressed": "#004578", + "compoundBrandStroke1": "#0078d4", + "compoundBrandStroke1Hover": "#106ebe", + "compoundBrandStroke1Pressed": "#004578", "dangerBackground1": "#fdf6f6", "dangerBackground2": "#f1bbbc", "dangerBackground3": "#d13438", @@ -1887,90 +2124,91 @@ exports[`defaultFluentTheme 1`] = ` "dangerForeground2": "#751d1f", "dangerForeground3": "#d13438", "dangerForegroundInverted": "#dc5e62", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", + "dangerStroke1": "#f1bbbc", + "defaultBackground": "#ffffff", + "defaultBorder": "#616161", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#000000", + "defaultCheckedHoveredBackground": "#f5f5f5", + "defaultCheckedHoveredContent": "#000000", + "defaultContent": "#000000", + "defaultDisabledBackground": "#f0f0f0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#757575", + "defaultDisabledIcon": "#757575", + "defaultFocusedBackground": "#f5f5f5", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#000000", + "defaultFocusedIcon": "#000000", + "defaultHoveredBackground": "#f5f5f5", + "defaultHoveredBorder": "#c7c7c7", + "defaultHoveredContent": "#000000", + "defaultHoveredIcon": "#000000", + "defaultHoveredSecondaryContent": "#424242", + "defaultIcon": "#000000", + "defaultPressedBackground": "#ebebeb", + "defaultPressedBorder": "#b3b3b3", + "defaultPressedContent": "#000000", + "defaultPressedIcon": "#000000", + "defaultPressedSecondaryContent": "#424242", + "disabledBackground": "#f0f0f0", + "disabledBodyText": "#757575", + "disabledText": "#757575", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#242424", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#000000", + "ghostCheckedHoveredContent": "#242424", + "ghostContent": "#000000", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#bdbdbd", + "ghostDisabledContent": "#757575", + "ghostDisabledIcon": "#757575", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#000000", + "ghostFocusedIcon": "#000000", + "ghostFocusedSecondaryContent": "#000000", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#000000", + "ghostHoveredContent": "#000000", + "ghostHoveredIcon": "#000000", + "ghostHoveredSecondaryContent": "#424242", + "ghostIcon": "#000000", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#000000", + "ghostPressedContent": "#000000", + "ghostPressedIcon": "#000000", + "ghostPressedSecondaryContent": "#424242", + "ghostSecondaryContent": "#000000", "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", - "inputFocusBorderAlt": "#185abd", - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", - "link": "#185abd", - "linkHovered": "#004578", - "linkPressed": "#13458f", - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", + "inputBorder": "#616161", + "inputFocusBorderAlt": "#0078d4", + "inputPlaceholderText": "#424242", + "inputText": "#000000", + "link": "#0078d4", + "linkHovered": "#106ebe", + "linkPressed": "#004578", + "listHeaderBackgroundHovered": "#f5f5f5", + "listHeaderBackgroundPressed": "#ebebeb", "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": "#185abd", - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", + "menuDivider": "#000000", + "menuIcon": "#000000", + "menuItemBackgroundHovered": "#f5f5f5", + "menuItemBackgroundPressed": "#ebebeb", + "menuItemText": "#000000", + "menuItemTextHovered": "#000000", "neutralBackground1": "#ffffff", "neutralBackground1Hover": "#f5f5f5", - "neutralBackground1Pressed": "#e0e0e0", + "neutralBackground1Pressed": "#ebebeb", "neutralBackground1Selected": "#ebebeb", - "neutralBackground2": "#fafafa", + "neutralBackground2": "#ffffff", "neutralBackground2Hover": "#f0f0f0", - "neutralBackground2Pressed": "#dbdbdb", + "neutralBackground2Pressed": "#ebebeb", "neutralBackground2Selected": "#e6e6e6", "neutralBackground3": "#f5f5f5", "neutralBackground3Hover": "#ebebeb", @@ -1985,50 +2223,61 @@ exports[`defaultFluentTheme 1`] = ` "neutralBackground5Pressed": "#f0f0f0", "neutralBackground5Selected": "#fafafa", "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", "neutralBackgroundDisabled": "#f0f0f0", "neutralBackgroundInverted": "#616161", - "neutralForeground1": "#242424", - "neutralForeground1Hover": "#242424", - "neutralForeground1Pressed": "#242424", - "neutralForeground1Selected": "#242424", - "neutralForeground2": "#424242", - "neutralForeground2BrandHover": "#185abd", - "neutralForeground2BrandPressed": "#1651aa", - "neutralForeground2BrandSelected": "#185abd", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", + "neutralForeground1": "#000000", + "neutralForeground1Hover": "#000000", + "neutralForeground1Pressed": "#000000", + "neutralForeground1Selected": "#000000", + "neutralForeground2": "#000000", + "neutralForeground2BrandHover": "#106ebe", + "neutralForeground2BrandPressed": "#004578", + "neutralForeground2BrandSelected": "#005a9e", "neutralForeground2Hover": "#242424", "neutralForeground2Pressed": "#242424", "neutralForeground2Selected": "#242424", - "neutralForeground3": "#616161", - "neutralForeground3BrandHover": "#185abd", - "neutralForeground3BrandPressed": "#1651aa", - "neutralForeground3BrandSelected": "#185abd", + "neutralForeground3": "#000000", + "neutralForeground3BrandHover": "#106ebe", + "neutralForeground3BrandPressed": "#004578", + "neutralForeground3BrandSelected": "#005a9e", "neutralForeground3Hover": "#424242", "neutralForeground3Pressed": "#424242", "neutralForeground3Selected": "#424242", - "neutralForeground4": "#707070", - "neutralForegroundDisabled": "#bdbdbd", + "neutralForeground4": "#424242", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#757575", + "neutralForegroundDisabled1": "#757575", + "neutralForegroundDisabled2": "#757575", "neutralForegroundInverted": "#ffffff", "neutralForegroundInvertedLink": "#ffffff", "neutralForegroundInvertedLinkHover": "#ffffff", "neutralForegroundInvertedLinkPressed": "#ffffff", "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#e6e6e6", "neutralStencil2": "#fafafa", - "neutralStroke1": "#d1d1d1", + "neutralStroke1": "#616161", "neutralStroke1Hover": "#c7c7c7", "neutralStroke1Pressed": "#b3b3b3", "neutralStroke1Selected": "#bdbdbd", - "neutralStroke2": "#e0e0e0", - "neutralStroke3": "#f0f0f0", - "neutralStrokeAccessible": "#616161", + "neutralStroke2": "#000000", + "neutralStroke3": "#616161", + "neutralStrokeAccessible": "#242424", "neutralStrokeAccessibleHover": "#575757", "neutralStrokeAccessiblePressed": "#4d4d4d", - "neutralStrokeAccessibleSelected": "#185abd", + "neutralStrokeAccessibleSelected": "#0078d4", "neutralStrokeDisabled": "#e0e0e0", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", "outofofficeBackground1": "#fdf5fc", "outofofficeBackground2": "#edbbe7", "outofofficeBackground3": "#c239b3", @@ -2038,18 +2287,31 @@ exports[`defaultFluentTheme 1`] = ` "outofofficeForeground1": "#af33a1", "outofofficeForeground2": "#6d2064", "outofofficeForeground3": "#c239b3", - "personaActivityGlow": "#185abd", + "personaActivityGlow": "#0078d4", "personaActivityRing": "#ffffff", - "primaryButtonBackground": "#185abd", - "primaryButtonBackgroundDisabled": "#f3f2f1", - "primaryButtonBackgroundHovered": "#1651aa", - "primaryButtonBackgroundPressed": "#13458f", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", + "primaryButtonBackground": "#0078d4", + "primaryButtonBackgroundDisabled": "#f0f0f0", + "primaryButtonBackgroundHovered": "#106ebe", + "primaryButtonBackgroundPressed": "#106ebe", + "primaryButtonBorder": "#000000", + "primaryButtonBorderFocused": "#000000", "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", + "primaryButtonTextDisabled": "#757575", "primaryButtonTextHovered": "#ffffff", "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#f4bfab", "severeBackground3": "#da3b01", @@ -2059,9 +2321,10 @@ exports[`defaultFluentTheme 1`] = ` "severeForeground1": "#c43501", "severeForeground2": "#7a2101", "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", "strokeFocus1": "#ffffff", "strokeFocus2": "#000000", - "subText": "#605e5c", + "subText": "#000000", "subtleBackground": "#00000000", "subtleBackgroundHover": "#f5f5f5", "subtleBackgroundPressed": "#e0e0e0", @@ -2076,14 +2339,15 @@ exports[`defaultFluentTheme 1`] = ` "successForeground2": "#094509", "successForeground3": "#107c10", "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", "transparentBackgroundSelected": "#00000000", - "transparentStroke": "#00000000", - "transparentStrokeDisabled": "#00000000", - "transparentStrokeInteractive": "#00000000", - "variantBorder": "#edebe9", + "transparentStroke": "#000000", + "transparentStrokeDisabled": "#bdbdbd", + "transparentStrokeInteractive": "#666666", + "variantBorder": "#000000", "warningBackground1": "#fffef5", "warningBackground2": "#fef7b2", "warningBackground3": "#fde300", @@ -2094,22 +2358,23 @@ exports[`defaultFluentTheme 1`] = ` "warningForeground2": "#817400", "warningForeground3": "#fde300", "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", }, "components": {}, "host": { - "appearance": "light", + "appearance": "highContrast", }, "shadows": { "shadow16": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 16, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 8, }, @@ -2131,13 +2396,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow2": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 2, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 1, }, @@ -2145,13 +2410,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow28": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 28, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 14, }, @@ -2187,13 +2452,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow4": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 4, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 2, }, @@ -2215,13 +2480,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow64": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 64, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 32, }, @@ -2243,13 +2508,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow8": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 8, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 4, }, @@ -2278,13 +2543,13 @@ exports[`defaultFluentTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "System", - "sansSerif": "System", - "secondary": "System", - "serif": "System", + "cursive": "Helvetica Neue", + "monospace": "Courier New", + "numeric": "Helvetica Neue", + "primary": "Helvetica Neue", + "sansSerif": "Helvetica Neue", + "secondary": "Helvetica Neue", + "serif": "Helvetica Neue", }, "sizes": { "body": 14, @@ -2298,138 +2563,153 @@ exports[`defaultFluentTheme 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { diff --git a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.win32.ts.snap b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.win32.ts.snap index fdeef02cf4f..7f9af812b05 100644 --- a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.win32.ts.snap +++ b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.win32.ts.snap @@ -4,63 +4,76 @@ exports[`defaultFluentDarkTheme 1`] = ` { "colors": { "accentButtonBackground": "#185abd", - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "actionLink": "#ffffff", + "background": "#292929", + "bodyDivider": "#525252", + "bodyFrameBackground": "#292929", + "bodyFrameDivider": "#525252", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", - "brandBackground": "#1651aa", - "brandBackground2": "#004578", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#185abd", - "brandBackgroundPressed": "#004578", + "brandBackground": "#185abd", + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#141414", + "brandBackgroundHover": "#1651aa", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#141414", + "brandBackgroundPressed": "#0e336a", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", - "brandForeground1": "#6794d7", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#aec6eb", - "brandForegroundLink": "#2e6ac5", - "brandForegroundLinkHover": "#aec6eb", - "brandForegroundLinkPressed": "#6794d7", - "brandForegroundLinkSelected": "#2e6ac5", - "brandStroke1": "#2e6ac5", - "brandStroke2": "#0e336a", - "brandedBackground": "#2e6ac5", - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandBackgroundTint": "#d2e0f4", + "brandForeground1": "#aec6eb", + "brandForeground1Disabled": "#5c5c5c", + "brandForeground1Pressed": "#aec6eb", + "brandForeground1Selected": "#aec6eb", + "brandForeground2": "#d2e0f4", + "brandForegroundDisabled1": "#5c5c5c", + "brandForegroundDisabled2": "#5c5c5c", + "brandForegroundLink": "#aec6eb", + "brandForegroundLinkHover": "#d2e0f4", + "brandForegroundLinkPressed": "#2e6ac5", + "brandForegroundLinkSelected": "#d2e0f4", + "brandForegroundTint": "#d2e0f4", + "brandStroke1": "#185abd", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", + "brandedBackground": "#185abd", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#292929", + "buttonBackgroundChecked": "#383838", + "buttonBackgroundDisabled": "#141414", + "buttonBackgroundHovered": "#3d3d3d", + "buttonBackgroundPressed": "#1f1f1f", + "buttonBorder": "#666666", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": "#2e6ac5", - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", - "compoundBrandBackground1": "#2e6ac5", - "compoundBrandBackground1Hover": "#6794d7", - "compoundBrandBackground1Pressed": "#185abd", - "compoundBrandForeground1": "#2e6ac5", - "compoundBrandForeground1Hover": "#6794d7", - "compoundBrandForeground1Pressed": "#185abd", - "compoundBrandStroke1": "#2e6ac5", - "compoundBrandStroke1Hover": "#6794d7", - "compoundBrandStroke1Pressed": "#185abd", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#185abd", + "checkboxBackgroundDisabled": "#141414", + "checkboxBorderColor": "#adadad", + "checkmarkColor": "#ffffff", + "compoundBrandBackground1": "#185abd", + "compoundBrandBackground1Hover": "#1651aa", + "compoundBrandBackground1Pressed": "#0e336a", + "compoundBrandForeground1": "#aec6eb", + "compoundBrandForeground1Hover": "#d2e0f4", + "compoundBrandForeground1Pressed": "#2e6ac5", + "compoundBrandStroke1": "#185abd", + "compoundBrandStroke1Hover": "#1651aa", + "compoundBrandStroke1Pressed": "#0e336a", "dangerBackground1": "#3f1011", "dangerBackground2": "#751d1f", "dangerBackground3": "#d13438", @@ -71,83 +84,84 @@ exports[`defaultFluentDarkTheme 1`] = ` "dangerForeground2": "#f1bbbc", "dangerForeground3": "#e37d80", "dangerForegroundInverted": "#d13438", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "dangerStroke1": "#d13438", + "defaultBackground": "#292929", + "defaultBorder": "#666666", + "defaultCheckedBackground": "#383838", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#3d3d3d", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#141414", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#3d3d3d", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#3d3d3d", + "defaultHoveredBorder": "#757575", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#d6d6d6", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", + "defaultPressedBackground": "#1f1f1f", + "defaultPressedBorder": "#6b6b6b", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#d6d6d6", + "disabledBackground": "#141414", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#383838", "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": "#2e6ac5", - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": "#2e6ac5", - "linkHovered": "#82c7ff", - "linkPressed": "#aec6eb", - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": "#6794d7", - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", + "ghostCheckedHoveredBackground": "#3d3d3d", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#ffffff", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#3d3d3d", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#3d3d3d", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#d6d6d6", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#1f1f1f", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#d6d6d6", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#292929", + "inputBorder": "#666666", + "inputFocusBorderAlt": "#185abd", + "inputPlaceholderText": "#999999", + "inputText": "#ffffff", + "link": "#aec6eb", + "linkHovered": "#d2e0f4", + "linkPressed": "#2e6ac5", + "listHeaderBackgroundHovered": "#3d3d3d", + "listHeaderBackgroundPressed": "#1f1f1f", + "menuBackground": "#292929", + "menuDivider": "#525252", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#3d3d3d", + "menuItemBackgroundPressed": "#1f1f1f", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", "neutralBackground1": "#292929", "neutralBackground1Hover": "#3d3d3d", "neutralBackground1Pressed": "#1f1f1f", @@ -169,37 +183,46 @@ exports[`defaultFluentDarkTheme 1`] = ` "neutralBackground5Pressed": "#050505", "neutralBackground5Selected": "#0f0f0f", "neutralBackground6": "#333333", + "neutralBackgroundCanvas": "#292929", + "neutralBackgroundDarkStatic": "#3d3d3d", "neutralBackgroundDisabled": "#141414", "neutralBackgroundInverted": "#ffffff", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#141414", "neutralForeground1": "#ffffff", "neutralForeground1Hover": "#ffffff", "neutralForeground1Pressed": "#ffffff", "neutralForeground1Selected": "#ffffff", "neutralForeground2": "#d6d6d6", - "neutralForeground2BrandHover": "#6794d7", + "neutralForeground2BrandHover": "#d2e0f4", "neutralForeground2BrandPressed": "#2e6ac5", - "neutralForeground2BrandSelected": "#6794d7", + "neutralForeground2BrandSelected": "#d2e0f4", "neutralForeground2Hover": "#ffffff", "neutralForeground2Pressed": "#ffffff", "neutralForeground2Selected": "#ffffff", "neutralForeground3": "#adadad", - "neutralForeground3BrandHover": "#6794d7", + "neutralForeground3BrandHover": "#d2e0f4", "neutralForeground3BrandPressed": "#2e6ac5", - "neutralForeground3BrandSelected": "#6794d7", + "neutralForeground3BrandSelected": "#d2e0f4", "neutralForeground3Hover": "#d6d6d6", "neutralForeground3Pressed": "#d6d6d6", "neutralForeground3Selected": "#d6d6d6", "neutralForeground4": "#999999", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#5c5c5c", - "neutralForegroundInverted": "#242424", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundDisabled1": "#5c5c5c", + "neutralForegroundDisabled2": "#5c5c5c", + "neutralForegroundInverted": "#000000", + "neutralForegroundInvertedLink": "#292929", + "neutralForegroundInvertedLinkHover": "#292929", + "neutralForegroundInvertedLinkPressed": "#292929", + "neutralForegroundInvertedLinkSelected": "#292929", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#333333", "neutralStencil2": "#575757", "neutralStroke1": "#666666", @@ -211,8 +234,10 @@ exports[`defaultFluentDarkTheme 1`] = ` "neutralStrokeAccessible": "#adadad", "neutralStrokeAccessibleHover": "#bdbdbd", "neutralStrokeAccessiblePressed": "#b3b3b3", - "neutralStrokeAccessibleSelected": "#6794d7", + "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#424242", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", "outofofficeBackground1": "#3a1136", "outofofficeBackground2": "#6d2064", "outofofficeBackground3": "#c239b3", @@ -222,18 +247,31 @@ exports[`defaultFluentDarkTheme 1`] = ` "outofofficeForeground1": "#da7ed0", "outofofficeForeground2": "#edbbe7", "outofofficeForeground3": "#d161c4", - "personaActivityGlow": "#2e6ac5", - "personaActivityRing": "#1b1a19", - "primaryButtonBackground": "#2e6ac5", - "primaryButtonBackgroundDisabled": "#252423", - "primaryButtonBackgroundHovered": "#6794d7", - "primaryButtonBackgroundPressed": "#aec6eb", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "personaActivityGlow": "#185abd", + "personaActivityRing": "#292929", + "presenceAvailable": "#54b054", + "presenceAway": "#feee66", + "presenceDnd": "#e37d80", + "presenceOof": "#da7ed0", + "primaryButtonBackground": "#185abd", + "primaryButtonBackgroundDisabled": "#141414", + "primaryButtonBackgroundHovered": "#1651aa", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#751d1f", + "redBackground3": "#d13438", + "redBorder1": "#d13438", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#f1bbbc", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#7a2101", "severeBackground3": "#da3b01", @@ -243,13 +281,14 @@ exports[`defaultFluentDarkTheme 1`] = ` "severeForeground1": "#e9835e", "severeForeground2": "#f4bfab", "severeForeground3": "#e9835e", + "severeStroke1": "#da3b01", "strokeFocus1": "#000000", "strokeFocus2": "#ffffff", - "subText": "#a19f9d", + "subText": "#d6d6d6", "subtleBackground": "#00000000", - "subtleBackgroundHover": "#383838", - "subtleBackgroundPressed": "#2e2e2e", - "subtleBackgroundSelected": "#333333", + "subtleBackgroundHover": "#3d3d3d", + "subtleBackgroundPressed": "#1f1f1f", + "subtleBackgroundSelected": "#383838", "successBackground1": "#052505", "successBackground2": "#094509", "successBackground3": "#107c10", @@ -260,6 +299,7 @@ exports[`defaultFluentDarkTheme 1`] = ` "successForeground2": "#9fd89f", "successForeground3": "#9fd89f", "successForegroundInverted": "#107c10", + "successStroke1": "#107c10", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -267,7 +307,7 @@ exports[`defaultFluentDarkTheme 1`] = ` "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#292827", + "variantBorder": "#525252", "warningBackground1": "#4c4400", "warningBackground2": "#817400", "warningBackground3": "#fde300", @@ -278,6 +318,7 @@ exports[`defaultFluentDarkTheme 1`] = ` "warningForeground2": "#fef7b2", "warningForeground3": "#fdea3d", "warningForegroundInverted": "#817400", + "warningStroke1": "#fde300", }, "components": {}, "host": { @@ -462,13 +503,13 @@ exports[`defaultFluentDarkTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -482,138 +523,153 @@ exports[`defaultFluentDarkTheme 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -624,1492 +680,4125 @@ exports[`defaultFluentDarkTheme 1`] = ` } `; -exports[`defaultFluentHighConstrastTheme 1`] = ` +exports[`defaultFluentTheme 1`] = ` { "colors": { - "accentButtonBackground": "#000000", - "actionLink": "#ffff00", - "background": "#000000", - "bodyDivider": "#ffffff", - "bodyFrameBackground": "#000000", - "bodyFrameDivider": "#000000", - "bodyStandoutBackground": "#000000", - "bodyText": "#ffffff", - "bodyTextChecked": "#000000", - "brandBackground": { - "resource_paths": [ - "ButtonFace", - ], - }, - "brandBackground2": { - "resource_paths": [ - "ButtonFace", - ], - }, - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": { - "resource_paths": [ - "Highlight", - ], - }, - "brandBackgroundPressed": { - "resource_paths": [ - "Highlight", - ], - }, - "brandBackgroundSelected": { - "resource_paths": [ - "Highlight", - ], - }, - "brandBackgroundStatic": { - "resource_paths": [ - "Window", - ], - }, - "brandForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": { - "resource_paths": [ - "ButtonText", - ], - }, - "brandForegroundLink": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandForegroundLinkHover": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandForegroundLinkPressed": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandForegroundLinkSelected": { - "resource_paths": [ - "Hotlight", - ], - }, - "brandStroke1": { - "resource_paths": [ - "WindowText", - ], - }, - "brandStroke2": { - "resource_paths": [ - "Window", - ], - }, - "brandedBackground": "#000000", - "brandedDisabledBorder": "#3ff23f", + "accentButtonBackground": "#185abd", + "actionLink": "#242424", + "background": "#ffffff", + "bodyDivider": "#e0e0e0", + "bodyFrameBackground": "#ffffff", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#fafafa", + "bodyText": "#242424", + "bodyTextChecked": "#242424", + "brandBackground": "#185abd", + "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", + "brandBackgroundDisabled": "#f0f0f0", + "brandBackgroundHover": "#1651aa", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", + "brandBackgroundPressed": "#0e336a", + "brandBackgroundSelected": "#13458f", + "brandBackgroundStatic": "#185abd", + "brandBackgroundTint": "#d2e0f4", + "brandForeground1": "#185abd", + "brandForeground1Disabled": "#bdbdbd", + "brandForeground1Pressed": "#185abd", + "brandForeground1Selected": "#185abd", + "brandForeground2": "#1651aa", + "brandForegroundDisabled1": "#bdbdbd", + "brandForegroundDisabled2": "#bdbdbd", + "brandForegroundLink": "#185abd", + "brandForegroundLinkHover": "#1651aa", + "brandForegroundLinkPressed": "#0e336a", + "brandForegroundLinkSelected": "#13458f", + "brandForegroundTint": "#1651aa", + "brandStroke1": "#185abd", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#6794d7", + "brandStrokeTint": "#6794d7", + "brandedBackground": "#185abd", + "brandedDisabledBorder": "#00000000", "brandedFocusedSecondaryContent": "#ffffff", - "brandedHoveredSecondaryContent": "#000000", - "brandedPressedSecondaryContent": "#000000", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", "brandedSecondaryContent": "#ffffff", - "buttonBackground": "#000000", - "buttonBackgroundChecked": "#1aebff", - "buttonBackgroundDisabled": "#000000", - "buttonBackgroundHovered": "#1aebff", - "buttonBackgroundPressed": "#1aebff", - "buttonBorder": "#ffffff", - "buttonBorderDisabled": "#3ff23f", - "buttonBorderFocused": "#ffffff", - "buttonText": "#ffffff", - "buttonTextChecked": "#000000", - "buttonTextDisabled": "#3ff23f", - "buttonTextHovered": "#000000", - "buttonTextPressed": "#000000", - "checkboxBackground": "#000000", - "checkboxBackgroundDisabled": "#000000", - "checkboxBorderColor": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#f0f0f0", + "buttonBackgroundHovered": "#f5f5f5", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", + "checkboxBackground": "#185abd", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", - "compoundBrandBackground1": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandBackground1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandBackground1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandForeground1": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandForeground1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandForeground1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandStroke1": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandStroke1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "compoundBrandStroke1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "dangerBackground1": { - "resource_paths": [ - "Window", - ], - }, - "dangerBackground2": { - "resource_paths": [ - "Window", - ], - }, - "dangerBackground3": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerBorder1": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerBorder2": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerBorderActive": { - "resource_paths": [ - "Highlight", - ], - }, - "dangerForeground1": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerForeground2": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerForeground3": { - "resource_paths": [ - "WindowText", - ], - }, - "dangerForegroundInverted": { - "resource_paths": [ - "WindowText", - ], - }, - "defaultBackground": "#000000", - "defaultBorder": "#ffffff", - "defaultCheckedBackground": "#1aebff", - "defaultCheckedContent": "#000000", - "defaultCheckedHoveredBackground": "#1aebff", - "defaultCheckedHoveredContent": "#000000", - "defaultContent": "#ffffff", - "defaultDisabledBackground": "#000000", - "defaultDisabledBorder": "#3ff23f", - "defaultDisabledContent": "#3ff23f", - "defaultDisabledIcon": "#3ff23f", - "defaultFocusedBackground": "#000000", - "defaultFocusedBorder": "#ffffff", - "defaultFocusedContent": "#ffffff", - "defaultFocusedIcon": "#ffffff", - "defaultHoveredBackground": "#1aebff", - "defaultHoveredBorder": "#1aebff", - "defaultHoveredContent": "#000000", - "defaultHoveredIcon": "#000000", - "defaultHoveredSecondaryContent": "#000000", - "defaultIcon": "#ffffff", - "defaultPressedBackground": "#1aebff", - "defaultPressedBorder": "#1aebff", - "defaultPressedContent": "#000000", - "defaultPressedIcon": "#000000", - "defaultPressedSecondaryContent": "#000000", - "disabledBackground": "#000000", - "disabledBodyText": "#3ff23f", - "disabledText": "#3ff23f", - "errorText": "#ffffff", - "focusBorder": "#ffffff", - "ghostBackground": "#000000", - "ghostBorder": "#000000", - "ghostCheckedBackground": "#1aebff", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#1aebff", - "ghostCheckedHoveredBorder": "#000000", - "ghostCheckedHoveredContent": "#000000", - "ghostContent": "#ffffff", - "ghostDisabledBackground": "#000000", - "ghostDisabledBorder": "#000000", - "ghostDisabledContent": "#3ff23f", - "ghostDisabledIcon": "#3ff23f", - "ghostFocusedBackground": "#000000", - "ghostFocusedBorder": "#ffffff", - "ghostFocusedContent": "#ffffff", - "ghostFocusedIcon": "#ffffff", - "ghostFocusedSecondaryContent": "#ffffff", - "ghostHoveredBackground": "#1aebff", - "ghostHoveredBorder": "#1aebff", - "ghostHoveredContent": "#000000", - "ghostHoveredIcon": "#000000", - "ghostHoveredSecondaryContent": "#000000", - "ghostIcon": "#ffffff", - "ghostPressedBackground": "#1aebff", - "ghostPressedBorder": "#1aebff", - "ghostPressedContent": "#000000", - "ghostPressedIcon": "#000000", - "ghostPressedSecondaryContent": "#000000", - "ghostSecondaryContent": "#ffffff", - "inputBackground": "#000000", - "inputBorder": "#ffffff", - "inputFocusBorderAlt": "#ffffff", - "inputPlaceholderText": "#ffffff", - "inputText": "#ffffff", - "link": "#ffff00", - "linkHovered": "#ffffff", - "linkPressed": "#ffffff", - "listHeaderBackgroundHovered": "#1aebff", - "listHeaderBackgroundPressed": "#1aebff", - "menuBackground": "#000000", - "menuDivider": "#ffffff", - "menuIcon": "#ffffff", - "menuItemBackgroundHovered": "#1aebff", - "menuItemBackgroundPressed": "#1aebff", - "menuItemText": "#ffffff", - "menuItemTextHovered": "#000000", - "neutralBackground1": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackground1Hover": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground1Pressed": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground1Selected": { - "resource_paths": [ - "Highlight", - ], - }, - "neutralBackground2": { - "resource_paths": [ - "Window", - ], - }, - "neutralBackground2Hover": { - "resource_paths": [ - "Highlight", - ], + "compoundBrandBackground1": "#185abd", + "compoundBrandBackground1Hover": "#1651aa", + "compoundBrandBackground1Pressed": "#0e336a", + "compoundBrandForeground1": "#185abd", + "compoundBrandForeground1Hover": "#1651aa", + "compoundBrandForeground1Pressed": "#0e336a", + "compoundBrandStroke1": "#185abd", + "compoundBrandStroke1Hover": "#1651aa", + "compoundBrandStroke1Pressed": "#0e336a", + "dangerBackground1": "#fdf6f6", + "dangerBackground2": "#f1bbbc", + "dangerBackground3": "#d13438", + "dangerBorder1": "#f1bbbc", + "dangerBorder2": "#d13438", + "dangerBorderActive": "#d13438", + "dangerForeground1": "#bc2f32", + "dangerForeground2": "#751d1f", + "dangerForeground3": "#d13438", + "dangerForegroundInverted": "#dc5e62", + "dangerStroke1": "#f1bbbc", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#f5f5f5", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#f0f0f0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#f5f5f5", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#f5f5f5", + "defaultHoveredBorder": "#c7c7c7", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#424242", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#b3b3b3", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#424242", + "disabledBackground": "#f0f0f0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#242424", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#242424", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#616161", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#424242", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#424242", + "ghostSecondaryContent": "#616161", + "inputBackground": "#ffffff", + "inputBorder": "#d1d1d1", + "inputFocusBorderAlt": "#185abd", + "inputPlaceholderText": "#707070", + "inputText": "#242424", + "link": "#185abd", + "linkHovered": "#1651aa", + "linkPressed": "#0e336a", + "listHeaderBackgroundHovered": "#f5f5f5", + "listHeaderBackgroundPressed": "#e0e0e0", + "menuBackground": "#ffffff", + "menuDivider": "#e0e0e0", + "menuIcon": "#424242", + "menuItemBackgroundHovered": "#f5f5f5", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", + "neutralBackground1": "#ffffff", + "neutralBackground1Hover": "#f5f5f5", + "neutralBackground1Pressed": "#e0e0e0", + "neutralBackground1Selected": "#ebebeb", + "neutralBackground2": "#fafafa", + "neutralBackground2Hover": "#f0f0f0", + "neutralBackground2Pressed": "#dbdbdb", + "neutralBackground2Selected": "#e6e6e6", + "neutralBackground3": "#f5f5f5", + "neutralBackground3Hover": "#ebebeb", + "neutralBackground3Pressed": "#d6d6d6", + "neutralBackground3Selected": "#e0e0e0", + "neutralBackground4": "#f0f0f0", + "neutralBackground4Hover": "#fafafa", + "neutralBackground4Pressed": "#f5f5f5", + "neutralBackground4Selected": "#ffffff", + "neutralBackground5": "#ebebeb", + "neutralBackground5Hover": "#f5f5f5", + "neutralBackground5Pressed": "#f0f0f0", + "neutralBackground5Selected": "#fafafa", + "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", + "neutralBackgroundDisabled": "#f0f0f0", + "neutralBackgroundInverted": "#616161", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", + "neutralForeground1": "#242424", + "neutralForeground1Hover": "#242424", + "neutralForeground1Pressed": "#242424", + "neutralForeground1Selected": "#242424", + "neutralForeground2": "#424242", + "neutralForeground2BrandHover": "#1651aa", + "neutralForeground2BrandPressed": "#0e336a", + "neutralForeground2BrandSelected": "#13458f", + "neutralForeground2Hover": "#242424", + "neutralForeground2Pressed": "#242424", + "neutralForeground2Selected": "#242424", + "neutralForeground3": "#616161", + "neutralForeground3BrandHover": "#1651aa", + "neutralForeground3BrandPressed": "#0e336a", + "neutralForeground3BrandSelected": "#13458f", + "neutralForeground3Hover": "#424242", + "neutralForeground3Pressed": "#424242", + "neutralForeground3Selected": "#424242", + "neutralForeground4": "#707070", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#bdbdbd", + "neutralForegroundDisabled1": "#bdbdbd", + "neutralForegroundDisabled2": "#bdbdbd", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#ffffff", + "neutralForegroundInvertedLinkPressed": "#ffffff", + "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", + "neutralStencil1": "#e6e6e6", + "neutralStencil2": "#fafafa", + "neutralStroke1": "#d1d1d1", + "neutralStroke1Hover": "#c7c7c7", + "neutralStroke1Pressed": "#b3b3b3", + "neutralStroke1Selected": "#bdbdbd", + "neutralStroke2": "#e0e0e0", + "neutralStroke3": "#f0f0f0", + "neutralStrokeAccessible": "#616161", + "neutralStrokeAccessibleHover": "#575757", + "neutralStrokeAccessiblePressed": "#4d4d4d", + "neutralStrokeAccessibleSelected": "#185abd", + "neutralStrokeDisabled": "#e0e0e0", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", + "outofofficeBackground1": "#fdf5fc", + "outofofficeBackground2": "#edbbe7", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#edbbe7", + "outofofficeBorder2": "#c239b3", + "outofofficeBorderActive": "#c239b3", + "outofofficeForeground1": "#af33a1", + "outofofficeForeground2": "#6d2064", + "outofofficeForeground3": "#c239b3", + "personaActivityGlow": "#185abd", + "personaActivityRing": "#ffffff", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", + "primaryButtonBackground": "#185abd", + "primaryButtonBackgroundDisabled": "#f0f0f0", + "primaryButtonBackgroundHovered": "#1651aa", + "primaryButtonBackgroundPressed": "#0e336a", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#bdbdbd", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", + "severeBackground1": "#fdf6f3", + "severeBackground2": "#f4bfab", + "severeBackground3": "#da3b01", + "severeBorder1": "#f4bfab", + "severeBorder2": "#da3b01", + "severeBorderActive": "#da3b01", + "severeForeground1": "#c43501", + "severeForeground2": "#7a2101", + "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", + "strokeFocus1": "#ffffff", + "strokeFocus2": "#000000", + "subText": "#424242", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#f5f5f5", + "subtleBackgroundPressed": "#e0e0e0", + "subtleBackgroundSelected": "#ebebeb", + "successBackground1": "#f1faf1", + "successBackground2": "#9fd89f", + "successBackground3": "#107c10", + "successBorder1": "#9fd89f", + "successBorder2": "#107c10", + "successBorderActive": "#107c10", + "successForeground1": "#0e700e", + "successForeground2": "#094509", + "successForeground3": "#107c10", + "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#e0e0e0", + "warningBackground1": "#fffef5", + "warningBackground2": "#fef7b2", + "warningBackground3": "#fde300", + "warningBorder1": "#fef7b2", + "warningBorder2": "#fde300", + "warningBorderActive": "#fde300", + "warningForeground1": "#817400", + "warningForeground2": "#817400", + "warningForeground3": "#fde300", + "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", + }, + "components": {}, + "host": { + "appearance": "light", + }, + "shadows": { + "shadow16": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000024", + "x": 0, + "y": 8, + }, }, - "neutralBackground2Pressed": { - "resource_paths": [ - "Highlight", - ], + "shadow16brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000040", + "x": 0, + "y": 8, + }, }, - "neutralBackground2Selected": { - "resource_paths": [ - "Highlight", - ], + "shadow2": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000024", + "x": 0, + "y": 1, + }, }, - "neutralBackground3": { - "resource_paths": [ - "Window", - ], + "shadow28": { + "ambient": { + "blur": 8, + "color": "#00000033", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#0000003d", + "x": 0, + "y": 14, + }, }, - "neutralBackground3Hover": { - "resource_paths": [ - "Highlight", - ], + "shadow28brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000040", + "x": 0, + "y": 14, + }, }, - "neutralBackground3Pressed": { - "resource_paths": [ - "Highlight", - ], + "shadow2brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000040", + "x": 0, + "y": 1, + }, }, - "neutralBackground3Selected": { - "resource_paths": [ - "Highlight", - ], + "shadow4": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000024", + "x": 0, + "y": 2, + }, }, - "neutralBackground4": { + "shadow4brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000040", + "x": 0, + "y": 2, + }, + }, + "shadow64": { + "ambient": { + "blur": 8, + "color": "#00000033", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#0000003d", + "x": 0, + "y": 32, + }, + }, + "shadow64brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000040", + "x": 0, + "y": 32, + }, + }, + "shadow8": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000024", + "x": 0, + "y": 4, + }, + }, + "shadow8brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000040", + "x": 0, + "y": 4, + }, + }, + }, + "spacing": { + "l1": "20px", + "l2": "32px", + "m": "16px", + "s1": "8px", + "s2": "4px", + }, + "typography": { + "families": { + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", + "primary": "Segoe UI", + "sansSerif": "Segoe UI", + "secondary": "Segoe UI", + "serif": "Segoe UI", + }, + "sizes": { + "body": 14, + "caption": 10, + "header": 20, + "hero": 28, + "heroLarge": 40, + "secondary": 12, + "subheader": 16, + }, + "variants": { + "body1": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "body1Strong": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "body2": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "body2Strong": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodySemibold": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodyStandard": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "caption1": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "caption1Strong": { + "face": "primary", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "captionStandard": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "display": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "headerSemibold": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "headerStandard": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "heroLargeSemibold": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "heroLargeStandard": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "heroSemibold": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "heroStandard": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "largeTitle": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "secondarySemibold": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "secondaryStandard": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "subheaderSemibold": { + "face": "primary", + "size": 16, + "weight": "600", + }, + "subheaderStandard": { + "face": "primary", + "size": 16, + "weight": "400", + }, + "subtitle1": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "subtitle1Strong": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "subtitle2": { + "face": "primary", + "size": 16, + "weight": "400", + }, + "subtitle2Strong": { + "face": "primary", + "size": 16, + "weight": "600", + }, + "title1": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "title1Strong": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", + }, + }, + "weights": { + "regular": "400", + "semiBold": "600", + }, + }, +} +`; + +exports[`high contrast dark theme 1`] = ` +{ + "colors": { + "accentButtonBackground": { "resource_paths": [ - "Window", + "ButtonFace", ], }, - "neutralBackground4Hover": { + "actionLink": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "neutralBackground4Pressed": { + "background": { "resource_paths": [ - "Highlight", + "Window", ], }, - "neutralBackground4Selected": { + "bodyDivider": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "neutralBackground5": { + "bodyFrameBackground": { "resource_paths": [ "Window", ], }, - "neutralBackground5Hover": { + "bodyFrameDivider": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "neutralBackground5Pressed": { + "bodyStandoutBackground": { "resource_paths": [ - "Highlight", + "Window", ], }, - "neutralBackground5Selected": { + "bodyText": { "resource_paths": [ - "Highlight", + "WindowText", ], }, - "neutralBackground6": { + "bodyTextChecked": { "resource_paths": [ - "Window", + "HighlightText", ], }, - "neutralBackgroundDisabled": { + "brandBackground": { "resource_paths": [ - "Window", + "ButtonFace", ], }, - "neutralBackgroundInverted": { + "brandBackground2": { "resource_paths": [ - "WindowText", + "ButtonFace", ], }, - "neutralForeground1": { + "brandBackground2Pressed": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "neutralForeground1Hover": { + "brandBackground2Selected": { "resource_paths": [ - "HighlightText", + "Highlight", ], }, - "neutralForeground1Pressed": { + "brandBackground3": { "resource_paths": [ - "HighlightText", + "ButtonFace", ], }, - "neutralForeground1Selected": { + "brandBackgroundDisabled": { "resource_paths": [ - "HighlightText", + "Window", ], }, - "neutralForeground2": { + "brandBackgroundHover": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "neutralForeground2BrandHover": { + "brandBackgroundInverted": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralForeground2BrandPressed": { + "brandBackgroundInvertedDisabled": { "resource_paths": [ - "HighlightText", + "Window", ], }, - "neutralForeground2BrandSelected": { + "brandBackgroundPressed": { "resource_paths": [ - "HighlightText", + "Highlight", ], }, - "neutralForeground2Hover": { + "brandBackgroundSelected": { "resource_paths": [ - "HighlightText", + "Highlight", ], }, - "neutralForeground2Pressed": { + "brandBackgroundStatic": { "resource_paths": [ - "HighlightText", + "Window", ], }, - "neutralForeground2Selected": { + "brandBackgroundTint": { "resource_paths": [ - "HighlightText", + "ButtonFace", ], }, - "neutralForeground3": { + "brandForeground1": { "resource_paths": [ "WindowText", ], }, - "neutralForeground3BrandHover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3BrandPressed": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3BrandSelected": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForeground3Hover": { + "brandForeground1Disabled": { "resource_paths": [ - "HighlightText", + "GrayText", ], }, - "neutralForeground3Pressed": { + "brandForeground1Pressed": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralForeground3Selected": { + "brandForeground1Selected": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralForeground4": { + "brandForeground2": { "resource_paths": [ - "WindowText", + "ButtonText", ], }, - "neutralForegroundDisabled": { + "brandForegroundDisabled1": { "resource_paths": [ "GrayText", ], }, - "neutralForegroundInverted": { + "brandForegroundDisabled2": { "resource_paths": [ - "Window", + "GrayText", ], }, - "neutralForegroundInvertedLink": { + "brandForegroundLink": { "resource_paths": [ "Hotlight", ], }, - "neutralForegroundInvertedLinkHover": { + "brandForegroundLinkHover": { "resource_paths": [ "Hotlight", ], }, - "neutralForegroundInvertedLinkPressed": { + "brandForegroundLinkPressed": { "resource_paths": [ "Hotlight", ], }, - "neutralForegroundInvertedLinkSelected": { + "brandForegroundLinkSelected": { "resource_paths": [ "Hotlight", ], }, - "neutralForegroundOnBrand": { + "brandForegroundTint": { "resource_paths": [ "ButtonText", ], }, - "neutralForegroundOnBrandHover": { - "resource_paths": [ - "HighlightText", - ], - }, - "neutralForegroundOnBrandPressed": { + "brandStroke1": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralForegroundOnBrandSelected": { + "brandStroke1Pressed": { "resource_paths": [ - "HighlightText", + "WindowText", ], }, - "neutralStencil1": "#141414", - "neutralStencil2": "#858585", - "neutralStroke1": { + "brandStroke1Selected": { "resource_paths": [ "WindowText", ], }, - "neutralStroke1Hover": { + "brandStroke2": { "resource_paths": [ - "Highlight", + "Window", ], }, - "neutralStroke1Pressed": { + "brandStrokeTint": { "resource_paths": [ - "Highlight", + "Window", ], }, - "neutralStroke1Selected": { + "brandedBackground": { "resource_paths": [ - "Highlight", + "ButtonFace", ], }, - "neutralStroke2": { + "brandedDisabledBorder": { "resource_paths": [ - "WindowText", + "GrayText", ], }, - "neutralStroke3": { + "brandedFocusedSecondaryContent": { "resource_paths": [ - "WindowText", + "HighlightText", ], }, - "neutralStrokeAccessible": { + "brandedHoveredSecondaryContent": { "resource_paths": [ - "WindowText", + "HighlightText", ], }, - "neutralStrokeAccessibleHover": { + "brandedPressedSecondaryContent": { "resource_paths": [ - "Highlight", + "HighlightText", ], }, - "neutralStrokeAccessiblePressed": { + "brandedSecondaryContent": { "resource_paths": [ - "Highlight", + "ButtonText", ], }, - "neutralStrokeAccessibleSelected": { + "buttonBackground": { "resource_paths": [ - "Highlight", + "Window", ], }, - "neutralStrokeDisabled": { + "buttonBackgroundChecked": { "resource_paths": [ - "GrayText", + "Highlight", ], }, - "outofofficeBackground1": { + "buttonBackgroundDisabled": { "resource_paths": [ "Window", ], }, - "outofofficeBackground2": { + "buttonBackgroundHovered": { "resource_paths": [ - "Window", + "Highlight", ], }, - "outofofficeBackground3": { + "buttonBackgroundPressed": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "outofofficeBorder1": { + "buttonBorder": { "resource_paths": [ "WindowText", ], }, - "outofofficeBorder2": { + "buttonBorderDisabled": { "resource_paths": [ - "WindowText", + "GrayText", ], }, - "outofofficeBorderActive": { + "buttonBorderFocused": { "resource_paths": [ "Highlight", ], }, - "outofofficeForeground1": { + "buttonText": { "resource_paths": [ "WindowText", ], }, - "outofofficeForeground2": { + "buttonTextChecked": { "resource_paths": [ - "WindowText", + "HighlightText", ], }, - "outofofficeForeground3": { + "buttonTextDisabled": { "resource_paths": [ - "WindowText", + "GrayText", ], }, - "personaActivityGlow": "transparent", - "personaActivityRing": "#ffffff", - "primaryButtonBackground": "#000000", - "primaryButtonBackgroundDisabled": "#000000", - "primaryButtonBackgroundHovered": "#1aebff", - "primaryButtonBackgroundPressed": "#1aebff", - "primaryButtonBorder": "#ffffff", - "primaryButtonBorderFocused": "#ffffff", - "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#3ff23f", - "primaryButtonTextHovered": "#000000", - "primaryButtonTextPressed": "#000000", - "severeBackground1": { + "buttonTextHovered": { "resource_paths": [ - "Window", + "HighlightText", ], }, - "severeBackground2": { + "buttonTextPressed": { "resource_paths": [ - "Window", + "HighlightText", ], }, - "severeBackground3": { + "checkboxBackground": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "severeBorder1": { + "checkboxBackgroundDisabled": { "resource_paths": [ - "WindowText", + "Window", ], }, - "severeBorder2": { + "checkboxBorderColor": { "resource_paths": [ "WindowText", ], }, - "severeBorderActive": { + "checkmarkColor": { + "resource_paths": [ + "ButtonText", + ], + }, + "compoundBrandBackground1": { "resource_paths": [ "Highlight", ], }, - "severeForeground1": { + "compoundBrandBackground1Hover": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "severeForeground2": { + "compoundBrandBackground1Pressed": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "severeForeground3": { + "compoundBrandForeground1": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "strokeFocus1": { + "compoundBrandForeground1Hover": { "resource_paths": [ - "Window", + "Highlight", ], }, - "strokeFocus2": { + "compoundBrandForeground1Pressed": { "resource_paths": [ "Highlight", ], }, - "subText": "#ffffff", - "subtleBackground": "#00000000", - "subtleBackgroundHover": { + "compoundBrandStroke1": { "resource_paths": [ "Highlight", ], }, - "subtleBackgroundPressed": { + "compoundBrandStroke1Hover": { "resource_paths": [ "Highlight", ], }, - "subtleBackgroundSelected": { + "compoundBrandStroke1Pressed": { "resource_paths": [ "Highlight", ], }, - "successBackground1": { + "dangerBackground1": { "resource_paths": [ "Window", ], }, - "successBackground2": { + "dangerBackground2": { "resource_paths": [ "Window", ], }, - "successBackground3": { + "dangerBackground3": { "resource_paths": [ "WindowText", ], }, - "successBorder1": { + "dangerBorder1": { "resource_paths": [ "WindowText", ], }, - "successBorder2": { + "dangerBorder2": { "resource_paths": [ "WindowText", ], }, - "successBorderActive": { + "dangerBorderActive": { "resource_paths": [ "Highlight", ], }, - "successForeground1": { + "dangerForeground1": { "resource_paths": [ "WindowText", ], }, - "successForeground2": { + "dangerForeground2": { "resource_paths": [ "WindowText", ], }, - "successForeground3": { + "dangerForeground3": { "resource_paths": [ "WindowText", ], }, - "successForegroundInverted": { + "dangerForegroundInverted": { "resource_paths": [ "WindowText", ], }, - "transparentBackground": "#00000000", - "transparentBackgroundHover": "#00000000", - "transparentBackgroundPressed": "#00000000", - "transparentBackgroundSelected": "#00000000", - "transparentStroke": { + "dangerStroke1": { "resource_paths": [ "WindowText", ], }, - "transparentStrokeDisabled": { + "defaultBackground": { "resource_paths": [ - "GrayText", + "Window", ], }, - "transparentStrokeInteractive": { + "defaultBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultCheckedBackground": { "resource_paths": [ "Highlight", ], }, - "variantBorder": "#ffffff", - "warningBackground1": { + "defaultCheckedContent": { "resource_paths": [ - "Window", + "HighlightText", ], }, - "warningBackground2": { + "defaultCheckedHoveredBackground": { "resource_paths": [ - "Window", + "Highlight", ], }, - "warningBackground3": { + "defaultCheckedHoveredContent": { "resource_paths": [ - "WindowText", + "HighlightText", ], }, - "warningBorder1": { + "defaultContent": { "resource_paths": [ "WindowText", ], }, - "warningBorder2": { + "defaultDisabledBackground": { "resource_paths": [ - "WindowText", + "Window", ], }, - "warningBorderActive": { + "defaultDisabledBorder": { "resource_paths": [ - "Highlight", + "GrayText", ], }, - "warningForeground1": { + "defaultDisabledContent": { "resource_paths": [ - "WindowText", + "GrayText", ], }, - "warningForeground2": { + "defaultDisabledIcon": { "resource_paths": [ - "WindowText", + "GrayText", ], }, - "warningForeground3": { + "defaultFocusedBackground": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - "warningForegroundInverted": { + "defaultFocusedBorder": { "resource_paths": [ - "WindowText", + "Highlight", ], }, - }, - "components": {}, - "host": { - "appearance": "highContrast", - }, - "shadows": { - "shadow16": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000047", - "x": 0, - "y": 8, - }, + "defaultFocusedContent": { + "resource_paths": [ + "HighlightText", + ], }, - "shadow16brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000040", - "x": 0, - "y": 8, - }, + "defaultFocusedIcon": { + "resource_paths": [ + "HighlightText", + ], }, - "shadow2": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000047", - "x": 0, - "y": 1, - }, + "defaultHoveredBackground": { + "resource_paths": [ + "Highlight", + ], }, - "shadow28": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#0000007a", - "x": 0, - "y": 14, - }, + "defaultHoveredBorder": { + "resource_paths": [ + "Highlight", + ], }, - "shadow28brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#00000040", - "x": 0, - "y": 14, - }, + "defaultHoveredContent": { + "resource_paths": [ + "HighlightText", + ], }, - "shadow2brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000040", - "x": 0, - "y": 1, - }, + "defaultHoveredIcon": { + "resource_paths": [ + "HighlightText", + ], }, - "shadow4": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000047", - "x": 0, - "y": 2, - }, + "defaultHoveredSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], }, - "shadow4brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000040", - "x": 0, - "y": 2, - }, + "defaultIcon": { + "resource_paths": [ + "WindowText", + ], }, - "shadow64": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#0000007a", - "x": 0, - "y": 32, - }, + "defaultPressedBackground": { + "resource_paths": [ + "Highlight", + ], }, - "shadow64brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#00000040", - "x": 0, - "y": 32, - }, + "defaultPressedBorder": { + "resource_paths": [ + "Highlight", + ], }, - "shadow8": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000047", - "x": 0, - "y": 4, - }, + "defaultPressedContent": { + "resource_paths": [ + "HighlightText", + ], }, - "shadow8brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000040", - "x": 0, - "y": 4, - }, + "defaultPressedIcon": { + "resource_paths": [ + "HighlightText", + ], }, - }, - "spacing": { - "l1": "20px", - "l2": "32px", - "m": "16px", - "s1": "8px", - "s2": "4px", - }, - "typography": { - "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "Segoe UI", - "sansSerif": "System", - "secondary": "Segoe UI", - "serif": "System", + "defaultPressedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], }, - "sizes": { - "body": 14, - "caption": 10, - "header": 20, - "hero": 28, - "heroLarge": 40, - "secondary": 12, - "subheader": 16, + "disabledBackground": { + "resource_paths": [ + "Window", + ], }, - "variants": { - "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", - }, - "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", - }, - "body2": { - "face": "primary", - "size": "body", - "weight": "regular", - }, - "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", - }, - "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", - }, - "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", - }, - "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", - }, - "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", - }, - "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", - }, - "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", - }, - "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", - }, - "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", - }, - "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", - }, - "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", - }, - "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", - }, - "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", - }, - "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", - }, - "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", + "disabledBodyText": { + "resource_paths": [ + "GrayText", + ], + }, + "disabledText": { + "resource_paths": [ + "GrayText", + ], + }, + "errorText": { + "resource_paths": [ + "WindowText", + ], + }, + "focusBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostBackground": "#00000000", + "ghostBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostCheckedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostCheckedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostCheckedHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostCheckedHoveredBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostCheckedHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostContent": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostDisabledContent": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostDisabledIcon": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostFocusedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostFocusedBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostFocusedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostFocusedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostFocusedSecondaryContent": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostHoveredBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostHoveredIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostHoveredSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostIcon": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostPressedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostPressedBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostPressedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostPressedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostPressedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostSecondaryContent": { + "resource_paths": [ + "WindowText", + ], + }, + "inputBackground": { + "resource_paths": [ + "Window", + ], + }, + "inputBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "inputFocusBorderAlt": { + "resource_paths": [ + "Highlight", + ], + }, + "inputPlaceholderText": { + "resource_paths": [ + "WindowText", + ], + }, + "inputText": { + "resource_paths": [ + "WindowText", + ], + }, + "link": { + "resource_paths": [ + "Hotlight", + ], + }, + "linkHovered": { + "resource_paths": [ + "Hotlight", + ], + }, + "linkPressed": { + "resource_paths": [ + "Hotlight", + ], + }, + "listHeaderBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "listHeaderBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "menuBackground": { + "resource_paths": [ + "Window", + ], + }, + "menuDivider": { + "resource_paths": [ + "WindowText", + ], + }, + "menuIcon": { + "resource_paths": [ + "WindowText", + ], + }, + "menuItemBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "menuItemBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "menuItemText": { + "resource_paths": [ + "WindowText", + ], + }, + "menuItemTextHovered": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralBackground1": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground1Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground2": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground2Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground2Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground2Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground3": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground3Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground3Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground3Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground4": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground4Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground4Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground4Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground5": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground5Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground5Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground5Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground6": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackgroundCanvas": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackgroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": { + "resource_paths": [ + "Window", + ], + }, + "neutralForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForeground1Hover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground1Pressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground1Selected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForeground2BrandHover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2BrandPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2BrandSelected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2Hover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2Pressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2Selected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForeground3BrandHover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3BrandPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3BrandSelected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3Hover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3Pressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3Selected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground4": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundDisabled1": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundDisabled2": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundInverted": { + "resource_paths": [ + "Window", + ], + }, + "neutralForegroundInvertedLink": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkHover": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkPressed": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkSelected": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": { + "resource_paths": [ + "ButtonText", + ], + }, + "neutralForegroundOnBrandHover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnBrandPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnBrandSelected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnColor": { + "resource_paths": [ + "ButtonText", + ], + }, + "neutralStencil1": "#141414", + "neutralStencil2": "#858585", + "neutralStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStroke1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke1Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke2": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStroke3": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStrokeAccessible": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStrokeAccessibleHover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeAccessiblePressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeAccessibleSelected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralStrokeFocus1": { + "resource_paths": [ + "Window", + ], + }, + "neutralStrokeFocus2": { + "resource_paths": [ + "Highlight", + ], + }, + "outofofficeBackground1": { + "resource_paths": [ + "Window", + ], + }, + "outofofficeBackground2": { + "resource_paths": [ + "Window", + ], + }, + "outofofficeBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "outofofficeForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "personaActivityGlow": { + "resource_paths": [ + "ButtonFace", + ], + }, + "personaActivityRing": { + "resource_paths": [ + "Window", + ], + }, + "presenceAvailable": { + "resource_paths": [ + "WindowText", + ], + }, + "presenceAway": { + "resource_paths": [ + "WindowText", + ], + }, + "presenceDnd": { + "resource_paths": [ + "WindowText", + ], + }, + "presenceOof": { + "resource_paths": [ + "WindowText", + ], + }, + "primaryButtonBackground": { + "resource_paths": [ + "ButtonFace", + ], + }, + "primaryButtonBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "primaryButtonBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "primaryButtonBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "primaryButtonBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "primaryButtonBorderFocused": { + "resource_paths": [ + "Highlight", + ], + }, + "primaryButtonText": { + "resource_paths": [ + "ButtonText", + ], + }, + "primaryButtonTextDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "primaryButtonTextHovered": { + "resource_paths": [ + "HighlightText", + ], + }, + "primaryButtonTextPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "redBackground1": { + "resource_paths": [ + "Window", + ], + }, + "redBackground2": { + "resource_paths": [ + "Window", + ], + }, + "redBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "redBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "redBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "redBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "redForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "redForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "redForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBackground1": { + "resource_paths": [ + "Window", + ], + }, + "severeBackground2": { + "resource_paths": [ + "Window", + ], + }, + "severeBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "severeForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "severeForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "severeForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "severeStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "strokeFocus1": { + "resource_paths": [ + "Window", + ], + }, + "strokeFocus2": { + "resource_paths": [ + "Highlight", + ], + }, + "subText": { + "resource_paths": [ + "WindowText", + ], + }, + "subtleBackground": "#00000000", + "subtleBackgroundHover": { + "resource_paths": [ + "Highlight", + ], + }, + "subtleBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "subtleBackgroundSelected": { + "resource_paths": [ + "Highlight", + ], + }, + "successBackground1": { + "resource_paths": [ + "Window", + ], + }, + "successBackground2": { + "resource_paths": [ + "Window", + ], + }, + "successBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "successBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "successBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "successBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "successForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "successForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "successForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "successForegroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "successStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": { + "resource_paths": [ + "WindowText", + ], + }, + "transparentStrokeDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "transparentStrokeInteractive": { + "resource_paths": [ + "Highlight", + ], + }, + "variantBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBackground1": { + "resource_paths": [ + "Window", + ], + }, + "warningBackground2": { + "resource_paths": [ + "Window", + ], + }, + "warningBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "warningForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "warningForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "warningForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "warningForegroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "warningStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + }, + "components": {}, + "host": { + "appearance": "highContrast", + }, + "shadows": { + "shadow16": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000047", + "x": 0, + "y": 8, + }, + }, + "shadow16brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000040", + "x": 0, + "y": 8, + }, + }, + "shadow2": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000047", + "x": 0, + "y": 1, + }, + }, + "shadow28": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#0000007a", + "x": 0, + "y": 14, + }, + }, + "shadow28brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000040", + "x": 0, + "y": 14, + }, + }, + "shadow2brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000040", + "x": 0, + "y": 1, + }, + }, + "shadow4": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000047", + "x": 0, + "y": 2, + }, + }, + "shadow4brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000040", + "x": 0, + "y": 2, + }, + }, + "shadow64": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#0000007a", + "x": 0, + "y": 32, + }, + }, + "shadow64brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000040", + "x": 0, + "y": 32, + }, + }, + "shadow8": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000047", + "x": 0, + "y": 4, + }, + }, + "shadow8brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000040", + "x": 0, + "y": 4, + }, + }, + }, + "spacing": { + "l1": "20px", + "l2": "32px", + "m": "16px", + "s1": "8px", + "s2": "4px", + }, + "typography": { + "families": { + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", + "primary": "Segoe UI", + "sansSerif": "Segoe UI", + "secondary": "Segoe UI", + "serif": "Segoe UI", + }, + "sizes": { + "body": 14, + "caption": 10, + "header": 20, + "hero": 28, + "heroLarge": 40, + "secondary": 12, + "subheader": 16, + }, + "variants": { + "body1": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "body1Strong": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "body2": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "body2Strong": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodySemibold": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodyStandard": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "caption1": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "caption1Strong": { + "face": "primary", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "captionStandard": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "display": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "headerSemibold": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "headerStandard": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "heroLargeSemibold": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "heroLargeStandard": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "heroSemibold": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "heroStandard": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "largeTitle": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "secondarySemibold": { + "face": "primary", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, - "weights": { - "regular": "400", - "semiBold": "600", + "weights": { + "regular": "400", + "semiBold": "600", + }, + }, +} +`; + +exports[`high contrast light theme 1`] = ` +{ + "colors": { + "accentButtonBackground": { + "resource_paths": [ + "ButtonFace", + ], + }, + "actionLink": { + "resource_paths": [ + "WindowText", + ], + }, + "background": { + "resource_paths": [ + "Window", + ], + }, + "bodyDivider": { + "resource_paths": [ + "WindowText", + ], + }, + "bodyFrameBackground": { + "resource_paths": [ + "Window", + ], + }, + "bodyFrameDivider": { + "resource_paths": [ + "WindowText", + ], + }, + "bodyStandoutBackground": { + "resource_paths": [ + "Window", + ], + }, + "bodyText": { + "resource_paths": [ + "WindowText", + ], + }, + "bodyTextChecked": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandBackground": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandBackground2": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandBackground2Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackground2Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackground3": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "brandBackgroundHover": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackgroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "brandBackgroundInvertedDisabled": { + "resource_paths": [ + "Window", + ], + }, + "brandBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackgroundSelected": { + "resource_paths": [ + "Highlight", + ], + }, + "brandBackgroundStatic": { + "resource_paths": [ + "Window", + ], + }, + "brandBackgroundTint": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "brandForeground1Disabled": { + "resource_paths": [ + "GrayText", + ], + }, + "brandForeground1Pressed": { + "resource_paths": [ + "WindowText", + ], + }, + "brandForeground1Selected": { + "resource_paths": [ + "WindowText", + ], + }, + "brandForeground2": { + "resource_paths": [ + "ButtonText", + ], + }, + "brandForegroundDisabled1": { + "resource_paths": [ + "GrayText", + ], + }, + "brandForegroundDisabled2": { + "resource_paths": [ + "GrayText", + ], + }, + "brandForegroundLink": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundLinkHover": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundLinkPressed": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundLinkSelected": { + "resource_paths": [ + "Hotlight", + ], + }, + "brandForegroundTint": { + "resource_paths": [ + "ButtonText", + ], + }, + "brandStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "brandStroke1Pressed": { + "resource_paths": [ + "WindowText", + ], + }, + "brandStroke1Selected": { + "resource_paths": [ + "WindowText", + ], + }, + "brandStroke2": { + "resource_paths": [ + "Window", + ], + }, + "brandStrokeTint": { + "resource_paths": [ + "Window", + ], + }, + "brandedBackground": { + "resource_paths": [ + "ButtonFace", + ], + }, + "brandedDisabledBorder": { + "resource_paths": [ + "GrayText", + ], + }, + "brandedFocusedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandedHoveredSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandedPressedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "brandedSecondaryContent": { + "resource_paths": [ + "ButtonText", + ], + }, + "buttonBackground": { + "resource_paths": [ + "Window", + ], + }, + "buttonBackgroundChecked": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "buttonBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "buttonBorderDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "buttonBorderFocused": { + "resource_paths": [ + "Highlight", + ], + }, + "buttonText": { + "resource_paths": [ + "WindowText", + ], + }, + "buttonTextChecked": { + "resource_paths": [ + "HighlightText", + ], + }, + "buttonTextDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "buttonTextHovered": { + "resource_paths": [ + "HighlightText", + ], + }, + "buttonTextPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "checkboxBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "checkboxBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "checkboxBorderColor": { + "resource_paths": [ + "WindowText", + ], + }, + "checkmarkColor": { + "resource_paths": [ + "ButtonText", + ], + }, + "compoundBrandBackground1": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandBackground1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandBackground1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandForeground1": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandForeground1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandForeground1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandStroke1": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandStroke1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "compoundBrandStroke1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "dangerBackground1": { + "resource_paths": [ + "Window", + ], + }, + "dangerBackground2": { + "resource_paths": [ + "Window", + ], + }, + "dangerBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "dangerForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerForegroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "dangerStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultBackground": { + "resource_paths": [ + "Window", + ], + }, + "defaultBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultCheckedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultCheckedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultCheckedHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultCheckedHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultContent": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultDisabledBackground": { + "resource_paths": [ + "Window", + ], + }, + "defaultDisabledBorder": { + "resource_paths": [ + "GrayText", + ], + }, + "defaultDisabledContent": { + "resource_paths": [ + "GrayText", + ], + }, + "defaultDisabledIcon": { + "resource_paths": [ + "GrayText", + ], + }, + "defaultFocusedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultFocusedBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultFocusedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultFocusedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultHoveredBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultHoveredIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultHoveredSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultIcon": { + "resource_paths": [ + "WindowText", + ], + }, + "defaultPressedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultPressedBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "defaultPressedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultPressedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "defaultPressedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "disabledBackground": { + "resource_paths": [ + "Window", + ], + }, + "disabledBodyText": { + "resource_paths": [ + "GrayText", + ], + }, + "disabledText": { + "resource_paths": [ + "GrayText", + ], + }, + "errorText": { + "resource_paths": [ + "WindowText", + ], + }, + "focusBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostBackground": "#00000000", + "ghostBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostCheckedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostCheckedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostCheckedHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostCheckedHoveredBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostCheckedHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostContent": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostDisabledContent": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostDisabledIcon": { + "resource_paths": [ + "GrayText", + ], + }, + "ghostFocusedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostFocusedBorder": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostFocusedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostFocusedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostFocusedSecondaryContent": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostHoveredBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostHoveredBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostHoveredContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostHoveredIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostHoveredSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostIcon": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostPressedBackground": { + "resource_paths": [ + "Highlight", + ], + }, + "ghostPressedBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "ghostPressedContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostPressedIcon": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostPressedSecondaryContent": { + "resource_paths": [ + "HighlightText", + ], + }, + "ghostSecondaryContent": { + "resource_paths": [ + "WindowText", + ], + }, + "inputBackground": { + "resource_paths": [ + "Window", + ], + }, + "inputBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "inputFocusBorderAlt": { + "resource_paths": [ + "Highlight", + ], + }, + "inputPlaceholderText": { + "resource_paths": [ + "WindowText", + ], + }, + "inputText": { + "resource_paths": [ + "WindowText", + ], + }, + "link": { + "resource_paths": [ + "Hotlight", + ], + }, + "linkHovered": { + "resource_paths": [ + "Hotlight", + ], + }, + "linkPressed": { + "resource_paths": [ + "Hotlight", + ], + }, + "listHeaderBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "listHeaderBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "menuBackground": { + "resource_paths": [ + "Window", + ], + }, + "menuDivider": { + "resource_paths": [ + "WindowText", + ], + }, + "menuIcon": { + "resource_paths": [ + "WindowText", + ], + }, + "menuItemBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "menuItemBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "menuItemText": { + "resource_paths": [ + "WindowText", + ], + }, + "menuItemTextHovered": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralBackground1": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground1Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground2": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground2Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground2Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground2Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground3": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground3Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground3Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground3Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground4": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground4Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground4Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground4Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground5": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackground5Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground5Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground5Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralBackground6": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackgroundCanvas": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "neutralBackgroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": { + "resource_paths": [ + "Window", + ], + }, + "neutralForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForeground1Hover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground1Pressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground1Selected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForeground2BrandHover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2BrandPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2BrandSelected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2Hover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2Pressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground2Selected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForeground3BrandHover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3BrandPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3BrandSelected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3Hover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3Pressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground3Selected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForeground4": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundDisabled1": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundDisabled2": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralForegroundInverted": { + "resource_paths": [ + "Window", + ], + }, + "neutralForegroundInvertedLink": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkHover": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkPressed": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundInvertedLinkSelected": { + "resource_paths": [ + "Hotlight", + ], + }, + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": { + "resource_paths": [ + "ButtonText", + ], + }, + "neutralForegroundOnBrandHover": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnBrandPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnBrandSelected": { + "resource_paths": [ + "HighlightText", + ], + }, + "neutralForegroundOnColor": { + "resource_paths": [ + "ButtonText", + ], + }, + "neutralStencil1": "#141414", + "neutralStencil2": "#858585", + "neutralStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStroke1Hover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke1Pressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke1Selected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStroke2": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStroke3": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStrokeAccessible": { + "resource_paths": [ + "WindowText", + ], + }, + "neutralStrokeAccessibleHover": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeAccessiblePressed": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeAccessibleSelected": { + "resource_paths": [ + "Highlight", + ], + }, + "neutralStrokeDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "neutralStrokeFocus1": { + "resource_paths": [ + "Window", + ], + }, + "neutralStrokeFocus2": { + "resource_paths": [ + "Highlight", + ], + }, + "outofofficeBackground1": { + "resource_paths": [ + "Window", + ], + }, + "outofofficeBackground2": { + "resource_paths": [ + "Window", + ], + }, + "outofofficeBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "outofofficeForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "outofofficeForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "personaActivityGlow": { + "resource_paths": [ + "ButtonFace", + ], + }, + "personaActivityRing": { + "resource_paths": [ + "Window", + ], + }, + "presenceAvailable": { + "resource_paths": [ + "WindowText", + ], + }, + "presenceAway": { + "resource_paths": [ + "WindowText", + ], + }, + "presenceDnd": { + "resource_paths": [ + "WindowText", + ], + }, + "presenceOof": { + "resource_paths": [ + "WindowText", + ], + }, + "primaryButtonBackground": { + "resource_paths": [ + "ButtonFace", + ], + }, + "primaryButtonBackgroundDisabled": { + "resource_paths": [ + "Window", + ], + }, + "primaryButtonBackgroundHovered": { + "resource_paths": [ + "Highlight", + ], + }, + "primaryButtonBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "primaryButtonBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "primaryButtonBorderFocused": { + "resource_paths": [ + "Highlight", + ], + }, + "primaryButtonText": { + "resource_paths": [ + "ButtonText", + ], + }, + "primaryButtonTextDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "primaryButtonTextHovered": { + "resource_paths": [ + "HighlightText", + ], + }, + "primaryButtonTextPressed": { + "resource_paths": [ + "HighlightText", + ], + }, + "redBackground1": { + "resource_paths": [ + "Window", + ], + }, + "redBackground2": { + "resource_paths": [ + "Window", + ], + }, + "redBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "redBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "redBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "redBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "redForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "redForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "redForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBackground1": { + "resource_paths": [ + "Window", + ], + }, + "severeBackground2": { + "resource_paths": [ + "Window", + ], + }, + "severeBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "severeBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "severeForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "severeForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "severeForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "severeStroke1": { + "resource_paths": [ + "WindowText", + ], + }, + "strokeFocus1": { + "resource_paths": [ + "Window", + ], + }, + "strokeFocus2": { + "resource_paths": [ + "Highlight", + ], + }, + "subText": { + "resource_paths": [ + "WindowText", + ], }, - }, -} -`; - -exports[`defaultFluentTheme 1`] = ` -{ - "colors": { - "accentButtonBackground": "#185abd", - "actionLink": "#323130", - "background": "#ffffff", - "bodyDivider": "#edebe9", - "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", - "bodyTextChecked": "#000000", - "brandBackground": "#185abd", - "brandBackground2": "#eff6fc", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#1651aa", - "brandBackgroundPressed": "#004578", - "brandBackgroundSelected": "#13458f", - "brandBackgroundStatic": "#185abd", - "brandForeground1": "#185abd", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#1651aa", - "brandForegroundLink": "#1651aa", - "brandForegroundLinkHover": "#13458f", - "brandForegroundLinkPressed": "#004578", - "brandForegroundLinkSelected": "#1651aa", - "brandStroke1": "#185abd", - "brandStroke2": "#d2e0f4", - "brandedBackground": "#185abd", - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", - "checkboxBackground": "#185abd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", - "checkmarkColor": "#ffffff", - "compoundBrandBackground1": "#185abd", - "compoundBrandBackground1Hover": "#1651aa", - "compoundBrandBackground1Pressed": "#13458f", - "compoundBrandForeground1": "#185abd", - "compoundBrandForeground1Hover": "#1651aa", - "compoundBrandForeground1Pressed": "#13458f", - "compoundBrandStroke1": "#185abd", - "compoundBrandStroke1Hover": "#1651aa", - "compoundBrandStroke1Pressed": "#13458f", - "dangerBackground1": "#fdf6f6", - "dangerBackground2": "#f1bbbc", - "dangerBackground3": "#d13438", - "dangerBorder1": "#f1bbbc", - "dangerBorder2": "#d13438", - "dangerBorderActive": "#d13438", - "dangerForeground1": "#bc2f32", - "dangerForeground2": "#751d1f", - "dangerForeground3": "#d13438", - "dangerForegroundInverted": "#dc5e62", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", - "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", - "inputFocusBorderAlt": "#185abd", - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", - "link": "#185abd", - "linkHovered": "#004578", - "linkPressed": "#13458f", - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", - "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": "#185abd", - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", - "neutralBackground1": "#ffffff", - "neutralBackground1Hover": "#f5f5f5", - "neutralBackground1Pressed": "#e0e0e0", - "neutralBackground1Selected": "#ebebeb", - "neutralBackground2": "#fafafa", - "neutralBackground2Hover": "#f0f0f0", - "neutralBackground2Pressed": "#dbdbdb", - "neutralBackground2Selected": "#e6e6e6", - "neutralBackground3": "#f5f5f5", - "neutralBackground3Hover": "#ebebeb", - "neutralBackground3Pressed": "#d6d6d6", - "neutralBackground3Selected": "#e0e0e0", - "neutralBackground4": "#f0f0f0", - "neutralBackground4Hover": "#fafafa", - "neutralBackground4Pressed": "#f5f5f5", - "neutralBackground4Selected": "#ffffff", - "neutralBackground5": "#ebebeb", - "neutralBackground5Hover": "#f5f5f5", - "neutralBackground5Pressed": "#f0f0f0", - "neutralBackground5Selected": "#fafafa", - "neutralBackground6": "#e6e6e6", - "neutralBackgroundDisabled": "#f0f0f0", - "neutralBackgroundInverted": "#616161", - "neutralForeground1": "#242424", - "neutralForeground1Hover": "#242424", - "neutralForeground1Pressed": "#242424", - "neutralForeground1Selected": "#242424", - "neutralForeground2": "#424242", - "neutralForeground2BrandHover": "#185abd", - "neutralForeground2BrandPressed": "#1651aa", - "neutralForeground2BrandSelected": "#185abd", - "neutralForeground2Hover": "#242424", - "neutralForeground2Pressed": "#242424", - "neutralForeground2Selected": "#242424", - "neutralForeground3": "#616161", - "neutralForeground3BrandHover": "#185abd", - "neutralForeground3BrandPressed": "#1651aa", - "neutralForeground3BrandSelected": "#185abd", - "neutralForeground3Hover": "#424242", - "neutralForeground3Pressed": "#424242", - "neutralForeground3Selected": "#424242", - "neutralForeground4": "#707070", - "neutralForegroundDisabled": "#bdbdbd", - "neutralForegroundInverted": "#ffffff", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", - "neutralForegroundOnBrand": "#ffffff", - "neutralForegroundOnBrandHover": "#ffffff", - "neutralForegroundOnBrandPressed": "#ffffff", - "neutralForegroundOnBrandSelected": "#ffffff", - "neutralStencil1": "#e6e6e6", - "neutralStencil2": "#fafafa", - "neutralStroke1": "#d1d1d1", - "neutralStroke1Hover": "#c7c7c7", - "neutralStroke1Pressed": "#b3b3b3", - "neutralStroke1Selected": "#bdbdbd", - "neutralStroke2": "#e0e0e0", - "neutralStroke3": "#f0f0f0", - "neutralStrokeAccessible": "#616161", - "neutralStrokeAccessibleHover": "#575757", - "neutralStrokeAccessiblePressed": "#4d4d4d", - "neutralStrokeAccessibleSelected": "#185abd", - "neutralStrokeDisabled": "#e0e0e0", - "outofofficeBackground1": "#fdf5fc", - "outofofficeBackground2": "#edbbe7", - "outofofficeBackground3": "#c239b3", - "outofofficeBorder1": "#edbbe7", - "outofofficeBorder2": "#c239b3", - "outofofficeBorderActive": "#c239b3", - "outofofficeForeground1": "#af33a1", - "outofofficeForeground2": "#6d2064", - "outofofficeForeground3": "#c239b3", - "personaActivityGlow": "#185abd", - "personaActivityRing": "#ffffff", - "primaryButtonBackground": "#185abd", - "primaryButtonBackgroundDisabled": "#f3f2f1", - "primaryButtonBackgroundHovered": "#1651aa", - "primaryButtonBackgroundPressed": "#13458f", - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", - "primaryButtonTextHovered": "#ffffff", - "primaryButtonTextPressed": "#ffffff", - "severeBackground1": "#fdf6f3", - "severeBackground2": "#f4bfab", - "severeBackground3": "#da3b01", - "severeBorder1": "#f4bfab", - "severeBorder2": "#da3b01", - "severeBorderActive": "#da3b01", - "severeForeground1": "#c43501", - "severeForeground2": "#7a2101", - "severeForeground3": "#da3b01", - "strokeFocus1": "#ffffff", - "strokeFocus2": "#000000", - "subText": "#605e5c", "subtleBackground": "#00000000", - "subtleBackgroundHover": "#f5f5f5", - "subtleBackgroundPressed": "#e0e0e0", - "subtleBackgroundSelected": "#ebebeb", - "successBackground1": "#f1faf1", - "successBackground2": "#9fd89f", - "successBackground3": "#107c10", - "successBorder1": "#9fd89f", - "successBorder2": "#107c10", - "successBorderActive": "#107c10", - "successForeground1": "#0e700e", - "successForeground2": "#094509", - "successForeground3": "#107c10", - "successForegroundInverted": "#359b35", + "subtleBackgroundHover": { + "resource_paths": [ + "Highlight", + ], + }, + "subtleBackgroundPressed": { + "resource_paths": [ + "Highlight", + ], + }, + "subtleBackgroundSelected": { + "resource_paths": [ + "Highlight", + ], + }, + "successBackground1": { + "resource_paths": [ + "Window", + ], + }, + "successBackground2": { + "resource_paths": [ + "Window", + ], + }, + "successBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "successBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "successBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "successBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "successForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "successForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "successForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "successForegroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "successStroke1": { + "resource_paths": [ + "WindowText", + ], + }, "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", "transparentBackgroundSelected": "#00000000", - "transparentStroke": "#00000000", - "transparentStrokeDisabled": "#00000000", - "transparentStrokeInteractive": "#00000000", - "variantBorder": "#edebe9", - "warningBackground1": "#fffef5", - "warningBackground2": "#fef7b2", - "warningBackground3": "#fde300", - "warningBorder1": "#fef7b2", - "warningBorder2": "#fde300", - "warningBorderActive": "#fde300", - "warningForeground1": "#817400", - "warningForeground2": "#817400", - "warningForeground3": "#fde300", - "warningForegroundInverted": "#fef7b2", + "transparentStroke": { + "resource_paths": [ + "WindowText", + ], + }, + "transparentStrokeDisabled": { + "resource_paths": [ + "GrayText", + ], + }, + "transparentStrokeInteractive": { + "resource_paths": [ + "Highlight", + ], + }, + "variantBorder": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBackground1": { + "resource_paths": [ + "Window", + ], + }, + "warningBackground2": { + "resource_paths": [ + "Window", + ], + }, + "warningBackground3": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBorder1": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBorder2": { + "resource_paths": [ + "WindowText", + ], + }, + "warningBorderActive": { + "resource_paths": [ + "Highlight", + ], + }, + "warningForeground1": { + "resource_paths": [ + "WindowText", + ], + }, + "warningForeground2": { + "resource_paths": [ + "WindowText", + ], + }, + "warningForeground3": { + "resource_paths": [ + "WindowText", + ], + }, + "warningForegroundInverted": { + "resource_paths": [ + "WindowText", + ], + }, + "warningStroke1": { + "resource_paths": [ + "WindowText", + ], + }, }, "components": {}, "host": { - "appearance": "light", + "appearance": "highContrast", }, "shadows": { "shadow16": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 16, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 8, }, @@ -2131,13 +4820,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow2": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 2, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 1, }, @@ -2145,13 +4834,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow28": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 28, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 14, }, @@ -2187,13 +4876,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow4": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 4, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 2, }, @@ -2215,13 +4904,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow64": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 64, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 32, }, @@ -2243,13 +4932,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow8": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 8, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 4, }, @@ -2278,13 +4967,13 @@ exports[`defaultFluentTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -2298,138 +4987,153 @@ exports[`defaultFluentTheme 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { diff --git a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.windows.ts.snap b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.windows.ts.snap index 75892f1df80..7de65b729d7 100644 --- a/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.windows.ts.snap +++ b/packages/theming/default-theme/src/__tests__/__snapshots__/defaultThemes.test.windows.ts.snap @@ -3,55 +3,68 @@ exports[`defaultFluentDarkTheme 1`] = ` { "colors": { - "accentButtonBackground": undefined, - "actionLink": "#f3f2f1", - "background": "#1b1a19", - "bodyDivider": "#292827", - "bodyFrameBackground": "#1b1a19", - "bodyFrameDivider": "#292827", - "bodyStandoutBackground": "#201f1e", - "bodyText": "#f3f2f1", + "accentButtonBackground": "#1651aa", + "actionLink": "#ffffff", + "background": "#292929", + "bodyDivider": "#525252", + "bodyFrameBackground": "#292929", + "bodyFrameDivider": "#525252", + "bodyStandoutBackground": "#1f1f1f", + "bodyText": "#ffffff", "bodyTextChecked": "#ffffff", "brandBackground": "#1651aa", "brandBackground2": "#004578", - "brandBackgroundDisabled": undefined, + "brandBackground2Pressed": "#004578", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#004578", + "brandBackgroundDisabled": "#141414", "brandBackgroundHover": "#185abd", + "brandBackgroundInverted": "#ffffff", + "brandBackgroundInvertedDisabled": "#141414", "brandBackgroundPressed": "#004578", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", + "brandBackgroundTint": "#004578", "brandForeground1": "#6794d7", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, + "brandForeground1Disabled": "#5c5c5c", + "brandForeground1Pressed": "#6794d7", + "brandForeground1Selected": "#6794d7", "brandForeground2": "#aec6eb", + "brandForegroundDisabled1": "#5c5c5c", + "brandForegroundDisabled2": "#5c5c5c", "brandForegroundLink": "#2e6ac5", "brandForegroundLinkHover": "#aec6eb", "brandForegroundLinkPressed": "#6794d7", "brandForegroundLinkSelected": "#2e6ac5", + "brandForegroundTint": "#aec6eb", "brandStroke1": "#2e6ac5", + "brandStroke1Pressed": "#2e6ac5", + "brandStroke1Selected": "#2e6ac5", "brandStroke2": "#0e336a", - "brandedBackground": undefined, - "brandedDisabledBorder": "#252423", - "brandedFocusedSecondaryContent": "#201f1e", - "brandedHoveredSecondaryContent": "#201f1e", - "brandedPressedSecondaryContent": "#201f1e", - "brandedSecondaryContent": "#201f1e", - "buttonBackground": "#252423", - "buttonBackgroundChecked": "#484644", - "buttonBackgroundDisabled": "#252423", - "buttonBackgroundHovered": "#292827", - "buttonBackgroundPressed": "#292827", - "buttonBorder": "#979693", - "buttonBorderDisabled": "#252423", - "buttonBorderFocused": "#979693", + "brandStrokeTint": "#0e336a", + "brandedBackground": "#1651aa", + "brandedDisabledBorder": "#00000000", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", + "buttonBackground": "#292929", + "buttonBackgroundChecked": "#383838", + "buttonBackgroundDisabled": "#141414", + "buttonBackgroundHovered": "#3d3d3d", + "buttonBackgroundPressed": "#1f1f1f", + "buttonBorder": "#666666", + "buttonBorderDisabled": "#424242", + "buttonBorderFocused": "#ffffff", "buttonText": "#ffffff", - "buttonTextChecked": "#faf9f8", - "buttonTextDisabled": "#797775", - "buttonTextHovered": "#f3f2f1", - "buttonTextPressed": "#faf9f8", - "checkboxBackground": undefined, - "checkboxBackgroundDisabled": "#252423", - "checkboxBorderColor": "#979693", - "checkmarkColor": "#1b1a19", + "buttonTextChecked": "#ffffff", + "buttonTextDisabled": "#5c5c5c", + "buttonTextHovered": "#ffffff", + "buttonTextPressed": "#ffffff", + "checkboxBackground": "#2e6ac5", + "checkboxBackgroundDisabled": "#141414", + "checkboxBorderColor": "#adadad", + "checkmarkColor": "#ffffff", "compoundBrandBackground1": "#2e6ac5", "compoundBrandBackground1Hover": "#6794d7", "compoundBrandBackground1Pressed": "#185abd", @@ -71,83 +84,84 @@ exports[`defaultFluentDarkTheme 1`] = ` "dangerForeground2": "#f1bbbc", "dangerForeground3": "#e37d80", "dangerForegroundInverted": "#d13438", - "defaultBackground": "#252423", - "defaultBorder": "#979693", - "defaultCheckedBackground": "#484644", - "defaultCheckedContent": "#faf9f8", - "defaultCheckedHoveredBackground": "#292827", - "defaultCheckedHoveredContent": "#f3f2f1", + "dangerStroke1": "#d13438", + "defaultBackground": "#292929", + "defaultBorder": "#666666", + "defaultCheckedBackground": "#383838", + "defaultCheckedContent": "#ffffff", + "defaultCheckedHoveredBackground": "#3d3d3d", + "defaultCheckedHoveredContent": "#ffffff", "defaultContent": "#ffffff", - "defaultDisabledBackground": "#252423", - "defaultDisabledBorder": "#252423", - "defaultDisabledContent": "#797775", - "defaultDisabledIcon": "#797775", - "defaultFocusedBackground": "#292827", - "defaultFocusedBorder": "#979693", - "defaultFocusedContent": "#f3f2f1", - "defaultFocusedIcon": "#f3f2f1", - "defaultHoveredBackground": "#292827", - "defaultHoveredBorder": "#979693", - "defaultHoveredContent": "#f3f2f1", - "defaultHoveredIcon": "#f3f2f1", - "defaultHoveredSecondaryContent": "#797775", + "defaultDisabledBackground": "#141414", + "defaultDisabledBorder": "#424242", + "defaultDisabledContent": "#5c5c5c", + "defaultDisabledIcon": "#5c5c5c", + "defaultFocusedBackground": "#3d3d3d", + "defaultFocusedBorder": "#ffffff", + "defaultFocusedContent": "#ffffff", + "defaultFocusedIcon": "#ffffff", + "defaultHoveredBackground": "#3d3d3d", + "defaultHoveredBorder": "#757575", + "defaultHoveredContent": "#ffffff", + "defaultHoveredIcon": "#ffffff", + "defaultHoveredSecondaryContent": "#d6d6d6", "defaultIcon": "#ffffff", - "defaultPressedBackground": "#292827", - "defaultPressedBorder": "#979693", - "defaultPressedContent": "#faf9f8", - "defaultPressedIcon": "#faf9f8", - "defaultPressedSecondaryContent": "#797775", - "disabledBackground": "#323130", - "disabledBodyText": "#797775", - "disabledText": "#797775", - "errorText": "#ff5f5f", - "focusBorder": "#a19f9d", - "ghostBackground": "#1b1a19", - "ghostBorder": "#1b1a19", - "ghostCheckedBackground": "#292827", + "defaultPressedBackground": "#1f1f1f", + "defaultPressedBorder": "#6b6b6b", + "defaultPressedContent": "#ffffff", + "defaultPressedIcon": "#ffffff", + "defaultPressedSecondaryContent": "#d6d6d6", + "disabledBackground": "#141414", + "disabledBodyText": "#5c5c5c", + "disabledText": "#5c5c5c", + "errorText": "#e37d80", + "focusBorder": "#ffffff", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#333333", "ghostCheckedContent": "#ffffff", - "ghostCheckedHoveredBackground": "#252423", - "ghostCheckedHoveredBorder": "#faf9f8", - "ghostCheckedHoveredContent": "#faf9f8", - "ghostContent": "#f3f2f1", - "ghostDisabledBackground": "#1b1a19", - "ghostDisabledBorder": "#1b1a19", - "ghostDisabledContent": "#797775", - "ghostDisabledIcon": "#797775", - "ghostFocusedBackground": "#252423", - "ghostFocusedBorder": "#979693", - "ghostFocusedContent": "#faf9f8", - "ghostFocusedIcon": "#faf9f8", - "ghostFocusedSecondaryContent": "#a19f9d", - "ghostHoveredBackground": "#252423", - "ghostHoveredBorder": "#252423", - "ghostHoveredContent": "#faf9f8", - "ghostHoveredIcon": "#faf9f8", - "ghostHoveredSecondaryContent": "#a19f9d", - "ghostIcon": "#f3f2f1", - "ghostPressedBackground": "#292827", - "ghostPressedBorder": "#292827", - "ghostPressedContent": "#faf9f8", - "ghostPressedIcon": "#faf9f8", - "ghostPressedSecondaryContent": "#a19f9d", - "ghostSecondaryContent": "#a19f9d", - "inputBackground": "#1b1a19", - "inputBorder": "#797775", - "inputFocusBorderAlt": undefined, - "inputPlaceholderText": "#a19f9d", - "inputText": "#f3f2f1", - "link": undefined, - "linkHovered": undefined, - "linkPressed": undefined, - "listHeaderBackgroundHovered": "#252423", - "listHeaderBackgroundPressed": "#292827", - "menuBackground": "#252423", - "menuDivider": "#484644", - "menuIcon": undefined, - "menuItemBackgroundHovered": "#323130", - "menuItemBackgroundPressed": "#3b3a39", - "menuItemText": "#f3f2f1", - "menuItemTextHovered": "#faf9f8", + "ghostCheckedHoveredBackground": "#383838", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#ffffff", + "ghostContent": "#ffffff", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#5c5c5c", + "ghostDisabledIcon": "#5c5c5c", + "ghostFocusedBackground": "#383838", + "ghostFocusedBorder": "#ffffff", + "ghostFocusedContent": "#ffffff", + "ghostFocusedIcon": "#ffffff", + "ghostFocusedSecondaryContent": "#adadad", + "ghostHoveredBackground": "#383838", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#ffffff", + "ghostHoveredIcon": "#ffffff", + "ghostHoveredSecondaryContent": "#d6d6d6", + "ghostIcon": "#ffffff", + "ghostPressedBackground": "#2e2e2e", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#ffffff", + "ghostPressedIcon": "#ffffff", + "ghostPressedSecondaryContent": "#d6d6d6", + "ghostSecondaryContent": "#adadad", + "inputBackground": "#292929", + "inputBorder": "#666666", + "inputFocusBorderAlt": "#2e6ac5", + "inputPlaceholderText": "#999999", + "inputText": "#ffffff", + "link": "#2e6ac5", + "linkHovered": "#aec6eb", + "linkPressed": "#6794d7", + "listHeaderBackgroundHovered": "#3d3d3d", + "listHeaderBackgroundPressed": "#1f1f1f", + "menuBackground": "#292929", + "menuDivider": "#525252", + "menuIcon": "#d6d6d6", + "menuItemBackgroundHovered": "#3d3d3d", + "menuItemBackgroundPressed": "#1f1f1f", + "menuItemText": "#ffffff", + "menuItemTextHovered": "#ffffff", "neutralBackground1": "#292929", "neutralBackground1Hover": "#3d3d3d", "neutralBackground1Pressed": "#1f1f1f", @@ -169,8 +183,12 @@ exports[`defaultFluentDarkTheme 1`] = ` "neutralBackground5Pressed": "#050505", "neutralBackground5Selected": "#0f0f0f", "neutralBackground6": "#333333", + "neutralBackgroundCanvas": "#292929", + "neutralBackgroundDarkStatic": "#3d3d3d", "neutralBackgroundDisabled": "#141414", "neutralBackgroundInverted": "#ffffff", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#141414", "neutralForeground1": "#ffffff", "neutralForeground1Hover": "#ffffff", "neutralForeground1Pressed": "#ffffff", @@ -190,16 +208,21 @@ exports[`defaultFluentDarkTheme 1`] = ` "neutralForeground3Pressed": "#d6d6d6", "neutralForeground3Selected": "#d6d6d6", "neutralForeground4": "#999999", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#5c5c5c", + "neutralForegroundDisabled1": "#5c5c5c", + "neutralForegroundDisabled2": "#5c5c5c", "neutralForegroundInverted": "#242424", "neutralForegroundInvertedLink": "#ffffff", "neutralForegroundInvertedLinkHover": "#ffffff", "neutralForegroundInvertedLinkPressed": "#ffffff", "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#ffffff", "neutralForegroundOnBrandHover": "#ffffff", "neutralForegroundOnBrandPressed": "#ffffff", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#333333", "neutralStencil2": "#575757", "neutralStroke1": "#666666", @@ -213,6 +236,8 @@ exports[`defaultFluentDarkTheme 1`] = ` "neutralStrokeAccessiblePressed": "#b3b3b3", "neutralStrokeAccessibleSelected": "#6794d7", "neutralStrokeDisabled": "#424242", + "neutralStrokeFocus1": "#000000", + "neutralStrokeFocus2": "#ffffff", "outofofficeBackground1": "#3a1136", "outofofficeBackground2": "#6d2064", "outofofficeBackground3": "#c239b3", @@ -222,18 +247,31 @@ exports[`defaultFluentDarkTheme 1`] = ` "outofofficeForeground1": "#da7ed0", "outofofficeForeground2": "#edbbe7", "outofofficeForeground3": "#d161c4", - "personaActivityGlow": undefined, - "personaActivityRing": "#1b1a19", - "primaryButtonBackground": undefined, - "primaryButtonBackgroundDisabled": "#252423", - "primaryButtonBackgroundHovered": undefined, - "primaryButtonBackgroundPressed": undefined, - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#1b1a19", - "primaryButtonTextDisabled": "#3b3a39", - "primaryButtonTextHovered": "#1b1a19", - "primaryButtonTextPressed": "#1b1a19", + "personaActivityGlow": "#1651aa", + "personaActivityRing": "#292929", + "presenceAvailable": "#54b054", + "presenceAway": "#feee66", + "presenceDnd": "#e37d80", + "presenceOof": "#da7ed0", + "primaryButtonBackground": "#1651aa", + "primaryButtonBackgroundDisabled": "#141414", + "primaryButtonBackgroundHovered": "#185abd", + "primaryButtonBackgroundPressed": "#004578", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#ffffff", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#5c5c5c", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#3f1011", + "redBackground2": "#751d1f", + "redBackground3": "#d13438", + "redBorder1": "#d13438", + "redBorder2": "#dc5e62", + "redBorderActive": "#e37d80", + "redForeground1": "#e37d80", + "redForeground2": "#f1bbbc", + "redForeground3": "#e37d80", "severeBackground1": "#411200", "severeBackground2": "#7a2101", "severeBackground3": "#da3b01", @@ -243,9 +281,10 @@ exports[`defaultFluentDarkTheme 1`] = ` "severeForeground1": "#e9835e", "severeForeground2": "#f4bfab", "severeForeground3": "#e9835e", + "severeStroke1": "#da3b01", "strokeFocus1": "#000000", "strokeFocus2": "#ffffff", - "subText": "#a19f9d", + "subText": "#d6d6d6", "subtleBackground": "#00000000", "subtleBackgroundHover": "#383838", "subtleBackgroundPressed": "#2e2e2e", @@ -260,6 +299,7 @@ exports[`defaultFluentDarkTheme 1`] = ` "successForeground2": "#9fd89f", "successForeground3": "#9fd89f", "successForegroundInverted": "#107c10", + "successStroke1": "#107c10", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -267,7 +307,7 @@ exports[`defaultFluentDarkTheme 1`] = ` "transparentStroke": "#00000000", "transparentStrokeDisabled": "#00000000", "transparentStrokeInteractive": "#00000000", - "variantBorder": "#292827", + "variantBorder": "#525252", "warningBackground1": "#4c4400", "warningBackground2": "#817400", "warningBackground3": "#fde300", @@ -278,6 +318,7 @@ exports[`defaultFluentDarkTheme 1`] = ` "warningForeground2": "#fef7b2", "warningForeground3": "#fdea3d", "warningForegroundInverted": "#817400", + "warningStroke1": "#fde300", }, "components": {}, "host": { @@ -462,13 +503,13 @@ exports[`defaultFluentDarkTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -482,138 +523,153 @@ exports[`defaultFluentDarkTheme 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { @@ -624,1492 +680,4125 @@ exports[`defaultFluentDarkTheme 1`] = ` } `; -exports[`defaultFluentHighConstrastTheme 1`] = ` +exports[`defaultFluentTheme 1`] = ` { "colors": { - "accentButtonBackground": "#000000", - "actionLink": "#ffff00", - "background": "#000000", - "bodyDivider": "#ffffff", - "bodyFrameBackground": "#000000", - "bodyFrameDivider": "#000000", - "bodyStandoutBackground": "#000000", - "bodyText": "#ffffff", - "bodyTextChecked": "#000000", - "brandBackground": { - "windowsbrush": [ - "SystemColorButtonFaceColor", - ], - }, - "brandBackground2": { - "windowsbrush": [ - "SystemColorButtonFaceColor", - ], - }, - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "brandBackgroundPressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "brandBackgroundSelected": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "brandBackgroundStatic": { - "windowsbrush": [ - "SystemColorWindowColor", - ], - }, - "brandForeground1": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": { - "windowsbrush": [ - "SystemColorButtonTextColor", - ], - }, - "brandForegroundLink": { - "windowsbrush": [ - "SystemColorHotlightColor", - ], - }, - "brandForegroundLinkHover": { - "windowsbrush": [ - "SystemColorHotlightColor", - ], - }, - "brandForegroundLinkPressed": { - "windowsbrush": [ - "SystemColorHotlightColor", - ], - }, - "brandForegroundLinkSelected": { - "windowsbrush": [ - "SystemColorHotlightColor", - ], - }, - "brandStroke1": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "brandStroke2": { - "windowsbrush": [ - "SystemColorWindowColor", - ], - }, - "brandedBackground": "#000000", - "brandedDisabledBorder": "#3ff23f", + "accentButtonBackground": "#185abd", + "actionLink": "#242424", + "background": "#ffffff", + "bodyDivider": "#e0e0e0", + "bodyFrameBackground": "#ffffff", + "bodyFrameDivider": "#e0e0e0", + "bodyStandoutBackground": "#fafafa", + "bodyText": "#242424", + "bodyTextChecked": "#242424", + "brandBackground": "#185abd", + "brandBackground2": "#eff6fc", + "brandBackground2Pressed": "#004578", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#eff6fc", + "brandBackgroundDisabled": "#f0f0f0", + "brandBackgroundHover": "#1651aa", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", + "brandBackgroundPressed": "#004578", + "brandBackgroundSelected": "#13458f", + "brandBackgroundStatic": "#185abd", + "brandBackgroundTint": "#eff6fc", + "brandForeground1": "#185abd", + "brandForeground1Disabled": "#bdbdbd", + "brandForeground1Pressed": "#185abd", + "brandForeground1Selected": "#185abd", + "brandForeground2": "#1651aa", + "brandForegroundDisabled1": "#bdbdbd", + "brandForegroundDisabled2": "#bdbdbd", + "brandForegroundLink": "#1651aa", + "brandForegroundLinkHover": "#13458f", + "brandForegroundLinkPressed": "#004578", + "brandForegroundLinkSelected": "#1651aa", + "brandForegroundTint": "#1651aa", + "brandStroke1": "#185abd", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", + "brandStroke2": "#d2e0f4", + "brandStrokeTint": "#d2e0f4", + "brandedBackground": "#185abd", + "brandedDisabledBorder": "#00000000", "brandedFocusedSecondaryContent": "#ffffff", - "brandedHoveredSecondaryContent": "#000000", - "brandedPressedSecondaryContent": "#000000", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", "brandedSecondaryContent": "#ffffff", - "buttonBackground": "#000000", - "buttonBackgroundChecked": "#1aebff", - "buttonBackgroundDisabled": "#000000", - "buttonBackgroundHovered": "#1aebff", - "buttonBackgroundPressed": "#1aebff", - "buttonBorder": "#ffffff", - "buttonBorderDisabled": "#3ff23f", - "buttonBorderFocused": "#ffffff", - "buttonText": "#ffffff", - "buttonTextChecked": "#000000", - "buttonTextDisabled": "#3ff23f", - "buttonTextHovered": "#000000", - "buttonTextPressed": "#000000", - "checkboxBackground": "#000000", - "checkboxBackgroundDisabled": "#000000", - "checkboxBorderColor": "#ffffff", + "buttonBackground": "#ffffff", + "buttonBackgroundChecked": "#ebebeb", + "buttonBackgroundDisabled": "#f0f0f0", + "buttonBackgroundHovered": "#f5f5f5", + "buttonBackgroundPressed": "#e0e0e0", + "buttonBorder": "#d1d1d1", + "buttonBorderDisabled": "#e0e0e0", + "buttonBorderFocused": "#000000", + "buttonText": "#242424", + "buttonTextChecked": "#242424", + "buttonTextDisabled": "#bdbdbd", + "buttonTextHovered": "#242424", + "buttonTextPressed": "#242424", + "checkboxBackground": "#185abd", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", - "compoundBrandBackground1": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandBackground1Hover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandBackground1Pressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandForeground1": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandForeground1Hover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandForeground1Pressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandStroke1": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandStroke1Hover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "compoundBrandStroke1Pressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "dangerBackground1": { - "windowsbrush": [ - "SystemColorWindowColor", - ], - }, - "dangerBackground2": { - "windowsbrush": [ - "SystemColorWindowColor", - ], - }, - "dangerBackground3": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "dangerBorder1": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "dangerBorder2": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "dangerBorderActive": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "dangerForeground1": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "dangerForeground2": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "dangerForeground3": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "dangerForegroundInverted": { - "windowsbrush": [ - "SystemColorWindowTextColor", - ], - }, - "defaultBackground": "#000000", - "defaultBorder": "#ffffff", - "defaultCheckedBackground": "#1aebff", - "defaultCheckedContent": "#000000", - "defaultCheckedHoveredBackground": "#1aebff", - "defaultCheckedHoveredContent": "#000000", - "defaultContent": "#ffffff", - "defaultDisabledBackground": "#000000", - "defaultDisabledBorder": "#3ff23f", - "defaultDisabledContent": "#3ff23f", - "defaultDisabledIcon": "#3ff23f", - "defaultFocusedBackground": "#000000", - "defaultFocusedBorder": "#ffffff", - "defaultFocusedContent": "#ffffff", - "defaultFocusedIcon": "#ffffff", - "defaultHoveredBackground": "#1aebff", - "defaultHoveredBorder": "#1aebff", - "defaultHoveredContent": "#000000", - "defaultHoveredIcon": "#000000", - "defaultHoveredSecondaryContent": "#000000", - "defaultIcon": "#ffffff", - "defaultPressedBackground": "#1aebff", - "defaultPressedBorder": "#1aebff", - "defaultPressedContent": "#000000", - "defaultPressedIcon": "#000000", - "defaultPressedSecondaryContent": "#000000", - "disabledBackground": "#000000", - "disabledBodyText": "#3ff23f", - "disabledText": "#3ff23f", - "errorText": "#ffffff", - "focusBorder": "#ffffff", - "ghostBackground": "#000000", - "ghostBorder": "#000000", - "ghostCheckedBackground": "#1aebff", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#1aebff", - "ghostCheckedHoveredBorder": "#000000", - "ghostCheckedHoveredContent": "#000000", - "ghostContent": "#ffffff", - "ghostDisabledBackground": "#000000", - "ghostDisabledBorder": "#000000", - "ghostDisabledContent": "#3ff23f", - "ghostDisabledIcon": "#3ff23f", - "ghostFocusedBackground": "#000000", - "ghostFocusedBorder": "#ffffff", - "ghostFocusedContent": "#ffffff", - "ghostFocusedIcon": "#ffffff", - "ghostFocusedSecondaryContent": "#ffffff", - "ghostHoveredBackground": "#1aebff", - "ghostHoveredBorder": "#1aebff", - "ghostHoveredContent": "#000000", - "ghostHoveredIcon": "#000000", - "ghostHoveredSecondaryContent": "#000000", - "ghostIcon": "#ffffff", - "ghostPressedBackground": "#1aebff", - "ghostPressedBorder": "#1aebff", - "ghostPressedContent": "#000000", - "ghostPressedIcon": "#000000", - "ghostPressedSecondaryContent": "#000000", - "ghostSecondaryContent": "#ffffff", - "inputBackground": "#000000", - "inputBorder": "#ffffff", - "inputFocusBorderAlt": "#ffffff", - "inputPlaceholderText": "#ffffff", - "inputText": "#ffffff", - "link": "#ffff00", - "linkHovered": "#ffffff", - "linkPressed": "#ffffff", - "listHeaderBackgroundHovered": "#1aebff", - "listHeaderBackgroundPressed": "#1aebff", - "menuBackground": "#000000", - "menuDivider": "#ffffff", - "menuIcon": "#ffffff", - "menuItemBackgroundHovered": "#1aebff", - "menuItemBackgroundPressed": "#1aebff", - "menuItemText": "#ffffff", - "menuItemTextHovered": "#000000", - "neutralBackground1": { - "windowsbrush": [ - "SystemColorWindowColor", - ], - }, - "neutralBackground1Hover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground1Pressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground1Selected": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground2": { - "windowsbrush": [ - "SystemColorWindowColor", - ], - }, - "neutralBackground2Hover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground2Pressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], - }, - "neutralBackground2Selected": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], + "compoundBrandBackground1": "#185abd", + "compoundBrandBackground1Hover": "#1651aa", + "compoundBrandBackground1Pressed": "#13458f", + "compoundBrandForeground1": "#185abd", + "compoundBrandForeground1Hover": "#1651aa", + "compoundBrandForeground1Pressed": "#13458f", + "compoundBrandStroke1": "#185abd", + "compoundBrandStroke1Hover": "#1651aa", + "compoundBrandStroke1Pressed": "#13458f", + "dangerBackground1": "#fdf6f6", + "dangerBackground2": "#f1bbbc", + "dangerBackground3": "#d13438", + "dangerBorder1": "#f1bbbc", + "dangerBorder2": "#d13438", + "dangerBorderActive": "#d13438", + "dangerForeground1": "#bc2f32", + "dangerForeground2": "#751d1f", + "dangerForeground3": "#d13438", + "dangerForegroundInverted": "#dc5e62", + "dangerStroke1": "#f1bbbc", + "defaultBackground": "#ffffff", + "defaultBorder": "#d1d1d1", + "defaultCheckedBackground": "#ebebeb", + "defaultCheckedContent": "#242424", + "defaultCheckedHoveredBackground": "#f5f5f5", + "defaultCheckedHoveredContent": "#242424", + "defaultContent": "#242424", + "defaultDisabledBackground": "#f0f0f0", + "defaultDisabledBorder": "#e0e0e0", + "defaultDisabledContent": "#bdbdbd", + "defaultDisabledIcon": "#bdbdbd", + "defaultFocusedBackground": "#f5f5f5", + "defaultFocusedBorder": "#000000", + "defaultFocusedContent": "#242424", + "defaultFocusedIcon": "#242424", + "defaultHoveredBackground": "#f5f5f5", + "defaultHoveredBorder": "#c7c7c7", + "defaultHoveredContent": "#242424", + "defaultHoveredIcon": "#242424", + "defaultHoveredSecondaryContent": "#424242", + "defaultIcon": "#242424", + "defaultPressedBackground": "#e0e0e0", + "defaultPressedBorder": "#b3b3b3", + "defaultPressedContent": "#242424", + "defaultPressedIcon": "#242424", + "defaultPressedSecondaryContent": "#424242", + "disabledBackground": "#f0f0f0", + "disabledBodyText": "#bdbdbd", + "disabledText": "#bdbdbd", + "errorText": "#bc2f32", + "focusBorder": "#000000", + "ghostBackground": "#00000000", + "ghostBorder": "#00000000", + "ghostCheckedBackground": "#ebebeb", + "ghostCheckedContent": "#242424", + "ghostCheckedHoveredBackground": "#f5f5f5", + "ghostCheckedHoveredBorder": "#00000000", + "ghostCheckedHoveredContent": "#242424", + "ghostContent": "#242424", + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": "#00000000", + "ghostDisabledContent": "#bdbdbd", + "ghostDisabledIcon": "#bdbdbd", + "ghostFocusedBackground": "#f5f5f5", + "ghostFocusedBorder": "#000000", + "ghostFocusedContent": "#242424", + "ghostFocusedIcon": "#242424", + "ghostFocusedSecondaryContent": "#616161", + "ghostHoveredBackground": "#f5f5f5", + "ghostHoveredBorder": "#00000000", + "ghostHoveredContent": "#242424", + "ghostHoveredIcon": "#242424", + "ghostHoveredSecondaryContent": "#424242", + "ghostIcon": "#242424", + "ghostPressedBackground": "#e0e0e0", + "ghostPressedBorder": "#00000000", + "ghostPressedContent": "#242424", + "ghostPressedIcon": "#242424", + "ghostPressedSecondaryContent": "#424242", + "ghostSecondaryContent": "#616161", + "inputBackground": "#ffffff", + "inputBorder": "#d1d1d1", + "inputFocusBorderAlt": "#185abd", + "inputPlaceholderText": "#707070", + "inputText": "#242424", + "link": "#1651aa", + "linkHovered": "#13458f", + "linkPressed": "#004578", + "listHeaderBackgroundHovered": "#f5f5f5", + "listHeaderBackgroundPressed": "#e0e0e0", + "menuBackground": "#ffffff", + "menuDivider": "#e0e0e0", + "menuIcon": "#424242", + "menuItemBackgroundHovered": "#f5f5f5", + "menuItemBackgroundPressed": "#e0e0e0", + "menuItemText": "#242424", + "menuItemTextHovered": "#242424", + "neutralBackground1": "#ffffff", + "neutralBackground1Hover": "#f5f5f5", + "neutralBackground1Pressed": "#e0e0e0", + "neutralBackground1Selected": "#ebebeb", + "neutralBackground2": "#fafafa", + "neutralBackground2Hover": "#f0f0f0", + "neutralBackground2Pressed": "#dbdbdb", + "neutralBackground2Selected": "#e6e6e6", + "neutralBackground3": "#f5f5f5", + "neutralBackground3Hover": "#ebebeb", + "neutralBackground3Pressed": "#d6d6d6", + "neutralBackground3Selected": "#e0e0e0", + "neutralBackground4": "#f0f0f0", + "neutralBackground4Hover": "#fafafa", + "neutralBackground4Pressed": "#f5f5f5", + "neutralBackground4Selected": "#ffffff", + "neutralBackground5": "#ebebeb", + "neutralBackground5Hover": "#f5f5f5", + "neutralBackground5Pressed": "#f0f0f0", + "neutralBackground5Selected": "#fafafa", + "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", + "neutralBackgroundDisabled": "#f0f0f0", + "neutralBackgroundInverted": "#616161", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", + "neutralForeground1": "#242424", + "neutralForeground1Hover": "#242424", + "neutralForeground1Pressed": "#242424", + "neutralForeground1Selected": "#242424", + "neutralForeground2": "#424242", + "neutralForeground2BrandHover": "#185abd", + "neutralForeground2BrandPressed": "#1651aa", + "neutralForeground2BrandSelected": "#185abd", + "neutralForeground2Hover": "#242424", + "neutralForeground2Pressed": "#242424", + "neutralForeground2Selected": "#242424", + "neutralForeground3": "#616161", + "neutralForeground3BrandHover": "#185abd", + "neutralForeground3BrandPressed": "#1651aa", + "neutralForeground3BrandSelected": "#185abd", + "neutralForeground3Hover": "#424242", + "neutralForeground3Pressed": "#424242", + "neutralForeground3Selected": "#424242", + "neutralForeground4": "#707070", + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": "#bdbdbd", + "neutralForegroundDisabled1": "#bdbdbd", + "neutralForegroundDisabled2": "#bdbdbd", + "neutralForegroundInverted": "#ffffff", + "neutralForegroundInvertedLink": "#ffffff", + "neutralForegroundInvertedLinkHover": "#ffffff", + "neutralForegroundInvertedLinkPressed": "#ffffff", + "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": "#ffffff", + "neutralForegroundOnBrandHover": "#ffffff", + "neutralForegroundOnBrandPressed": "#ffffff", + "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", + "neutralStencil1": "#e6e6e6", + "neutralStencil2": "#fafafa", + "neutralStroke1": "#d1d1d1", + "neutralStroke1Hover": "#c7c7c7", + "neutralStroke1Pressed": "#b3b3b3", + "neutralStroke1Selected": "#bdbdbd", + "neutralStroke2": "#e0e0e0", + "neutralStroke3": "#f0f0f0", + "neutralStrokeAccessible": "#616161", + "neutralStrokeAccessibleHover": "#575757", + "neutralStrokeAccessiblePressed": "#4d4d4d", + "neutralStrokeAccessibleSelected": "#185abd", + "neutralStrokeDisabled": "#e0e0e0", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", + "outofofficeBackground1": "#fdf5fc", + "outofofficeBackground2": "#edbbe7", + "outofofficeBackground3": "#c239b3", + "outofofficeBorder1": "#edbbe7", + "outofofficeBorder2": "#c239b3", + "outofofficeBorderActive": "#c239b3", + "outofofficeForeground1": "#af33a1", + "outofofficeForeground2": "#6d2064", + "outofofficeForeground3": "#c239b3", + "personaActivityGlow": "#185abd", + "personaActivityRing": "#ffffff", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", + "primaryButtonBackground": "#185abd", + "primaryButtonBackgroundDisabled": "#f0f0f0", + "primaryButtonBackgroundHovered": "#1651aa", + "primaryButtonBackgroundPressed": "#004578", + "primaryButtonBorder": "#00000000", + "primaryButtonBorderFocused": "#000000", + "primaryButtonText": "#ffffff", + "primaryButtonTextDisabled": "#bdbdbd", + "primaryButtonTextHovered": "#ffffff", + "primaryButtonTextPressed": "#ffffff", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", + "severeBackground1": "#fdf6f3", + "severeBackground2": "#f4bfab", + "severeBackground3": "#da3b01", + "severeBorder1": "#f4bfab", + "severeBorder2": "#da3b01", + "severeBorderActive": "#da3b01", + "severeForeground1": "#c43501", + "severeForeground2": "#7a2101", + "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", + "strokeFocus1": "#ffffff", + "strokeFocus2": "#000000", + "subText": "#424242", + "subtleBackground": "#00000000", + "subtleBackgroundHover": "#f5f5f5", + "subtleBackgroundPressed": "#e0e0e0", + "subtleBackgroundSelected": "#ebebeb", + "successBackground1": "#f1faf1", + "successBackground2": "#9fd89f", + "successBackground3": "#107c10", + "successBorder1": "#9fd89f", + "successBorder2": "#107c10", + "successBorderActive": "#107c10", + "successForeground1": "#0e700e", + "successForeground2": "#094509", + "successForeground3": "#107c10", + "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": "#00000000", + "transparentStrokeDisabled": "#00000000", + "transparentStrokeInteractive": "#00000000", + "variantBorder": "#e0e0e0", + "warningBackground1": "#fffef5", + "warningBackground2": "#fef7b2", + "warningBackground3": "#fde300", + "warningBorder1": "#fef7b2", + "warningBorder2": "#fde300", + "warningBorderActive": "#fde300", + "warningForeground1": "#817400", + "warningForeground2": "#817400", + "warningForeground3": "#fde300", + "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", + }, + "components": {}, + "host": { + "appearance": "light", + }, + "shadows": { + "shadow16": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000024", + "x": 0, + "y": 8, + }, }, - "neutralBackground3": { - "windowsbrush": [ - "SystemColorWindowColor", - ], + "shadow16brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000040", + "x": 0, + "y": 8, + }, }, - "neutralBackground3Hover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], + "shadow2": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000024", + "x": 0, + "y": 1, + }, }, - "neutralBackground3Pressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], + "shadow28": { + "ambient": { + "blur": 8, + "color": "#00000033", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#0000003d", + "x": 0, + "y": 14, + }, }, - "neutralBackground3Selected": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], + "shadow28brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000040", + "x": 0, + "y": 14, + }, }, - "neutralBackground4": { - "windowsbrush": [ - "SystemColorWindowColor", - ], + "shadow2brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000040", + "x": 0, + "y": 1, + }, }, - "neutralBackground4Hover": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], + "shadow4": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000024", + "x": 0, + "y": 2, + }, }, - "neutralBackground4Pressed": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], + "shadow4brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000040", + "x": 0, + "y": 2, + }, }, - "neutralBackground4Selected": { - "windowsbrush": [ - "SystemColorHighlightColor", - ], + "shadow64": { + "ambient": { + "blur": 8, + "color": "#00000033", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#0000003d", + "x": 0, + "y": 32, + }, }, - "neutralBackground5": { + "shadow64brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000040", + "x": 0, + "y": 32, + }, + }, + "shadow8": { + "ambient": { + "blur": 2, + "color": "#0000001f", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000024", + "x": 0, + "y": 4, + }, + }, + "shadow8brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000040", + "x": 0, + "y": 4, + }, + }, + }, + "spacing": { + "l1": "20px", + "l2": "32px", + "m": "16px", + "s1": "8px", + "s2": "4px", + }, + "typography": { + "families": { + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", + "primary": "Segoe UI", + "sansSerif": "Segoe UI", + "secondary": "Segoe UI", + "serif": "Segoe UI", + }, + "sizes": { + "body": 14, + "caption": 10, + "header": 20, + "hero": 28, + "heroLarge": 40, + "secondary": 12, + "subheader": 16, + }, + "variants": { + "body1": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "body1Strong": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "body2": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "body2Strong": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodySemibold": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodyStandard": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "caption1": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "caption1Strong": { + "face": "primary", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "captionStandard": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "display": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "headerSemibold": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "headerStandard": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "heroLargeSemibold": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "heroLargeStandard": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "heroSemibold": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "heroStandard": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "largeTitle": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "secondarySemibold": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "secondaryStandard": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "subheaderSemibold": { + "face": "primary", + "size": 16, + "weight": "600", + }, + "subheaderStandard": { + "face": "primary", + "size": 16, + "weight": "400", + }, + "subtitle1": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "subtitle1Strong": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "subtitle2": { + "face": "primary", + "size": 16, + "weight": "400", + }, + "subtitle2Strong": { + "face": "primary", + "size": 16, + "weight": "600", + }, + "title1": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "title1Strong": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", + }, + }, + "weights": { + "regular": "400", + "semiBold": "600", + }, + }, +} +`; + +exports[`high contrast dark theme 1`] = ` +{ + "colors": { + "accentButtonBackground": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorButtonFaceColor", ], }, - "neutralBackground5Hover": { + "actionLink": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorWindowTextColor", ], }, - "neutralBackground5Pressed": { + "background": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorWindowColor", ], }, - "neutralBackground5Selected": { + "bodyDivider": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorWindowTextColor", ], }, - "neutralBackground6": { + "bodyFrameBackground": { "windowsbrush": [ "SystemColorWindowColor", ], }, - "neutralBackgroundDisabled": { + "bodyFrameDivider": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorWindowTextColor", ], }, - "neutralBackgroundInverted": { + "bodyStandoutBackground": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorWindowColor", ], }, - "neutralForeground1": { + "bodyText": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "neutralForeground1Hover": { + "bodyTextChecked": { "windowsbrush": [ "SystemColorHighlightTextColor", ], }, - "neutralForeground1Pressed": { + "brandBackground": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorButtonFaceColor", ], }, - "neutralForeground1Selected": { + "brandBackground2": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorButtonFaceColor", ], }, - "neutralForeground2": { + "brandBackground2Pressed": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "neutralForeground2BrandHover": { + "brandBackground2Selected": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorHighlightColor", ], }, - "neutralForeground2BrandPressed": { + "brandBackground3": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorButtonFaceColor", ], }, - "neutralForeground2BrandSelected": { + "brandBackgroundDisabled": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowColor", ], }, - "neutralForeground2Hover": { + "brandBackgroundHover": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorHighlightColor", ], }, - "neutralForeground2Pressed": { + "brandBackgroundInverted": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowTextColor", ], }, - "neutralForeground2Selected": { + "brandBackgroundInvertedDisabled": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowColor", ], }, - "neutralForeground3": { + "brandBackgroundPressed": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "neutralForeground3BrandHover": { + "brandBackgroundSelected": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorHighlightColor", ], }, - "neutralForeground3BrandPressed": { + "brandBackgroundStatic": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowColor", ], }, - "neutralForeground3BrandSelected": { + "brandBackgroundTint": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorButtonFaceColor", ], }, - "neutralForeground3Hover": { + "brandForeground1": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowTextColor", ], }, - "neutralForeground3Pressed": { + "brandForeground1Disabled": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorGrayTextColor", ], }, - "neutralForeground3Selected": { + "brandForeground1Pressed": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowTextColor", ], }, - "neutralForeground4": { + "brandForeground1Selected": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "neutralForegroundDisabled": { + "brandForeground2": { "windowsbrush": [ - "SystemColorGrayTextColor", + "SystemColorButtonTextColor", ], }, - "neutralForegroundInverted": { + "brandForegroundDisabled1": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorGrayTextColor", ], }, - "neutralForegroundInvertedLink": { + "brandForegroundDisabled2": { "windowsbrush": [ - "SystemColorHotlightColor", + "SystemColorGrayTextColor", ], }, - "neutralForegroundInvertedLinkHover": { + "brandForegroundLink": { "windowsbrush": [ "SystemColorHotlightColor", ], }, - "neutralForegroundInvertedLinkPressed": { + "brandForegroundLinkHover": { "windowsbrush": [ "SystemColorHotlightColor", ], }, - "neutralForegroundInvertedLinkSelected": { + "brandForegroundLinkPressed": { "windowsbrush": [ "SystemColorHotlightColor", ], }, - "neutralForegroundOnBrand": { + "brandForegroundLinkSelected": { "windowsbrush": [ - "SystemColorButtonTextColor", + "SystemColorHotlightColor", ], }, - "neutralForegroundOnBrandHover": { + "brandForegroundTint": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorButtonTextColor", ], }, - "neutralForegroundOnBrandPressed": { + "brandStroke1": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowTextColor", ], }, - "neutralForegroundOnBrandSelected": { + "brandStroke1Pressed": { "windowsbrush": [ - "SystemColorHighlightTextColor", + "SystemColorWindowTextColor", ], }, - "neutralStencil1": "#141414", - "neutralStencil2": "#858585", - "neutralStroke1": { + "brandStroke1Selected": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "neutralStroke1Hover": { + "brandStroke2": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorWindowColor", ], }, - "neutralStroke1Pressed": { + "brandStrokeTint": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorWindowColor", ], }, - "neutralStroke1Selected": { + "brandedBackground": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorButtonFaceColor", ], }, - "neutralStroke2": { + "brandedDisabledBorder": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorGrayTextColor", ], }, - "neutralStroke3": { + "brandedFocusedSecondaryContent": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightTextColor", ], }, - "neutralStrokeAccessible": { + "brandedHoveredSecondaryContent": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightTextColor", ], }, - "neutralStrokeAccessibleHover": { + "brandedPressedSecondaryContent": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorHighlightTextColor", ], }, - "neutralStrokeAccessiblePressed": { + "brandedSecondaryContent": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorButtonTextColor", ], }, - "neutralStrokeAccessibleSelected": { + "buttonBackground": { "windowsbrush": [ - "SystemColorHighlightColor", + "SystemColorWindowColor", ], }, - "neutralStrokeDisabled": { + "buttonBackgroundChecked": { "windowsbrush": [ - "SystemColorGrayTextColor", + "SystemColorHighlightColor", ], }, - "outofofficeBackground1": { + "buttonBackgroundDisabled": { "windowsbrush": [ "SystemColorWindowColor", ], }, - "outofofficeBackground2": { + "buttonBackgroundHovered": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorHighlightColor", ], }, - "outofofficeBackground3": { + "buttonBackgroundPressed": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "outofofficeBorder1": { + "buttonBorder": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "outofofficeBorder2": { + "buttonBorderDisabled": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorGrayTextColor", ], }, - "outofofficeBorderActive": { + "buttonBorderFocused": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "outofofficeForeground1": { + "buttonText": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "outofofficeForeground2": { + "buttonTextChecked": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightTextColor", ], }, - "outofofficeForeground3": { + "buttonTextDisabled": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorGrayTextColor", ], }, - "personaActivityGlow": "transparent", - "personaActivityRing": "#ffffff", - "primaryButtonBackground": "#000000", - "primaryButtonBackgroundDisabled": "#000000", - "primaryButtonBackgroundHovered": "#1aebff", - "primaryButtonBackgroundPressed": "#1aebff", - "primaryButtonBorder": "#ffffff", - "primaryButtonBorderFocused": "#ffffff", - "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#3ff23f", - "primaryButtonTextHovered": "#000000", - "primaryButtonTextPressed": "#000000", - "severeBackground1": { + "buttonTextHovered": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorHighlightTextColor", ], }, - "severeBackground2": { + "buttonTextPressed": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorHighlightTextColor", ], }, - "severeBackground3": { + "checkboxBackground": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "severeBorder1": { + "checkboxBackgroundDisabled": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorWindowColor", ], }, - "severeBorder2": { + "checkboxBorderColor": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "severeBorderActive": { + "checkmarkColor": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "compoundBrandBackground1": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "severeForeground1": { + "compoundBrandBackground1Hover": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "severeForeground2": { + "compoundBrandBackground1Pressed": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "severeForeground3": { + "compoundBrandForeground1": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "strokeFocus1": { + "compoundBrandForeground1Hover": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorHighlightColor", ], }, - "strokeFocus2": { + "compoundBrandForeground1Pressed": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "subText": "#ffffff", - "subtleBackground": "#00000000", - "subtleBackgroundHover": { + "compoundBrandStroke1": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "subtleBackgroundPressed": { + "compoundBrandStroke1Hover": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "subtleBackgroundSelected": { + "compoundBrandStroke1Pressed": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "successBackground1": { + "dangerBackground1": { "windowsbrush": [ "SystemColorWindowColor", ], }, - "successBackground2": { + "dangerBackground2": { "windowsbrush": [ "SystemColorWindowColor", ], }, - "successBackground3": { + "dangerBackground3": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "successBorder1": { + "dangerBorder1": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "successBorder2": { + "dangerBorder2": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "successBorderActive": { + "dangerBorderActive": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "successForeground1": { + "dangerForeground1": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "successForeground2": { + "dangerForeground2": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "successForeground3": { + "dangerForeground3": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "successForegroundInverted": { + "dangerForegroundInverted": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "transparentBackground": "#00000000", - "transparentBackgroundHover": "#00000000", - "transparentBackgroundPressed": "#00000000", - "transparentBackgroundSelected": "#00000000", - "transparentStroke": { + "dangerStroke1": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "transparentStrokeDisabled": { + "defaultBackground": { "windowsbrush": [ - "SystemColorGrayTextColor", + "SystemColorWindowColor", ], }, - "transparentStrokeInteractive": { + "defaultBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "defaultCheckedBackground": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "variantBorder": "#ffffff", - "warningBackground1": { + "defaultCheckedContent": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorHighlightTextColor", ], }, - "warningBackground2": { + "defaultCheckedHoveredBackground": { "windowsbrush": [ - "SystemColorWindowColor", + "SystemColorHighlightColor", ], }, - "warningBackground3": { + "defaultCheckedHoveredContent": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightTextColor", ], }, - "warningBorder1": { + "defaultContent": { "windowsbrush": [ "SystemColorWindowTextColor", ], }, - "warningBorder2": { + "defaultDisabledBackground": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorWindowColor", ], }, - "warningBorderActive": { + "defaultDisabledBorder": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "defaultDisabledContent": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "defaultDisabledIcon": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "defaultFocusedBackground": { "windowsbrush": [ "SystemColorHighlightColor", ], }, - "warningForeground1": { + "defaultFocusedBorder": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - "warningForeground2": { + "defaultFocusedContent": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightTextColor", ], }, - "warningForeground3": { + "defaultFocusedIcon": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightTextColor", ], }, - "warningForegroundInverted": { + "defaultHoveredBackground": { "windowsbrush": [ - "SystemColorWindowTextColor", + "SystemColorHighlightColor", ], }, - }, - "components": {}, - "host": { - "appearance": "highContrast", - }, - "shadows": { - "shadow16": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000047", - "x": 0, - "y": 8, - }, + "defaultHoveredBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], }, - "shadow16brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 16, - "color": "#00000040", - "x": 0, - "y": 8, - }, + "defaultHoveredContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], }, - "shadow2": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000047", - "x": 0, - "y": 1, - }, + "defaultHoveredIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], }, - "shadow28": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#0000007a", - "x": 0, - "y": 14, - }, + "defaultHoveredSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], }, - "shadow28brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 28, - "color": "#00000040", - "x": 0, - "y": 14, - }, + "defaultIcon": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], }, - "shadow2brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 2, - "color": "#00000040", - "x": 0, - "y": 1, - }, + "defaultPressedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], }, - "shadow4": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000047", - "x": 0, - "y": 2, - }, + "defaultPressedBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], }, - "shadow4brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 4, - "color": "#00000040", - "x": 0, - "y": 2, - }, + "defaultPressedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], }, - "shadow64": { - "ambient": { - "blur": 8, - "color": "#00000066", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#0000007a", - "x": 0, - "y": 32, - }, + "defaultPressedIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], }, - "shadow64brand": { - "ambient": { - "blur": 8, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 64, - "color": "#00000040", - "x": 0, - "y": 32, - }, + "defaultPressedSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], }, - "shadow8": { - "ambient": { - "blur": 2, - "color": "#0000003d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000047", - "x": 0, - "y": 4, - }, + "disabledBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], }, - "shadow8brand": { - "ambient": { - "blur": 2, - "color": "#0000004d", - "x": 0, - "y": 0, - }, - "key": { - "blur": 8, - "color": "#00000040", - "x": 0, - "y": 4, - }, + "disabledBodyText": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], }, - }, - "spacing": { - "l1": "20px", - "l2": "32px", - "m": "16px", - "s1": "8px", - "s2": "4px", - }, - "typography": { - "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", - "primary": "Segoe UI", - "sansSerif": "System", - "secondary": "Segoe UI", - "serif": "System", + "disabledText": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], }, - "sizes": { - "body": 14, - "caption": 10, - "header": 20, - "hero": 28, - "heroLarge": 40, - "secondary": 12, - "subheader": 16, + "errorText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], }, - "variants": { - "body1": { - "face": "primary", - "size": "secondary", - "weight": "regular", - }, - "body1Strong": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", - }, - "body2": { - "face": "primary", - "size": "body", - "weight": "regular", - }, - "body2Strong": { - "face": "primary", - "size": "body", - "weight": "semiBold", - }, - "bodySemibold": { - "face": "primary", - "size": "body", - "weight": "semiBold", - }, - "bodyStandard": { - "face": "primary", - "size": "body", - "weight": "regular", - }, - "caption1": { - "face": "primary", - "size": "caption", - "weight": "regular", - }, - "caption1Strong": { - "face": "primary", - "size": "caption", - "weight": "semiBold", - }, - "captionStandard": { - "face": "primary", - "size": "caption", - "weight": "regular", - }, - "display": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", - }, - "headerSemibold": { - "face": "primary", - "size": "header", - "weight": "semiBold", - }, - "headerStandard": { - "face": "primary", - "size": "header", - "weight": "regular", - }, - "heroLargeSemibold": { - "face": "primary", - "size": "heroLarge", - "weight": "semiBold", - }, - "heroLargeStandard": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", - }, - "heroSemibold": { - "face": "primary", - "size": "hero", - "weight": "semiBold", - }, - "heroStandard": { - "face": "primary", - "size": "hero", - "weight": "regular", - }, - "largeTitle": { - "face": "primary", - "size": "heroLarge", - "weight": "regular", - }, - "secondarySemibold": { - "face": "primary", - "size": "secondary", - "weight": "semiBold", - }, - "secondaryStandard": { + "focusBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostBackground": "#00000000", + "ghostBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostCheckedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostCheckedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostCheckedHoveredBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostCheckedHoveredBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostCheckedHoveredContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostContent": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "ghostDisabledContent": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "ghostDisabledIcon": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "ghostFocusedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostFocusedBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostFocusedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostFocusedIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostFocusedSecondaryContent": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostHoveredBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostHoveredBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostHoveredContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostHoveredIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostHoveredSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostIcon": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostPressedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostPressedBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostPressedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostPressedIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostPressedSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostSecondaryContent": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "inputBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "inputBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "inputFocusBorderAlt": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "inputPlaceholderText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "inputText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "link": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "linkHovered": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "linkPressed": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "listHeaderBackgroundHovered": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "listHeaderBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "menuBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "menuDivider": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "menuIcon": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "menuItemBackgroundHovered": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "menuItemBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "menuItemText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "menuItemTextHovered": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground1Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground1Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground1Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground2Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground2Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground2Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground3": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground3Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground3Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground3Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground4": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground4Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground4Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground4Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground5": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground5Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground5Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground5Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground6": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackgroundCanvas": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackgroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForeground1Hover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground1Pressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground1Selected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForeground2BrandHover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2BrandPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2BrandSelected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2Hover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2Pressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2Selected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForeground3BrandHover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3BrandPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3BrandSelected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3Hover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3Pressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3Selected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground4": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralForegroundDisabled1": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralForegroundDisabled2": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralForegroundInverted": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralForegroundInvertedLink": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundInvertedLinkHover": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundInvertedLinkPressed": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundInvertedLinkSelected": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "neutralForegroundOnBrandHover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForegroundOnBrandPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForegroundOnBrandSelected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForegroundOnColor": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "neutralStencil1": "#141414", + "neutralStencil2": "#858585", + "neutralStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStroke1Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStroke1Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStroke1Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStroke2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStroke3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStrokeAccessible": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStrokeAccessibleHover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStrokeAccessiblePressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStrokeAccessibleSelected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStrokeDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralStrokeFocus1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralStrokeFocus2": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "outofofficeBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "outofofficeBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "outofofficeBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "outofofficeForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "personaActivityGlow": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "personaActivityRing": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "presenceAvailable": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "presenceAway": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "presenceDnd": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "presenceOof": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "primaryButtonBackground": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "primaryButtonBackgroundDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "primaryButtonBackgroundHovered": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "primaryButtonBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "primaryButtonBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "primaryButtonBorderFocused": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "primaryButtonText": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "primaryButtonTextDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "primaryButtonTextHovered": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "primaryButtonTextPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "redBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "redBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "redBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "redForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "severeBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "severeBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "severeForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "strokeFocus1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "strokeFocus2": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "subText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "subtleBackground": "#00000000", + "subtleBackgroundHover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "subtleBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "subtleBackgroundSelected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "successBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "successBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "successBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "successForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successForegroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "transparentBackground": "#00000000", + "transparentBackgroundHover": "#00000000", + "transparentBackgroundPressed": "#00000000", + "transparentBackgroundSelected": "#00000000", + "transparentStroke": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "transparentStrokeDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "transparentStrokeInteractive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "variantBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "warningBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "warningBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "warningForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningForegroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + }, + "components": {}, + "host": { + "appearance": "highContrast", + }, + "shadows": { + "shadow16": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000047", + "x": 0, + "y": 8, + }, + }, + "shadow16brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 16, + "color": "#00000040", + "x": 0, + "y": 8, + }, + }, + "shadow2": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000047", + "x": 0, + "y": 1, + }, + }, + "shadow28": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#0000007a", + "x": 0, + "y": 14, + }, + }, + "shadow28brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 28, + "color": "#00000040", + "x": 0, + "y": 14, + }, + }, + "shadow2brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 2, + "color": "#00000040", + "x": 0, + "y": 1, + }, + }, + "shadow4": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000047", + "x": 0, + "y": 2, + }, + }, + "shadow4brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 4, + "color": "#00000040", + "x": 0, + "y": 2, + }, + }, + "shadow64": { + "ambient": { + "blur": 8, + "color": "#00000066", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#0000007a", + "x": 0, + "y": 32, + }, + }, + "shadow64brand": { + "ambient": { + "blur": 8, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 64, + "color": "#00000040", + "x": 0, + "y": 32, + }, + }, + "shadow8": { + "ambient": { + "blur": 2, + "color": "#0000003d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000047", + "x": 0, + "y": 4, + }, + }, + "shadow8brand": { + "ambient": { + "blur": 2, + "color": "#0000004d", + "x": 0, + "y": 0, + }, + "key": { + "blur": 8, + "color": "#00000040", + "x": 0, + "y": 4, + }, + }, + }, + "spacing": { + "l1": "20px", + "l2": "32px", + "m": "16px", + "s1": "8px", + "s2": "4px", + }, + "typography": { + "families": { + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", + "primary": "Segoe UI", + "sansSerif": "Segoe UI", + "secondary": "Segoe UI", + "serif": "Segoe UI", + }, + "sizes": { + "body": 14, + "caption": 10, + "header": 20, + "hero": 28, + "heroLarge": 40, + "secondary": 12, + "subheader": 16, + }, + "variants": { + "body1": { + "face": "primary", + "size": 12, + "weight": "400", + }, + "body1Strong": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "body2": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "body2Strong": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodySemibold": { + "face": "primary", + "size": 14, + "weight": "600", + }, + "bodyStandard": { + "face": "primary", + "size": 14, + "weight": "400", + }, + "caption1": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "caption1Strong": { + "face": "primary", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "captionStandard": { + "face": "primary", + "size": 10, + "weight": "400", + }, + "display": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "headerSemibold": { + "face": "primary", + "size": 20, + "weight": "600", + }, + "headerStandard": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "heroLargeSemibold": { + "face": "primary", + "size": 40, + "weight": "600", + }, + "heroLargeStandard": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "heroSemibold": { + "face": "primary", + "size": 28, + "weight": "600", + }, + "heroStandard": { + "face": "primary", + "size": 28, + "weight": "400", + }, + "largeTitle": { + "face": "primary", + "size": 40, + "weight": "400", + }, + "secondarySemibold": { + "face": "primary", + "size": 12, + "weight": "600", + }, + "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, - "weights": { - "regular": "400", - "semiBold": "600", + "weights": { + "regular": "400", + "semiBold": "600", + }, + }, +} +`; + +exports[`high contrast light theme 1`] = ` +{ + "colors": { + "accentButtonBackground": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "actionLink": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "background": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "bodyDivider": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "bodyFrameBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "bodyFrameDivider": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "bodyStandoutBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "bodyText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "bodyTextChecked": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "brandBackground": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "brandBackground2": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "brandBackground2Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "brandBackground2Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "brandBackground3": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "brandBackgroundDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "brandBackgroundHover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "brandBackgroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "brandBackgroundInvertedDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "brandBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "brandBackgroundSelected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "brandBackgroundStatic": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "brandBackgroundTint": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "brandForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "brandForeground1Disabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "brandForeground1Pressed": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "brandForeground1Selected": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "brandForeground2": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "brandForegroundDisabled1": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "brandForegroundDisabled2": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "brandForegroundLink": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "brandForegroundLinkHover": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "brandForegroundLinkPressed": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "brandForegroundLinkSelected": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "brandForegroundTint": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "brandStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "brandStroke1Pressed": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "brandStroke1Selected": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "brandStroke2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "brandStrokeTint": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "brandedBackground": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "brandedDisabledBorder": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "brandedFocusedSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "brandedHoveredSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "brandedPressedSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "brandedSecondaryContent": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "buttonBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "buttonBackgroundChecked": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "buttonBackgroundDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "buttonBackgroundHovered": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "buttonBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "buttonBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "buttonBorderDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "buttonBorderFocused": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "buttonText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "buttonTextChecked": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "buttonTextDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "buttonTextHovered": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "buttonTextPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "checkboxBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "checkboxBackgroundDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "checkboxBorderColor": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "checkmarkColor": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "compoundBrandBackground1": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandBackground1Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandBackground1Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandForeground1": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandForeground1Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandForeground1Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandStroke1": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandStroke1Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "compoundBrandStroke1Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "dangerBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "dangerBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "dangerBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "dangerBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "dangerBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "dangerBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "dangerForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "dangerForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "dangerForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "dangerForegroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "dangerStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "defaultBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "defaultBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "defaultCheckedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultCheckedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultCheckedHoveredBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultCheckedHoveredContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultContent": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "defaultDisabledBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "defaultDisabledBorder": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "defaultDisabledContent": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "defaultDisabledIcon": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "defaultFocusedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultFocusedBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultFocusedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultFocusedIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultHoveredBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultHoveredBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultHoveredContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultHoveredIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultHoveredSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultIcon": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "defaultPressedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultPressedBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "defaultPressedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultPressedIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "defaultPressedSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "disabledBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "disabledBodyText": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "disabledText": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "errorText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "focusBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostBackground": "#00000000", + "ghostBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostCheckedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostCheckedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostCheckedHoveredBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostCheckedHoveredBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostCheckedHoveredContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostContent": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostDisabledBackground": "#00000000", + "ghostDisabledBorder": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "ghostDisabledContent": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "ghostDisabledIcon": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "ghostFocusedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostFocusedBorder": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostFocusedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostFocusedIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostFocusedSecondaryContent": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostHoveredBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostHoveredBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostHoveredContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostHoveredIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostHoveredSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostIcon": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostPressedBackground": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "ghostPressedBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "ghostPressedContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostPressedIcon": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostPressedSecondaryContent": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "ghostSecondaryContent": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "inputBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "inputBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "inputFocusBorderAlt": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "inputPlaceholderText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "inputText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "link": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "linkHovered": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "linkPressed": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "listHeaderBackgroundHovered": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "listHeaderBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "menuBackground": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "menuDivider": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "menuIcon": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "menuItemBackgroundHovered": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "menuItemBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "menuItemText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "menuItemTextHovered": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground1Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground1Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground1Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground2Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground2Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground2Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground3": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground3Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground3Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground3Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground4": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground4Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground4Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground4Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground5": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackground5Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground5Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground5Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralBackground6": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackgroundCanvas": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackgroundDarkStatic": "#3d3d3d", + "neutralBackgroundDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralBackgroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForeground1Hover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground1Pressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground1Selected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForeground2BrandHover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2BrandPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2BrandSelected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2Hover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2Pressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground2Selected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForeground3BrandHover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3BrandPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3BrandSelected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3Hover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3Pressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground3Selected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForeground4": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralForegroundDarkStatic": "#000000", + "neutralForegroundDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralForegroundDisabled1": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralForegroundDisabled2": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralForegroundInverted": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralForegroundInvertedLink": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundInvertedLinkHover": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundInvertedLinkPressed": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundInvertedLinkSelected": { + "windowsbrush": [ + "SystemColorHotlightColor", + ], + }, + "neutralForegroundLightStatic": "#ffffff", + "neutralForegroundOnBrand": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "neutralForegroundOnBrandHover": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForegroundOnBrandPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForegroundOnBrandSelected": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "neutralForegroundOnColor": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "neutralStencil1": "#141414", + "neutralStencil2": "#858585", + "neutralStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStroke1Hover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStroke1Pressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStroke1Selected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStroke2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStroke3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStrokeAccessible": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "neutralStrokeAccessibleHover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStrokeAccessiblePressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStrokeAccessibleSelected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "neutralStrokeDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "neutralStrokeFocus1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "neutralStrokeFocus2": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "outofofficeBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "outofofficeBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "outofofficeBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "outofofficeForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "outofofficeForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "personaActivityGlow": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "personaActivityRing": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "presenceAvailable": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "presenceAway": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "presenceDnd": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "presenceOof": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "primaryButtonBackground": { + "windowsbrush": [ + "SystemColorButtonFaceColor", + ], + }, + "primaryButtonBackgroundDisabled": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "primaryButtonBackgroundHovered": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "primaryButtonBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "primaryButtonBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "primaryButtonBorderFocused": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "primaryButtonText": { + "windowsbrush": [ + "SystemColorButtonTextColor", + ], + }, + "primaryButtonTextDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "primaryButtonTextHovered": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "primaryButtonTextPressed": { + "windowsbrush": [ + "SystemColorHighlightTextColor", + ], + }, + "redBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "redBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "redBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "redForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "redForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "severeBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "severeBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "severeForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "severeStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "strokeFocus1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "strokeFocus2": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "subText": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], }, - }, -} -`; - -exports[`defaultFluentTheme 1`] = ` -{ - "colors": { - "accentButtonBackground": undefined, - "actionLink": "#323130", - "background": "#ffffff", - "bodyDivider": "#edebe9", - "bodyFrameBackground": "#ffffff", - "bodyFrameDivider": "#edebe9", - "bodyStandoutBackground": "#faf9f8", - "bodyText": "#323130", - "bodyTextChecked": "#000000", - "brandBackground": "#185abd", - "brandBackground2": "#eff6fc", - "brandBackgroundDisabled": undefined, - "brandBackgroundHover": "#1651aa", - "brandBackgroundPressed": "#004578", - "brandBackgroundSelected": "#13458f", - "brandBackgroundStatic": "#185abd", - "brandForeground1": "#185abd", - "brandForeground1Disabled": undefined, - "brandForeground1Pressed": undefined, - "brandForeground2": "#1651aa", - "brandForegroundLink": "#1651aa", - "brandForegroundLinkHover": "#13458f", - "brandForegroundLinkPressed": "#004578", - "brandForegroundLinkSelected": "#1651aa", - "brandStroke1": "#185abd", - "brandStroke2": "#d2e0f4", - "brandedBackground": undefined, - "brandedDisabledBorder": "#f3f2f1", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", - "buttonBackground": "#f3f2f1", - "buttonBackgroundChecked": "#c8c6c4", - "buttonBackgroundDisabled": "#f3f2f1", - "buttonBackgroundHovered": "#edebe9", - "buttonBackgroundPressed": "#edebe9", - "buttonBorder": "#8a8886", - "buttonBorderDisabled": "#f3f2f1", - "buttonBorderFocused": "#8a8886", - "buttonText": "#323130", - "buttonTextChecked": "#201f1e", - "buttonTextDisabled": "#a19f9d", - "buttonTextHovered": "#201f1e", - "buttonTextPressed": "#201f1e", - "checkboxBackground": undefined, - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", - "checkmarkColor": "#ffffff", - "compoundBrandBackground1": "#185abd", - "compoundBrandBackground1Hover": "#1651aa", - "compoundBrandBackground1Pressed": "#13458f", - "compoundBrandForeground1": "#185abd", - "compoundBrandForeground1Hover": "#1651aa", - "compoundBrandForeground1Pressed": "#13458f", - "compoundBrandStroke1": "#185abd", - "compoundBrandStroke1Hover": "#1651aa", - "compoundBrandStroke1Pressed": "#13458f", - "dangerBackground1": "#fdf6f6", - "dangerBackground2": "#f1bbbc", - "dangerBackground3": "#d13438", - "dangerBorder1": "#f1bbbc", - "dangerBorder2": "#d13438", - "dangerBorderActive": "#d13438", - "dangerForeground1": "#bc2f32", - "dangerForeground2": "#751d1f", - "dangerForeground3": "#d13438", - "dangerForegroundInverted": "#dc5e62", - "defaultBackground": "#f3f2f1", - "defaultBorder": "#8a8886", - "defaultCheckedBackground": "#c8c6c4", - "defaultCheckedContent": "#201f1e", - "defaultCheckedHoveredBackground": "#edebe9", - "defaultCheckedHoveredContent": "#201f1e", - "defaultContent": "#323130", - "defaultDisabledBackground": "#f3f2f1", - "defaultDisabledBorder": "#f3f2f1", - "defaultDisabledContent": "#a19f9d", - "defaultDisabledIcon": "#a19f9d", - "defaultFocusedBackground": "#edebe9", - "defaultFocusedBorder": "#8a8886", - "defaultFocusedContent": "#201f1e", - "defaultFocusedIcon": "#201f1e", - "defaultHoveredBackground": "#edebe9", - "defaultHoveredBorder": "#8a8886", - "defaultHoveredContent": "#201f1e", - "defaultHoveredIcon": "#201f1e", - "defaultHoveredSecondaryContent": "#a19f9d", - "defaultIcon": "#323130", - "defaultPressedBackground": "#edebe9", - "defaultPressedBorder": "#8a8886", - "defaultPressedContent": "#201f1e", - "defaultPressedIcon": "#201f1e", - "defaultPressedSecondaryContent": "#a19f9d", - "disabledBackground": "#f3f2f1", - "disabledBodyText": "#a19f9d", - "disabledText": "#a19f9d", - "errorText": "#a4262c", - "focusBorder": "#605e5c", - "ghostBackground": "#ffffff", - "ghostBorder": "#ffffff", - "ghostCheckedBackground": "#edebe9", - "ghostCheckedContent": "#000000", - "ghostCheckedHoveredBackground": "#f3f2f1", - "ghostCheckedHoveredBorder": "#201f1e", - "ghostCheckedHoveredContent": "#201f1e", - "ghostContent": "#323130", - "ghostDisabledBackground": "#ffffff", - "ghostDisabledBorder": "#ffffff", - "ghostDisabledContent": "#a19f9d", - "ghostDisabledIcon": "#a19f9d", - "ghostFocusedBackground": "#f3f2f1", - "ghostFocusedBorder": "#8a8886", - "ghostFocusedContent": "#201f1e", - "ghostFocusedIcon": "#201f1e", - "ghostFocusedSecondaryContent": "#605e5c", - "ghostHoveredBackground": "#f3f2f1", - "ghostHoveredBorder": "#f3f2f1", - "ghostHoveredContent": "#201f1e", - "ghostHoveredIcon": "#201f1e", - "ghostHoveredSecondaryContent": "#605e5c", - "ghostIcon": "#323130", - "ghostPressedBackground": "#edebe9", - "ghostPressedBorder": "#edebe9", - "ghostPressedContent": "#201f1e", - "ghostPressedIcon": "#201f1e", - "ghostPressedSecondaryContent": "#605e5c", - "ghostSecondaryContent": "#605e5c", - "inputBackground": "#ffffff", - "inputBorder": "#a19f9d", - "inputFocusBorderAlt": undefined, - "inputPlaceholderText": "#605e5c", - "inputText": "#323130", - "link": undefined, - "linkHovered": undefined, - "linkPressed": undefined, - "listHeaderBackgroundHovered": "#f3f2f1", - "listHeaderBackgroundPressed": "#edebe9", - "menuBackground": "#ffffff", - "menuDivider": "#c8c6c4", - "menuIcon": undefined, - "menuItemBackgroundHovered": "#f3f2f1", - "menuItemBackgroundPressed": "#edebe9", - "menuItemText": "#323130", - "menuItemTextHovered": "#201f1e", - "neutralBackground1": "#ffffff", - "neutralBackground1Hover": "#f5f5f5", - "neutralBackground1Pressed": "#e0e0e0", - "neutralBackground1Selected": "#ebebeb", - "neutralBackground2": "#fafafa", - "neutralBackground2Hover": "#f0f0f0", - "neutralBackground2Pressed": "#dbdbdb", - "neutralBackground2Selected": "#e6e6e6", - "neutralBackground3": "#f5f5f5", - "neutralBackground3Hover": "#ebebeb", - "neutralBackground3Pressed": "#d6d6d6", - "neutralBackground3Selected": "#e0e0e0", - "neutralBackground4": "#f0f0f0", - "neutralBackground4Hover": "#fafafa", - "neutralBackground4Pressed": "#f5f5f5", - "neutralBackground4Selected": "#ffffff", - "neutralBackground5": "#ebebeb", - "neutralBackground5Hover": "#f5f5f5", - "neutralBackground5Pressed": "#f0f0f0", - "neutralBackground5Selected": "#fafafa", - "neutralBackground6": "#e6e6e6", - "neutralBackgroundDisabled": "#f0f0f0", - "neutralBackgroundInverted": "#616161", - "neutralForeground1": "#242424", - "neutralForeground1Hover": "#242424", - "neutralForeground1Pressed": "#242424", - "neutralForeground1Selected": "#242424", - "neutralForeground2": "#424242", - "neutralForeground2BrandHover": "#185abd", - "neutralForeground2BrandPressed": "#1651aa", - "neutralForeground2BrandSelected": "#185abd", - "neutralForeground2Hover": "#242424", - "neutralForeground2Pressed": "#242424", - "neutralForeground2Selected": "#242424", - "neutralForeground3": "#616161", - "neutralForeground3BrandHover": "#185abd", - "neutralForeground3BrandPressed": "#1651aa", - "neutralForeground3BrandSelected": "#185abd", - "neutralForeground3Hover": "#424242", - "neutralForeground3Pressed": "#424242", - "neutralForeground3Selected": "#424242", - "neutralForeground4": "#707070", - "neutralForegroundDisabled": "#bdbdbd", - "neutralForegroundInverted": "#ffffff", - "neutralForegroundInvertedLink": "#ffffff", - "neutralForegroundInvertedLinkHover": "#ffffff", - "neutralForegroundInvertedLinkPressed": "#ffffff", - "neutralForegroundInvertedLinkSelected": "#ffffff", - "neutralForegroundOnBrand": "#ffffff", - "neutralForegroundOnBrandHover": "#ffffff", - "neutralForegroundOnBrandPressed": "#ffffff", - "neutralForegroundOnBrandSelected": "#ffffff", - "neutralStencil1": "#e6e6e6", - "neutralStencil2": "#fafafa", - "neutralStroke1": "#d1d1d1", - "neutralStroke1Hover": "#c7c7c7", - "neutralStroke1Pressed": "#b3b3b3", - "neutralStroke1Selected": "#bdbdbd", - "neutralStroke2": "#e0e0e0", - "neutralStroke3": "#f0f0f0", - "neutralStrokeAccessible": "#616161", - "neutralStrokeAccessibleHover": "#575757", - "neutralStrokeAccessiblePressed": "#4d4d4d", - "neutralStrokeAccessibleSelected": "#185abd", - "neutralStrokeDisabled": "#e0e0e0", - "outofofficeBackground1": "#fdf5fc", - "outofofficeBackground2": "#edbbe7", - "outofofficeBackground3": "#c239b3", - "outofofficeBorder1": "#edbbe7", - "outofofficeBorder2": "#c239b3", - "outofofficeBorderActive": "#c239b3", - "outofofficeForeground1": "#af33a1", - "outofofficeForeground2": "#6d2064", - "outofofficeForeground3": "#c239b3", - "personaActivityGlow": undefined, - "personaActivityRing": "#ffffff", - "primaryButtonBackground": undefined, - "primaryButtonBackgroundDisabled": "#f3f2f1", - "primaryButtonBackgroundHovered": undefined, - "primaryButtonBackgroundPressed": undefined, - "primaryButtonBorder": "transparent", - "primaryButtonBorderFocused": "transparent", - "primaryButtonText": "#ffffff", - "primaryButtonTextDisabled": "#d2d0ce", - "primaryButtonTextHovered": "#ffffff", - "primaryButtonTextPressed": "#ffffff", - "severeBackground1": "#fdf6f3", - "severeBackground2": "#f4bfab", - "severeBackground3": "#da3b01", - "severeBorder1": "#f4bfab", - "severeBorder2": "#da3b01", - "severeBorderActive": "#da3b01", - "severeForeground1": "#c43501", - "severeForeground2": "#7a2101", - "severeForeground3": "#da3b01", - "strokeFocus1": "#ffffff", - "strokeFocus2": "#000000", - "subText": "#605e5c", "subtleBackground": "#00000000", - "subtleBackgroundHover": "#f5f5f5", - "subtleBackgroundPressed": "#e0e0e0", - "subtleBackgroundSelected": "#ebebeb", - "successBackground1": "#f1faf1", - "successBackground2": "#9fd89f", - "successBackground3": "#107c10", - "successBorder1": "#9fd89f", - "successBorder2": "#107c10", - "successBorderActive": "#107c10", - "successForeground1": "#0e700e", - "successForeground2": "#094509", - "successForeground3": "#107c10", - "successForegroundInverted": "#359b35", + "subtleBackgroundHover": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "subtleBackgroundPressed": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "subtleBackgroundSelected": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "successBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "successBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "successBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "successForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successForegroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "successStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", "transparentBackgroundSelected": "#00000000", - "transparentStroke": "#00000000", - "transparentStrokeDisabled": "#00000000", - "transparentStrokeInteractive": "#00000000", - "variantBorder": "#edebe9", - "warningBackground1": "#fffef5", - "warningBackground2": "#fef7b2", - "warningBackground3": "#fde300", - "warningBorder1": "#fef7b2", - "warningBorder2": "#fde300", - "warningBorderActive": "#fde300", - "warningForeground1": "#817400", - "warningForeground2": "#817400", - "warningForeground3": "#fde300", - "warningForegroundInverted": "#fef7b2", + "transparentStroke": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "transparentStrokeDisabled": { + "windowsbrush": [ + "SystemColorGrayTextColor", + ], + }, + "transparentStrokeInteractive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "variantBorder": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBackground1": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "warningBackground2": { + "windowsbrush": [ + "SystemColorWindowColor", + ], + }, + "warningBackground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBorder1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBorder2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningBorderActive": { + "windowsbrush": [ + "SystemColorHighlightColor", + ], + }, + "warningForeground1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningForeground2": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningForeground3": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningForegroundInverted": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, + "warningStroke1": { + "windowsbrush": [ + "SystemColorWindowTextColor", + ], + }, }, "components": {}, "host": { - "appearance": "light", + "appearance": "highContrast", }, "shadows": { "shadow16": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 16, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 8, }, @@ -2131,13 +4820,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow2": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 2, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 1, }, @@ -2145,13 +4834,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow28": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 28, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 14, }, @@ -2187,13 +4876,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow4": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 4, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 2, }, @@ -2215,13 +4904,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow64": { "ambient": { "blur": 8, - "color": "#00000033", + "color": "#00000066", "x": 0, "y": 0, }, "key": { "blur": 64, - "color": "#0000003d", + "color": "#0000007a", "x": 0, "y": 32, }, @@ -2243,13 +4932,13 @@ exports[`defaultFluentTheme 1`] = ` "shadow8": { "ambient": { "blur": 2, - "color": "#0000001f", + "color": "#0000003d", "x": 0, "y": 0, }, "key": { "blur": 8, - "color": "#00000024", + "color": "#00000047", "x": 0, "y": 4, }, @@ -2278,13 +4967,13 @@ exports[`defaultFluentTheme 1`] = ` }, "typography": { "families": { - "cursive": "System", - "monospace": "System", - "numeric": "System", + "cursive": "Segoe UI", + "monospace": "Consolas", + "numeric": "Bahnschrift", "primary": "Segoe UI", - "sansSerif": "System", + "sansSerif": "Segoe UI", "secondary": "Segoe UI", - "serif": "System", + "serif": "Segoe UI", }, "sizes": { "body": 14, @@ -2298,138 +4987,153 @@ exports[`defaultFluentTheme 1`] = ` "variants": { "body1": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "body1Strong": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "body2": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "body2Strong": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodySemibold": { "face": "primary", - "size": "body", - "weight": "semiBold", + "size": 14, + "weight": "600", }, "bodyStandard": { "face": "primary", - "size": "body", - "weight": "regular", + "size": 14, + "weight": "400", }, "caption1": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", - "size": "caption", - "weight": "regular", + "size": 10, + "weight": "400", }, "display": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "headerSemibold": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "headerStandard": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "heroLargeSemibold": { "face": "primary", - "size": "heroLarge", - "weight": "semiBold", + "size": 40, + "weight": "600", }, "heroLargeStandard": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "heroSemibold": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", }, "heroStandard": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "largeTitle": { "face": "primary", - "size": "heroLarge", - "weight": "regular", + "size": 40, + "weight": "400", }, "secondarySemibold": { "face": "primary", - "size": "secondary", - "weight": "semiBold", + "size": 12, + "weight": "600", }, "secondaryStandard": { "face": "primary", - "size": "secondary", - "weight": "regular", + "size": 12, + "weight": "400", }, "subheaderSemibold": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "subheaderStandard": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle1": { "face": "primary", - "size": "header", - "weight": "regular", + "size": 20, + "weight": "400", }, "subtitle1Strong": { "face": "primary", - "size": "header", - "weight": "semiBold", + "size": 20, + "weight": "600", }, "subtitle2": { "face": "primary", - "size": "subheader", - "weight": "regular", + "size": 16, + "weight": "400", }, "subtitle2Strong": { "face": "primary", - "size": "subheader", - "weight": "semiBold", + "size": 16, + "weight": "600", }, "title1": { "face": "primary", - "size": "hero", - "weight": "regular", + "size": 28, + "weight": "400", }, "title1Strong": { "face": "primary", - "size": "hero", - "weight": "semiBold", + "size": 28, + "weight": "600", + }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", }, }, "weights": { diff --git a/packages/theming/default-theme/src/__tests__/default-theme.test.ts b/packages/theming/default-theme/src/__tests__/default-theme.test.ts index eebc8328eb9..592f9d69fdb 100644 --- a/packages/theming/default-theme/src/__tests__/default-theme.test.ts +++ b/packages/theming/default-theme/src/__tests__/default-theme.test.ts @@ -1,8 +1,6 @@ -import type { ThemeOptions, AppearanceOptions } from '@fluentui-react-native/design/theming'; +import type { ThemeOptions } from '@fluentui-react-native/design/theming'; -import { createColorAliasTokens, createShadowAliasTokens } from '../createAliasTokens'; -import { createDefaultTheme } from '../createDefaultTheme'; -import { defaultFluentTheme, defaultFluentDarkTheme } from '../defaultTheme'; +import { createDefaultTheme, defaultFluentTheme, defaultFluentDarkTheme } from '../index'; const defaultThemeOptions: ThemeOptions[][] = [ [{ appearance: 'light', defaultAppearance: 'light' }], @@ -12,8 +10,6 @@ const defaultThemeOptions: ThemeOptions[][] = [ [{ appearance: 'dynamic', defaultAppearance: 'light' }], ]; -const appearanceOptions: AppearanceOptions[] = ['light', 'dark', 'highContrast']; - beforeAll(() => { jest.mock('react-native/Libraries/Utilities/Appearance', () => ({ getColorScheme: () => 'dark', @@ -57,15 +53,3 @@ describe('createDefaultTheme test', () => { expect(reference.theme.host.appearance).toBe('dark'); }); }); - -describe('createColorAliasTokens test', () => { - it.concurrent.each(appearanceOptions)('appearanceOptions - %s', async (appearanceOption: AppearanceOptions) => { - expect(createColorAliasTokens(appearanceOption)).toMatchSnapshot(); - }); -}); - -describe('createShadowAliasTokens test', () => { - it.concurrent.each(appearanceOptions)('appearanceOptions - %s', async (appearanceOption: AppearanceOptions) => { - expect(createShadowAliasTokens(appearanceOption)).toMatchSnapshot(); - }); -}); diff --git a/packages/theming/default-theme/src/__tests__/defaultThemes.test.android.ts b/packages/theming/default-theme/src/__tests__/defaultThemes.test.android.ts index 988677a1344..b111ccd8854 100644 --- a/packages/theming/default-theme/src/__tests__/defaultThemes.test.android.ts +++ b/packages/theming/default-theme/src/__tests__/defaultThemes.test.android.ts @@ -1,4 +1,4 @@ -import { defaultFluentTheme, defaultFluentDarkTheme, defaultFluentHighConstrastTheme } from '../defaultTheme'; +import { createDefaultTheme, defaultFluentDarkTheme, defaultFluentTheme } from '../index'; it('defaultFluentTheme', () => { expect(defaultFluentTheme).toMatchSnapshot(); @@ -8,6 +8,11 @@ it('defaultFluentDarkTheme', () => { expect(defaultFluentDarkTheme).toMatchSnapshot(); }); -it('defaultFluentHighConstrastTheme', () => { - expect(defaultFluentHighConstrastTheme).toMatchSnapshot(); +it.each(['light', 'dark'] as const)('high contrast %s theme', (colorScheme) => { + const theme = createDefaultTheme({ appearance: 'highContrast' }).resolveTheme({ + colorScheme, + contrast: 'highContrast', + interfaceLevel: 'base', + }); + expect(theme).toMatchSnapshot(); }); diff --git a/packages/theming/default-theme/src/__tests__/defaultThemes.test.ios.ts b/packages/theming/default-theme/src/__tests__/defaultThemes.test.ios.ts index 988677a1344..b111ccd8854 100644 --- a/packages/theming/default-theme/src/__tests__/defaultThemes.test.ios.ts +++ b/packages/theming/default-theme/src/__tests__/defaultThemes.test.ios.ts @@ -1,4 +1,4 @@ -import { defaultFluentTheme, defaultFluentDarkTheme, defaultFluentHighConstrastTheme } from '../defaultTheme'; +import { createDefaultTheme, defaultFluentDarkTheme, defaultFluentTheme } from '../index'; it('defaultFluentTheme', () => { expect(defaultFluentTheme).toMatchSnapshot(); @@ -8,6 +8,11 @@ it('defaultFluentDarkTheme', () => { expect(defaultFluentDarkTheme).toMatchSnapshot(); }); -it('defaultFluentHighConstrastTheme', () => { - expect(defaultFluentHighConstrastTheme).toMatchSnapshot(); +it.each(['light', 'dark'] as const)('high contrast %s theme', (colorScheme) => { + const theme = createDefaultTheme({ appearance: 'highContrast' }).resolveTheme({ + colorScheme, + contrast: 'highContrast', + interfaceLevel: 'base', + }); + expect(theme).toMatchSnapshot(); }); diff --git a/packages/theming/default-theme/src/__tests__/defaultThemes.test.macos.ts b/packages/theming/default-theme/src/__tests__/defaultThemes.test.macos.ts index 988677a1344..b111ccd8854 100644 --- a/packages/theming/default-theme/src/__tests__/defaultThemes.test.macos.ts +++ b/packages/theming/default-theme/src/__tests__/defaultThemes.test.macos.ts @@ -1,4 +1,4 @@ -import { defaultFluentTheme, defaultFluentDarkTheme, defaultFluentHighConstrastTheme } from '../defaultTheme'; +import { createDefaultTheme, defaultFluentDarkTheme, defaultFluentTheme } from '../index'; it('defaultFluentTheme', () => { expect(defaultFluentTheme).toMatchSnapshot(); @@ -8,6 +8,11 @@ it('defaultFluentDarkTheme', () => { expect(defaultFluentDarkTheme).toMatchSnapshot(); }); -it('defaultFluentHighConstrastTheme', () => { - expect(defaultFluentHighConstrastTheme).toMatchSnapshot(); +it.each(['light', 'dark'] as const)('high contrast %s theme', (colorScheme) => { + const theme = createDefaultTheme({ appearance: 'highContrast' }).resolveTheme({ + colorScheme, + contrast: 'highContrast', + interfaceLevel: 'base', + }); + expect(theme).toMatchSnapshot(); }); diff --git a/packages/theming/default-theme/src/__tests__/defaultThemes.test.win32.ts b/packages/theming/default-theme/src/__tests__/defaultThemes.test.win32.ts index 988677a1344..b111ccd8854 100644 --- a/packages/theming/default-theme/src/__tests__/defaultThemes.test.win32.ts +++ b/packages/theming/default-theme/src/__tests__/defaultThemes.test.win32.ts @@ -1,4 +1,4 @@ -import { defaultFluentTheme, defaultFluentDarkTheme, defaultFluentHighConstrastTheme } from '../defaultTheme'; +import { createDefaultTheme, defaultFluentDarkTheme, defaultFluentTheme } from '../index'; it('defaultFluentTheme', () => { expect(defaultFluentTheme).toMatchSnapshot(); @@ -8,6 +8,11 @@ it('defaultFluentDarkTheme', () => { expect(defaultFluentDarkTheme).toMatchSnapshot(); }); -it('defaultFluentHighConstrastTheme', () => { - expect(defaultFluentHighConstrastTheme).toMatchSnapshot(); +it.each(['light', 'dark'] as const)('high contrast %s theme', (colorScheme) => { + const theme = createDefaultTheme({ appearance: 'highContrast' }).resolveTheme({ + colorScheme, + contrast: 'highContrast', + interfaceLevel: 'base', + }); + expect(theme).toMatchSnapshot(); }); diff --git a/packages/theming/default-theme/src/__tests__/defaultThemes.test.windows.ts b/packages/theming/default-theme/src/__tests__/defaultThemes.test.windows.ts index 988677a1344..b111ccd8854 100644 --- a/packages/theming/default-theme/src/__tests__/defaultThemes.test.windows.ts +++ b/packages/theming/default-theme/src/__tests__/defaultThemes.test.windows.ts @@ -1,4 +1,4 @@ -import { defaultFluentTheme, defaultFluentDarkTheme, defaultFluentHighConstrastTheme } from '../defaultTheme'; +import { createDefaultTheme, defaultFluentDarkTheme, defaultFluentTheme } from '../index'; it('defaultFluentTheme', () => { expect(defaultFluentTheme).toMatchSnapshot(); @@ -8,6 +8,11 @@ it('defaultFluentDarkTheme', () => { expect(defaultFluentDarkTheme).toMatchSnapshot(); }); -it('defaultFluentHighConstrastTheme', () => { - expect(defaultFluentHighConstrastTheme).toMatchSnapshot(); +it.each(['light', 'dark'] as const)('high contrast %s theme', (colorScheme) => { + const theme = createDefaultTheme({ appearance: 'highContrast' }).resolveTheme({ + colorScheme, + contrast: 'highContrast', + interfaceLevel: 'base', + }); + expect(theme).toMatchSnapshot(); }); diff --git a/packages/theming/default-theme/src/createAliasTokens.ts b/packages/theming/default-theme/src/createAliasTokens.ts deleted file mode 100644 index f6e55a87bcb..00000000000 --- a/packages/theming/default-theme/src/createAliasTokens.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { memoize } from '@fluentui-react-native/framework-base'; -import { getAliasTokens, getShadowTokens } from '@fluentui-react-native/design/tokens/legacy'; -import type { AliasColorTokens, AppearanceOptions, ThemeShadowDefinition } from '@fluentui-react-native/design/theming'; -import { mapPipelineToShadow, mapPipelineToTheme } from '@fluentui-react-native/design/theming'; - -function createColorAliasTokensWorker(mode: AppearanceOptions): AliasColorTokens { - const aliasTokens = getAliasTokens(mode); - return mapPipelineToTheme(aliasTokens); -} - -export const createColorAliasTokens = memoize(createColorAliasTokensWorker); - -function createShadowAliasTokensWorker(mode: AppearanceOptions): ThemeShadowDefinition { - const aliasTokens = getShadowTokens(mode); - return mapPipelineToShadow(aliasTokens); -} - -export const createShadowAliasTokens = memoize(createShadowAliasTokensWorker); diff --git a/packages/theming/default-theme/src/createDefaultTheme.ts b/packages/theming/default-theme/src/createDefaultTheme.ts index 0268a457a36..23fc2fc3ebe 100644 --- a/packages/theming/default-theme/src/createDefaultTheme.ts +++ b/packages/theming/default-theme/src/createDefaultTheme.ts @@ -1,37 +1,21 @@ -import { ThemeReference } from '@fluentui-react-native/design/theming'; +import { appearanceOptionsFromLegacy, resolveThemeAppearance, ThemeReference } from '@fluentui-react-native/design/theming'; import type { Theme, ThemeOptions } from '@fluentui-react-native/design/theming'; -import { - appearanceOptionFromResolved, - appearanceOptionsFromLegacy, - getCurrentAppearance, - resolveThemeAppearance, -} from '@fluentui-react-native/design/theming'; -import assertNever from 'assert-never'; - -import { defaultFluentDarkTheme, defaultFluentHighConstrastTheme, defaultFluentTheme } from './defaultTheme'; +import { fluentTheme } from '@fluentui-react-native/design/themes'; +/** + * Create a theme reference for legacy theme options. It resolves the design package's Fluent themes, including the + * high-contrast themes, for the requested appearance. + */ export function createDefaultTheme(options: ThemeOptions = {}): ThemeReference { + const getAppearance = () => appearanceOptionsFromLegacy(options.appearance ?? options.defaultAppearance ?? 'light'); + const getFallbackAppearance = () => resolveThemeAppearance(appearanceOptionsFromLegacy(options.defaultAppearance ?? 'light')).resolved; return new ThemeReference({ base: {} as Theme, - getAppearance: () => appearanceOptionsFromLegacy(options.appearance ?? options.defaultAppearance ?? 'light'), - getFallbackAppearance: () => resolveThemeAppearance(appearanceOptionsFromLegacy(options.defaultAppearance ?? 'light')).resolved, + getAppearance, + getFallbackAppearance, recipes: [ - (_theme, resolvedAppearance) => { - const current = resolvedAppearance - ? appearanceOptionFromResolved(resolvedAppearance) - : getCurrentAppearance(options.appearance, options.defaultAppearance ?? 'light'); - switch (current) { - case 'light': - return defaultFluentTheme; - case 'dark': - case 'darkElevated': - return defaultFluentDarkTheme; - case 'highContrast': - return defaultFluentHighConstrastTheme; - default: - assertNever(current); - } - }, + (_theme, appearance) => + fluentTheme.resolveTheme(appearance ?? resolveThemeAppearance(getAppearance(), undefined, getFallbackAppearance()).resolved), ], }); } diff --git a/packages/theming/default-theme/src/defaultColors.ts b/packages/theming/default-theme/src/defaultColors.ts deleted file mode 100644 index 2969323c6e4..00000000000 --- a/packages/theming/default-theme/src/defaultColors.ts +++ /dev/null @@ -1,325 +0,0 @@ -import type { Palette, FabricWebPalette, ThemeColorDefinition } from '@fluentui-react-native/design/theming'; - -import { createColorAliasTokens } from './createAliasTokens'; - -/** - * Generate a palette from a set of fabric web colors, like those output from the theme designer. - * - * @param palette - fabric web palette definition. This allows initializing our color values in the same - * manner the fabric web does it - */ -export function paletteFromFabricColors(p: FabricWebPalette, isInverted?: boolean): Palette { - return { - background: p.white, - bodyStandoutBackground: p.neutralLighterAlt, - bodyFrameBackground: p.white, - bodyFrameDivider: p.neutralLight, - bodyText: p.neutralPrimary, - bodyTextChecked: p.black, - subText: p.neutralSecondary, - bodyDivider: p.neutralLight, - - disabledBackground: isInverted ? p.neutralQuaternaryAlt : p.neutralLighter, - disabledText: p.neutralTertiary, - disabledBodyText: p.neutralTertiary, - - focusBorder: p.neutralSecondary, - variantBorder: p.neutralLight, - - errorText: !isInverted ? p.redDark : '#ff5f5f', - inputBorder: p.neutralTertiary, - inputBackground: p.white, - inputFocusBorderAlt: p.themePrimary, - inputText: p.neutralPrimary, - inputPlaceholderText: p.neutralSecondary, - - buttonBackground: p.neutralLighter, - buttonBackgroundChecked: p.neutralTertiaryAlt, - buttonBackgroundHovered: p.neutralLight, - buttonBackgroundPressed: p.neutralLight, - buttonBackgroundDisabled: p.neutralLighter, - buttonBorder: p.neutralSecondaryAlt, - buttonText: isInverted ? p.black : p.neutralPrimary, - buttonTextHovered: isInverted ? p.neutralPrimary : p.neutralDark, - buttonTextChecked: p.neutralDark, - buttonTextPressed: p.neutralDark, - buttonTextDisabled: p.neutralTertiary, - buttonBorderDisabled: p.neutralLighter, - buttonBorderFocused: p.neutralSecondaryAlt, - - primaryButtonBackground: p.themePrimary, - primaryButtonBackgroundHovered: p.themeDarkAlt, - primaryButtonBackgroundPressed: p.themeDark, - primaryButtonBackgroundDisabled: p.neutralLighter, - primaryButtonBorder: 'transparent', - primaryButtonBorderFocused: 'transparent', - primaryButtonText: p.white, - primaryButtonTextHovered: p.white, - primaryButtonTextPressed: p.white, - primaryButtonTextDisabled: p.neutralQuaternary, - - accentButtonBackground: p.accent, - - menuBackground: isInverted ? p.neutralLighter : p.white, - menuDivider: isInverted ? p.neutralTertiaryAlt : p.neutralTertiaryAlt, - menuIcon: isInverted ? p.themeDarkAlt : p.themePrimary, - menuItemBackgroundHovered: isInverted ? p.neutralQuaternaryAlt : p.neutralLighter, - menuItemBackgroundPressed: isInverted ? p.neutralQuaternary : p.neutralLight, - menuItemText: p.neutralPrimary, - menuItemTextHovered: p.neutralDark, - - listHeaderBackgroundHovered: p.neutralLighter, - listHeaderBackgroundPressed: p.neutralLight, - - actionLink: p.neutralPrimary, - link: p.themePrimary, - linkHovered: p.themeDarker, - linkPressed: p.themeDark, - - // Control Color Tokens - defaultBackground: p.neutralLighter, - defaultBorder: p.neutralSecondaryAlt, - defaultContent: isInverted ? p.black : p.neutralPrimary, - defaultIcon: isInverted ? p.black : p.neutralPrimary, - - defaultHoveredBackground: p.neutralLight, - defaultHoveredBorder: p.neutralSecondaryAlt, - defaultHoveredContent: isInverted ? p.neutralPrimary : p.neutralDark, - defaultHoveredIcon: isInverted ? p.neutralPrimary : p.neutralDark, - - defaultFocusedBackground: p.neutralLight, - defaultFocusedBorder: p.neutralSecondaryAlt, - defaultFocusedContent: isInverted ? p.neutralPrimary : p.neutralDark, - defaultFocusedIcon: isInverted ? p.neutralPrimary : p.neutralDark, - - defaultPressedBackground: p.neutralLight, - defaultPressedBorder: p.neutralSecondaryAlt, - defaultPressedContent: p.neutralDark, - defaultPressedIcon: p.neutralDark, - - defaultDisabledBackground: p.neutralLighter, - defaultDisabledBorder: p.neutralLighter, - defaultDisabledContent: p.neutralTertiary, - defaultDisabledIcon: p.neutralTertiary, - - ghostBackground: p.white, - ghostBorder: p.white, - ghostContent: p.neutralPrimary, - ghostIcon: p.neutralPrimary, - - ghostHoveredBackground: p.neutralLighter, - ghostHoveredBorder: p.neutralLighter, - ghostHoveredContent: p.neutralDark, - ghostHoveredIcon: p.neutralDark, - - ghostFocusedBackground: p.neutralLighter, - ghostFocusedBorder: p.neutralSecondaryAlt, - ghostFocusedContent: p.neutralDark, - ghostFocusedIcon: p.neutralDark, - - ghostPressedBackground: p.neutralLight, - ghostPressedBorder: p.neutralLight, - ghostPressedContent: p.neutralDark, - ghostPressedIcon: p.neutralDark, - - ghostDisabledBackground: p.white, - ghostDisabledBorder: p.white, - ghostDisabledContent: p.neutralTertiary, - ghostDisabledIcon: p.neutralTertiary, - - brandedBackground: p.themePrimary, - - brandedDisabledBorder: p.neutralLighter, - - defaultCheckedBackground: p.neutralTertiaryAlt, - defaultCheckedContent: p.neutralDark, - defaultCheckedHoveredBackground: p.neutralLight, - defaultCheckedHoveredContent: isInverted ? p.neutralPrimary : p.neutralDark, - - ghostCheckedBackground: p.neutralLight, - ghostCheckedContent: p.black, - ghostCheckedHoveredBackground: p.neutralLighter, - ghostCheckedHoveredContent: p.neutralDark, - ghostCheckedHoveredBorder: p.neutralDark, - - ghostSecondaryContent: p.neutralSecondary, - ghostFocusedSecondaryContent: p.neutralSecondary, - ghostHoveredSecondaryContent: p.neutralSecondary, - ghostPressedSecondaryContent: p.neutralSecondary, - - brandedSecondaryContent: p.neutralLighterAlt, - brandedFocusedSecondaryContent: p.neutralLighterAlt, - brandedHoveredSecondaryContent: p.neutralLighterAlt, - brandedPressedSecondaryContent: p.neutralLighterAlt, - - defaultHoveredSecondaryContent: p.neutralTertiary, - defaultPressedSecondaryContent: p.neutralTertiary, - - checkmarkColor: p.white, - checkboxBackground: p.themePrimary, - checkboxBackgroundDisabled: p.neutralLighter, - checkboxBorderColor: p.neutralSecondaryAlt, - - personaActivityRing: p.white, - personaActivityGlow: p.themePrimary, - }; -} - -export function getStockWebHCPalette(): ThemeColorDefinition { - return { - background: '#000000', - bodyStandoutBackground: '#000000', - bodyFrameBackground: '#000000', - bodyFrameDivider: '#000000', - bodyText: '#ffffff', - bodyTextChecked: '#000000', - subText: '#ffffff', - bodyDivider: '#ffffff', - - disabledBackground: '#000000', - disabledText: '#3ff23f', - disabledBodyText: '#3ff23f', - - focusBorder: '#ffffff', - variantBorder: '#ffffff', - - errorText: '#ffffff', - - inputBorder: '#ffffff', - inputBackground: '#000000', - inputFocusBorderAlt: '#ffffff', - inputText: '#ffffff', - inputPlaceholderText: '#ffffff', - - buttonBackground: '#000000', - buttonBackgroundChecked: '#1aebff', - buttonBackgroundHovered: '#1aebff', - buttonBackgroundPressed: '#1aebff', - buttonBackgroundDisabled: '#000000', - buttonBorder: '#ffffff', - buttonText: '#ffffff', - buttonTextHovered: '#000000', - buttonTextChecked: '#000000', - buttonTextPressed: '#000000', - buttonTextDisabled: '#3ff23f', - buttonBorderDisabled: '#3ff23f', - buttonBorderFocused: '#ffffff', - - primaryButtonBackground: '#000000', - primaryButtonBackgroundHovered: '#1aebff', - primaryButtonBackgroundPressed: '#1aebff', - primaryButtonBackgroundDisabled: '#000000', - primaryButtonBorder: '#ffffff', - primaryButtonBorderFocused: '#ffffff', - primaryButtonText: '#ffffff', - primaryButtonTextHovered: '#000000', - primaryButtonTextPressed: '#000000', - primaryButtonTextDisabled: '#3ff23f', - - accentButtonBackground: '#000000', - - menuBackground: '#000000', - menuDivider: '#ffffff', - menuIcon: '#ffffff', - menuItemBackgroundHovered: '#1aebff', - menuItemBackgroundPressed: '#1aebff', - menuItemText: '#ffffff', - menuItemTextHovered: '#000000', - - listHeaderBackgroundHovered: '#1aebff', - listHeaderBackgroundPressed: '#1aebff', - - actionLink: '#ffff00', - link: '#ffff00', - linkHovered: '#ffffff', - linkPressed: '#ffffff', - - // Control Color Tokens - defaultBackground: '#000000', - defaultBorder: '#ffffff', - defaultContent: '#ffffff', - defaultIcon: '#ffffff', - - defaultHoveredBackground: '#1aebff', - defaultHoveredBorder: '#1aebff', - defaultHoveredContent: '#000000', - defaultHoveredIcon: '#000000', - - defaultFocusedBackground: '#000000', - defaultFocusedBorder: '#ffffff', - defaultFocusedContent: '#ffffff', - defaultFocusedIcon: '#ffffff', - - defaultPressedBackground: '#1aebff', - defaultPressedBorder: '#1aebff', - defaultPressedContent: '#000000', - defaultPressedIcon: '#000000', - - defaultDisabledBackground: '#000000', - defaultDisabledBorder: '#3ff23f', - defaultDisabledContent: '#3ff23f', - defaultDisabledIcon: '#3ff23f', - - ghostBackground: '#000000', - ghostBorder: '#000000', - ghostContent: '#ffffff', - ghostIcon: '#ffffff', - - ghostHoveredBackground: '#1aebff', - ghostHoveredBorder: '#1aebff', - ghostHoveredContent: '#000000', - ghostHoveredIcon: '#000000', - - ghostFocusedBackground: '#000000', - ghostFocusedBorder: '#ffffff', - ghostFocusedContent: '#ffffff', - ghostFocusedIcon: '#ffffff', - - ghostPressedBackground: '#1aebff', - ghostPressedBorder: '#1aebff', - ghostPressedContent: '#000000', - ghostPressedIcon: '#000000', - - ghostDisabledBackground: '#000000', - ghostDisabledBorder: '#000000', - ghostDisabledContent: '#3ff23f', - ghostDisabledIcon: '#3ff23f', - - brandedBackground: '#000000', - - brandedDisabledBorder: '#3ff23f', - - defaultCheckedBackground: '#1aebff', - defaultCheckedContent: '#000000', - defaultCheckedHoveredBackground: '#1aebff', - defaultCheckedHoveredContent: '#000000', - - ghostCheckedBackground: '#1aebff', - ghostCheckedContent: '#000000', - ghostCheckedHoveredBackground: '#1aebff', - ghostCheckedHoveredContent: '#000000', - ghostCheckedHoveredBorder: '#000000', - - ghostSecondaryContent: '#ffffff', - ghostFocusedSecondaryContent: '#ffffff', - ghostHoveredSecondaryContent: '#000000', - ghostPressedSecondaryContent: '#000000', - - brandedSecondaryContent: '#ffffff', - brandedFocusedSecondaryContent: '#ffffff', - brandedHoveredSecondaryContent: '#000000', - brandedPressedSecondaryContent: '#000000', - - defaultHoveredSecondaryContent: '#000000', - defaultPressedSecondaryContent: '#000000', - - checkmarkColor: '#ffffff', - checkboxBackground: '#000000', - checkboxBackgroundDisabled: '#000000', - checkboxBorderColor: '#ffffff', - - personaActivityRing: '#ffffff', - personaActivityGlow: 'transparent', // glow probably doesn't make sense on HC - ...createColorAliasTokens('highContrast'), - }; -} diff --git a/packages/theming/default-theme/src/defaultTheme.ts b/packages/theming/default-theme/src/defaultTheme.ts deleted file mode 100644 index 19a231f300b..00000000000 --- a/packages/theming/default-theme/src/defaultTheme.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { getDefaultLegacyTheme } from '@fluentui-react-native/design/theming/compat/defaults'; - -export const defaultFluentTheme = getDefaultLegacyTheme({ - colorScheme: 'light', - contrast: 'standard', - interfaceLevel: 'base', -}); - -export const defaultFluentDarkTheme = getDefaultLegacyTheme({ - colorScheme: 'dark', - contrast: 'standard', - interfaceLevel: 'base', -}); - -export const defaultFluentHighConstrastTheme = getDefaultLegacyTheme({ - colorScheme: 'dark', - contrast: 'highContrast', - interfaceLevel: 'base', -}); diff --git a/packages/theming/default-theme/src/index.ts b/packages/theming/default-theme/src/index.ts index 4d25a17a249..07130710a71 100644 --- a/packages/theming/default-theme/src/index.ts +++ b/packages/theming/default-theme/src/index.ts @@ -1,3 +1,2 @@ -export { defaultFluentTheme, defaultFluentDarkTheme } from './defaultTheme'; +export { fluentLightTheme as defaultFluentTheme, fluentDarkTheme as defaultFluentDarkTheme } from '@fluentui-react-native/design/themes'; export { createDefaultTheme } from './createDefaultTheme'; -export { createColorAliasTokens as createAliasTokens } from './createAliasTokens'; diff --git a/packages/theming/default-theme/src/stockWebPalette.macos.ts b/packages/theming/default-theme/src/stockWebPalette.macos.ts deleted file mode 100644 index 3502caf0027..00000000000 --- a/packages/theming/default-theme/src/stockWebPalette.macos.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { globalTokens } from '@fluentui-react-native/design/tokens/legacy'; -import type { ThemeColorDefinition } from '@fluentui-react-native/design/theming'; -import { colorBlack, colorBurgundyPrimary, colorRedPrimary, colorWhite } from '@fluentui-react-native/design/tokens/global'; - -import { createColorAliasTokens } from './createAliasTokens'; -import { paletteFromFabricColors } from './defaultColors'; - -export function getStockWebPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors({ - black: colorBlack, - neutralDark: '#201f1e', - neutralPrimary: '#323130', - neutralPrimaryAlt: '#3b3a39', - neutralSecondary: '#605e5c', - neutralSecondaryAlt: '#8a8886', - neutralTertiary: '#a19f9d', - neutralTertiaryAlt: '#c8c6c4', - neutralQuaternary: '#d2d0ce', - neutralQuaternaryAlt: '#e1dfdd', - neutralLight: '#edebe9', - neutralLighter: '#f3f2f1', - neutralLighterAlt: '#faf9f8', - white: colorWhite, - // Shared Colors - red: colorRedPrimary, - redDark: colorBurgundyPrimary, - - themeDarker: globalTokens.color.brand.shade40, - themeDark: globalTokens.color.brand.shade20, - themeDarkAlt: globalTokens.color.brand.shade10, - themePrimary: globalTokens.color.brand.primary, - themeSecondary: '#2b88d8', - themeTertiary: '#71afe5', - themeLight: globalTokens.color.brand.tint40, - themeLighter: globalTokens.color.brand.tint50, - themeLighterAlt: globalTokens.color.brand.tint60, - accent: globalTokens.color.brand.primary, - blackTranslucent40: 'rgba(0,0,0,.4)', - }), - ...createColorAliasTokens('light'), - }; -} - -export function getStockWebDarkPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors( - { - // colors taken from fluentui DarkCustomizations.ts - themeDarker: '#82c7ff', - themeDark: globalTokens.color.brand.tint30, - themeDarkAlt: globalTokens.color.brand.tint20, - themePrimary: globalTokens.color.brand.tint10, - themeSecondary: globalTokens.color.brand.primary, - themeTertiary: '#235a85', - themeLight: globalTokens.color.brand.shade30, - themeLighter: globalTokens.color.brand.shade50, - themeLighterAlt: globalTokens.color.brand.shade60, - black: colorWhite, - neutralDark: '#faf9f8', - neutralPrimary: '#f3f2f1', - neutralPrimaryAlt: '#c8c6c4', - neutralSecondary: '#a19f9d', - neutralSecondaryAlt: '#979693', - neutralTertiary: '#797775', - neutralTertiaryAlt: '#484644', - neutralQuaternary: '#3b3a39', - neutralQuaternaryAlt: '#323130', - neutralLight: '#292827', - neutralLighter: '#252423', - neutralLighterAlt: '#201f1e', - white: '#1b1a19', - red: colorRedPrimary, - accent: globalTokens.color.brand.primary, - redDark: '#f1707b', - blackTranslucent40: 'rgba(0,0,0,.4)', - }, - true, - ), - ...createColorAliasTokens('dark'), - }; -} diff --git a/packages/theming/default-theme/src/stockWebPalette.ts b/packages/theming/default-theme/src/stockWebPalette.ts deleted file mode 100644 index dd7b3b40cb5..00000000000 --- a/packages/theming/default-theme/src/stockWebPalette.ts +++ /dev/null @@ -1,107 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -import { globalTokens } from '@fluentui-react-native/design/tokens/legacy'; -import type { ThemeColorDefinition } from '@fluentui-react-native/design/theming'; -import { colorBlack, colorBurgundyPrimary, colorRedPrimary, colorWhite } from '@fluentui-react-native/design/tokens/global'; - -import { createColorAliasTokens } from './createAliasTokens'; -import { paletteFromFabricColors } from './defaultColors'; - -export function getStockWebPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors({ - black: colorBlack, - neutralDark: '#201f1e', - neutralPrimary: '#323130', - neutralPrimaryAlt: '#3b3a39', - neutralSecondary: '#605e5c', - neutralSecondaryAlt: '#8a8886', - neutralTertiary: '#a19f9d', - neutralTertiaryAlt: '#c8c6c4', - neutralQuaternary: '#d2d0ce', - neutralQuaternaryAlt: '#e1dfdd', - neutralLight: '#edebe9', - neutralLighter: '#f3f2f1', - neutralLighterAlt: '#faf9f8', - white: colorWhite, - // Shared Colors - red: colorRedPrimary, - redDark: colorBurgundyPrimary, - - // @ts-expect-error - accent: globalTokens.color.brand80, - blackTranslucent40: 'rgba(0,0,0,.4)', - - // Colors to be deprecated - // @ts-expect-error - themeDarker: globalTokens.color.brand40, - // @ts-expect-error - themeDark: globalTokens.color.brand60, - // @ts-expect-error - themeDarkAlt: globalTokens.color.brand70, - // @ts-expect-error - themePrimary: globalTokens.color.brand80, - // @ts-expect-error - themeSecondary: globalTokens.color.brand90, - // @ts-expect-error - themeTertiary: globalTokens.color.brand120, - // @ts-expect-error - themeLight: globalTokens.color.brand140, - // @ts-expect-error - themeLighter: globalTokens.color.brand150, - // @ts-expect-error - themeLighterAlt: globalTokens.color.brand160, - }), - ...createColorAliasTokens('light'), - }; -} - -export function getStockWebDarkPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors( - { - // colors taken from fluentui DarkCustomizations.ts - black: colorWhite, - neutralDark: '#faf9f8', - neutralPrimary: '#f3f2f1', - neutralPrimaryAlt: '#c8c6c4', - neutralSecondary: '#a19f9d', - neutralSecondaryAlt: '#979693', - neutralTertiary: '#797775', - neutralTertiaryAlt: '#484644', - neutralQuaternary: '#3b3a39', - neutralQuaternaryAlt: '#323130', - neutralLight: '#292827', - neutralLighter: '#252423', - neutralLighterAlt: '#201f1e', - white: '#1b1a19', - red: colorRedPrimary, - // @ts-expect-error - accent: globalTokens.color.brand40, - redDark: '#f1707b', - blackTranslucent40: 'rgba(0,0,0,.4)', - - // Colors to be deprecated - // @ts-expect-error - themeDarker: globalTokens.color.brand110, - // @ts-expect-error - themeDark: globalTokens.color.brand100, - // @ts-expect-error - themeDarkAlt: globalTokens.color.brand100, - // @ts-expect-error - themePrimary: globalTokens.color.brand90, - // @ts-expect-error - themeSecondary: globalTokens.color.brand90, - // @ts-expect-error - themeTertiary: globalTokens.color.brand60, - // @ts-expect-error - themeLight: globalTokens.color.brand50, - // @ts-expect-error - themeLighter: globalTokens.color.brand40, - // @ts-expect-error - themeLighterAlt: globalTokens.color.brand30, - }, - true, - ), - ...createColorAliasTokens('dark'), - }; -} diff --git a/packages/theming/default-theme/src/stockWebPalette.win32.ts b/packages/theming/default-theme/src/stockWebPalette.win32.ts deleted file mode 100644 index 3502caf0027..00000000000 --- a/packages/theming/default-theme/src/stockWebPalette.win32.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { globalTokens } from '@fluentui-react-native/design/tokens/legacy'; -import type { ThemeColorDefinition } from '@fluentui-react-native/design/theming'; -import { colorBlack, colorBurgundyPrimary, colorRedPrimary, colorWhite } from '@fluentui-react-native/design/tokens/global'; - -import { createColorAliasTokens } from './createAliasTokens'; -import { paletteFromFabricColors } from './defaultColors'; - -export function getStockWebPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors({ - black: colorBlack, - neutralDark: '#201f1e', - neutralPrimary: '#323130', - neutralPrimaryAlt: '#3b3a39', - neutralSecondary: '#605e5c', - neutralSecondaryAlt: '#8a8886', - neutralTertiary: '#a19f9d', - neutralTertiaryAlt: '#c8c6c4', - neutralQuaternary: '#d2d0ce', - neutralQuaternaryAlt: '#e1dfdd', - neutralLight: '#edebe9', - neutralLighter: '#f3f2f1', - neutralLighterAlt: '#faf9f8', - white: colorWhite, - // Shared Colors - red: colorRedPrimary, - redDark: colorBurgundyPrimary, - - themeDarker: globalTokens.color.brand.shade40, - themeDark: globalTokens.color.brand.shade20, - themeDarkAlt: globalTokens.color.brand.shade10, - themePrimary: globalTokens.color.brand.primary, - themeSecondary: '#2b88d8', - themeTertiary: '#71afe5', - themeLight: globalTokens.color.brand.tint40, - themeLighter: globalTokens.color.brand.tint50, - themeLighterAlt: globalTokens.color.brand.tint60, - accent: globalTokens.color.brand.primary, - blackTranslucent40: 'rgba(0,0,0,.4)', - }), - ...createColorAliasTokens('light'), - }; -} - -export function getStockWebDarkPalette(): ThemeColorDefinition { - return { - ...paletteFromFabricColors( - { - // colors taken from fluentui DarkCustomizations.ts - themeDarker: '#82c7ff', - themeDark: globalTokens.color.brand.tint30, - themeDarkAlt: globalTokens.color.brand.tint20, - themePrimary: globalTokens.color.brand.tint10, - themeSecondary: globalTokens.color.brand.primary, - themeTertiary: '#235a85', - themeLight: globalTokens.color.brand.shade30, - themeLighter: globalTokens.color.brand.shade50, - themeLighterAlt: globalTokens.color.brand.shade60, - black: colorWhite, - neutralDark: '#faf9f8', - neutralPrimary: '#f3f2f1', - neutralPrimaryAlt: '#c8c6c4', - neutralSecondary: '#a19f9d', - neutralSecondaryAlt: '#979693', - neutralTertiary: '#797775', - neutralTertiaryAlt: '#484644', - neutralQuaternary: '#3b3a39', - neutralQuaternaryAlt: '#323130', - neutralLight: '#292827', - neutralLighter: '#252423', - neutralLighterAlt: '#201f1e', - white: '#1b1a19', - red: colorRedPrimary, - accent: globalTokens.color.brand.primary, - redDark: '#f1707b', - blackTranslucent40: 'rgba(0,0,0,.4)', - }, - true, - ), - ...createColorAliasTokens('dark'), - }; -} diff --git a/packages/theming/default-theme/tsconfig.json b/packages/theming/default-theme/tsconfig.json index 58f7e57aae9..9698ec893e0 100644 --- a/packages/theming/default-theme/tsconfig.json +++ b/packages/theming/default-theme/tsconfig.json @@ -11,9 +11,6 @@ { "path": "../../agentic/design/tsconfig.json" }, - { - "path": "../../framework-base/tsconfig.json" - }, { "path": "../../../scripts/tsconfig.json" } diff --git a/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap b/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap index a0c49956444..4eefe9b5dcc 100644 --- a/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap +++ b/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap @@ -2452,24 +2452,37 @@ exports[`createOfficeTheme test 1`] = ` "bodyTextChecked": "#262626", "brandBackground": "#D83B01", "brandBackground2": "#d2e0f4", + "brandBackground2Pressed": "#0e336a", + "brandBackground2Selected": "#13458f", + "brandBackground3": "#d2e0f4", "brandBackgroundHover": "#F29F71", + "brandBackgroundInverted": "#616161", + "brandBackgroundInvertedDisabled": "#f0f0f0", "brandBackgroundPressed": "#A22C01", "brandBackgroundSelected": "#13458f", "brandBackgroundStatic": "#185abd", + "brandBackgroundTint": "#d2e0f4", "brandForeground1": "#185abd", + "brandForeground1Selected": "#185abd", "brandForeground2": "#1651aa", + "brandForegroundDisabled1": "#bdbdbd", + "brandForegroundDisabled2": "#bdbdbd", "brandForegroundLink": "#185abd", "brandForegroundLinkHover": "#1651aa", "brandForegroundLinkPressed": "#0e336a", "brandForegroundLinkSelected": "#13458f", + "brandForegroundTint": "#1651aa", "brandStroke1": "#D83B01", + "brandStroke1Pressed": "#185abd", + "brandStroke1Selected": "#185abd", "brandStroke2": "#d2e0f4", + "brandStrokeTint": "#6794d7", "brandedBackground": "#D83B01", "brandedDisabledBorder": "#D2D2D2", - "brandedFocusedSecondaryContent": "#faf9f8", - "brandedHoveredSecondaryContent": "#faf9f8", - "brandedPressedSecondaryContent": "#faf9f8", - "brandedSecondaryContent": "#faf9f8", + "brandedFocusedSecondaryContent": "#ffffff", + "brandedHoveredSecondaryContent": "#ffffff", + "brandedPressedSecondaryContent": "#ffffff", + "brandedSecondaryContent": "#ffffff", "buttonBackground": "#E6E6E6", "buttonBackgroundChecked": "#E6E6E6", "buttonBackgroundDisabled": "#E6E6E6", @@ -2484,8 +2497,8 @@ exports[`createOfficeTheme test 1`] = ` "buttonTextHovered": "#262626", "buttonTextPressed": "#262626", "checkboxBackground": "#185abd", - "checkboxBackgroundDisabled": "#f3f2f1", - "checkboxBorderColor": "#8a8886", + "checkboxBackgroundDisabled": "#f0f0f0", + "checkboxBorderColor": "#616161", "checkmarkColor": "#ffffff", "compoundBrandBackground1": "#D83B01", "compoundBrandBackground1Hover": "#EA6115", @@ -2506,6 +2519,7 @@ exports[`createOfficeTheme test 1`] = ` "dangerForeground2": "#751d1f", "dangerForeground3": "#d13438", "dangerForegroundInverted": "#dc5e62", + "dangerStroke1": "#f1bbbc", "defaultBackground": "#E6E6E6", "defaultBorder": "#969696", "defaultCheckedBackground": "#E6E6E6", @@ -2525,13 +2539,13 @@ exports[`createOfficeTheme test 1`] = ` "defaultHoveredBorder": "#FBDFD0", "defaultHoveredContent": "#262626", "defaultHoveredIcon": "#262626", - "defaultHoveredSecondaryContent": "#a19f9d", + "defaultHoveredSecondaryContent": "#424242", "defaultIcon": "#262626", "defaultPressedBackground": "#FBDFD0", "defaultPressedBorder": "#EA6115", "defaultPressedContent": "#262626", "defaultPressedIcon": "#262626", - "defaultPressedSecondaryContent": "#a19f9d", + "defaultPressedSecondaryContent": "#424242", "disabledBackground": "#F3F3F3", "disabledBodyText": "#B1B1B1", "disabledText": "#B1B1B1", @@ -2604,8 +2618,12 @@ exports[`createOfficeTheme test 1`] = ` "neutralBackground5Pressed": "#f0f0f0", "neutralBackground5Selected": "#fafafa", "neutralBackground6": "#e6e6e6", + "neutralBackgroundCanvas": "#ffffff", + "neutralBackgroundDarkStatic": "#242424", "neutralBackgroundDisabled": "#E6E6E6", "neutralBackgroundInverted": "#737373", + "neutralBackgroundLightStatic": "#ffffff", + "neutralBackgroundLightStaticDisabled": "#f0f0f0", "neutralForeground1": "#262626", "neutralForeground1Hover": "#262626", "neutralForeground1Pressed": "#262626", @@ -2625,16 +2643,21 @@ exports[`createOfficeTheme test 1`] = ` "neutralForeground3Pressed": "#424242", "neutralForeground3Selected": "#424242", "neutralForeground4": "#666666", + "neutralForegroundDarkStatic": "#000000", "neutralForegroundDisabled": "#B1B1B1", + "neutralForegroundDisabled1": "#bdbdbd", + "neutralForegroundDisabled2": "#bdbdbd", "neutralForegroundInverted": "#ffffff", "neutralForegroundInvertedLink": "#FFFFFF", "neutralForegroundInvertedLinkHover": "#D2D2D2", "neutralForegroundInvertedLinkPressed": "#B1B1B1", "neutralForegroundInvertedLinkSelected": "#ffffff", + "neutralForegroundLightStatic": "#ffffff", "neutralForegroundOnBrand": "#FFFFFF", "neutralForegroundOnBrandHover": "#FFFFFF", "neutralForegroundOnBrandPressed": "#FFFFFF", "neutralForegroundOnBrandSelected": "#ffffff", + "neutralForegroundOnColor": "#ffffff", "neutralStencil1": "#262626", "neutralStencil2": "#fafafa", "neutralStroke1": "#969696", @@ -2648,6 +2671,8 @@ exports[`createOfficeTheme test 1`] = ` "neutralStrokeAccessiblePressed": "#737373", "neutralStrokeAccessibleSelected": "#185abd", "neutralStrokeDisabled": "#D2D2D2", + "neutralStrokeFocus1": "#ffffff", + "neutralStrokeFocus2": "#000000", "outofofficeBackground1": "#fdf5fc", "outofofficeBackground2": "#edbbe7", "outofofficeBackground3": "#c239b3", @@ -2659,6 +2684,10 @@ exports[`createOfficeTheme test 1`] = ` "outofofficeForeground3": "#c239b3", "personaActivityGlow": "#185abd", "personaActivityRing": "#ffffff", + "presenceAvailable": "#0e700e", + "presenceAway": "#817400", + "presenceDnd": "#bc2f32", + "presenceOof": "#af33a1", "primaryButtonBackground": "#D83B01", "primaryButtonBackgroundDisabled": "#E6E6E6", "primaryButtonBackgroundHovered": "#F29F71", @@ -2669,6 +2698,15 @@ exports[`createOfficeTheme test 1`] = ` "primaryButtonTextDisabled": "#B1B1B1", "primaryButtonTextHovered": "#FFFFFF", "primaryButtonTextPressed": "#FFFFFF", + "redBackground1": "#fdf6f6", + "redBackground2": "#f1bbbc", + "redBackground3": "#d13438", + "redBorder1": "#f1bbbc", + "redBorder2": "#d13438", + "redBorderActive": "#d13438", + "redForeground1": "#bc2f32", + "redForeground2": "#751d1f", + "redForeground3": "#d13438", "severeBackground1": "#fdf6f3", "severeBackground2": "#f4bfab", "severeBackground3": "#da3b01", @@ -2678,6 +2716,7 @@ exports[`createOfficeTheme test 1`] = ` "severeForeground1": "#c43501", "severeForeground2": "#7a2101", "severeForeground3": "#da3b01", + "severeStroke1": "#f4bfab", "strokeFocus1": "#ffffff", "strokeFocus2": "#969696", "subText": "#666666", @@ -2695,6 +2734,7 @@ exports[`createOfficeTheme test 1`] = ` "successForeground2": "#094509", "successForeground3": "#107c10", "successForegroundInverted": "#359b35", + "successStroke1": "#9fd89f", "transparentBackground": "#00000000", "transparentBackgroundHover": "#00000000", "transparentBackgroundPressed": "#00000000", @@ -2713,6 +2753,7 @@ exports[`createOfficeTheme test 1`] = ` "warningForeground2": "#817400", "warningForeground3": "#fde300", "warningForegroundInverted": "#fef7b2", + "warningStroke1": "#fef7b2", }, "host": { "appearance": "light", @@ -3108,8 +3149,13 @@ exports[`createOfficeTheme test 1`] = ` }, "caption1Strong": { "face": "primary", - "size": "caption", - "weight": "semiBold", + "size": 10, + "weight": "600", + }, + "caption2": { + "face": "primary", + "size": 10, + "weight": "400", }, "captionStandard": { "face": "primary", @@ -3206,6 +3252,16 @@ exports[`createOfficeTheme test 1`] = ` "size": 28, "weight": "600", }, + "title2": { + "face": "primary", + "size": 20, + "weight": "400", + }, + "title3": { + "face": "primary", + "size": 16, + "weight": "400", + }, }, "weights": { "regular": "400", diff --git a/packages/theming/win32-theme/src/createBrandedThemeWithAlias.ts b/packages/theming/win32-theme/src/createBrandedThemeWithAlias.ts index fa97b553377..2eb992b7072 100644 --- a/packages/theming/win32-theme/src/createBrandedThemeWithAlias.ts +++ b/packages/theming/win32-theme/src/createBrandedThemeWithAlias.ts @@ -1,6 +1,6 @@ import type { ColorValue } from 'react-native'; -import { globalTokens } from '@fluentui-react-native/design/tokens/legacy'; +import { globalTokens } from '@fluentui-react-native/design/deprecated'; import type { Theme, PartialTheme, AliasColorTokens } from '@fluentui-react-native/design/theming'; export function createBrandedThemeWithAlias(themeName: string, theme: Theme): PartialTheme { diff --git a/packages/theming/win32-theme/src/createFontAliasTokens.ts b/packages/theming/win32-theme/src/createFontAliasTokens.ts index 0bb272bf6e6..c172f4de922 100644 --- a/packages/theming/win32-theme/src/createFontAliasTokens.ts +++ b/packages/theming/win32-theme/src/createFontAliasTokens.ts @@ -1,6 +1,6 @@ import { memoize } from '@fluentui-react-native/framework-base'; +import { mapFontPipelineToTheme } from '@fluentui-react-native/design/deprecated'; import type { Variants } from '@fluentui-react-native/design/theming'; -import { mapFontPipelineToTheme } from '@fluentui-react-native/design/theming'; import { getOfficeAliasTokens } from './getOfficeTokens'; diff --git a/packages/theming/win32-theme/src/createOfficeAliasTokens.ts b/packages/theming/win32-theme/src/createOfficeAliasTokens.ts index 0b4f447d5d6..90540f488af 100644 --- a/packages/theming/win32-theme/src/createOfficeAliasTokens.ts +++ b/packages/theming/win32-theme/src/createOfficeAliasTokens.ts @@ -1,6 +1,6 @@ import { memoize } from '@fluentui-react-native/framework-base'; +import { mapPipelineToShadow, mapPipelineToTheme } from '@fluentui-react-native/design/deprecated'; import type { AliasColorTokens, ThemeShadowDefinition } from '@fluentui-react-native/design/theming'; -import { mapPipelineToShadow, mapPipelineToTheme } from '@fluentui-react-native/design/theming'; import { getOfficeAliasTokens, getOfficeShadowTokens } from './getOfficeTokens'; diff --git a/packages/theming/win32-theme/src/getOfficeTokens.ts b/packages/theming/win32-theme/src/getOfficeTokens.ts index 081faf497ed..87b386d9bdc 100644 --- a/packages/theming/win32-theme/src/getOfficeTokens.ts +++ b/packages/theming/win32-theme/src/getOfficeTokens.ts @@ -5,7 +5,7 @@ import colorfulShadowTokens from '@fluentui-react-native/design-tokens-win32/col import darkGrayAliasTokens from '@fluentui-react-native/design-tokens-win32/darkgray/tokens-aliases.json'; import darkGrayShadowTokens from '@fluentui-react-native/design-tokens-win32/darkgray/tokens-shadow.json'; import hcShadowTokens from '@fluentui-react-native/design-tokens-win32/hc/tokens-shadow.json'; -import { hcAliasTokens } from '@fluentui-react-native/design/tokens/legacy'; +import { hcAliasTokens } from '@fluentui-react-native/design/deprecated'; export function getOfficeAliasTokens(officeTheme: string) { if (officeTheme === 'White' || officeTheme === 'Colorful') { diff --git a/scripts/package.json b/scripts/package.json index 95735510cc1..f4a2cb9479b 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -29,7 +29,7 @@ "build": "tsc -b", "format": "node ./src/cli.ts format", "lint": "node ./src/cli.ts lint", - "test": "node --test src/tasks/agentInstructions.test.ts src/tasks/clean.test.mjs src/utils/jestSelection.test.ts src/utils/runScript.test.ts src/utils/securityPatches.test.ts" + "test": "node --test src/tasks/agentInstructions.test.ts src/tasks/clean.test.mjs src/utils/jestSelection.test.ts src/utils/runScript.test.ts src/utils/securityPatches.test.ts src/codegen/file.test.ts src/codegen/valuePool.test.ts" }, "dependencies": { "@babel/core": "catalog:", diff --git a/scripts/src/codegen/content.ts b/scripts/src/codegen/content.ts new file mode 100644 index 00000000000..46fdbcfb08b --- /dev/null +++ b/scripts/src/codegen/content.ts @@ -0,0 +1,90 @@ +import type { Chunk, Output } from './file.ts'; +import { serialize } from './file.ts'; + +type RampEntry = Chunk & { + raw: Output; + count: number; + name?: string; +}; + +/** + * A ramp is a collection of categorized values that track their usage and combines them into named entries when they meet a + * usage threshold + */ +export class Ramp implements Chunk { + private _exported: boolean; + private _useThreshold: number; + private _ramps: Record<string, Record<string, RampEntry>>; + private _resolved?: Record<string, RampEntry[] | undefined>; + + constructor(exported: boolean = false, useThreshold: number = 2) { + this._exported = exported; + this._useThreshold = useThreshold; + this._ramps = {}; + } + + /** + * Add a value to the ramp + * @param rampCategory The category of the ramp (e.g., 'color'). + * @param rawValue The raw value to add to the ramp. + * @returns The created or updated ramp entry. + */ + add(rampCategory: string, rawValue: Output): Chunk { + const ramp = (this._ramps[rampCategory] ??= {}); + const valueKey = serialize(rawValue); + const entry = (ramp[valueKey] ??= createRampEntry(rawValue)); + entry.count++; + return entry; + } + + resolveEntries() { + if (this._resolved) return; + this._resolved = {}; + for (const rampKey in this._ramps) { + let index = 1; + for (const entry of Object.values(this._ramps[rampKey])) { + if (entry.count >= this._useThreshold) { + entry.name = createEntryName(entry, rampKey, index++); + } + } + this._resolved[rampKey] = Object.values(this._ramps[rampKey]) + .filter((entry) => entry.name) + .sort((a, b) => a.name!.localeCompare(b.name!)); + } + } + + output(): string { + const prefix = this._exported ? 'export const ' : 'const '; + let output = ''; + for (const rampKey in this._ramps) { + const entries = Object.values(this._ramps[rampKey]).filter((entry) => entry.name); + if (rampKey === 'color') { + entries.sort((a, b) => a.name!.localeCompare(b.name!)); + } + if (entries.length > 0) { + output += entries.map((entry) => `${prefix}${entry.name} = ${serialize(entry.raw)};`).join('\n') + '\n\n'; + } + } + return output; + } +} + +function createRampEntry(raw: Output): RampEntry { + const entry = { raw, count: 0, name: undefined }; + return Object.assign(entry, { output: () => entry.name ?? serialize(entry.raw) }); +} + +// hex color strings will come in quoted with either ' or " +const HEX_COLOR = /^['"]#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})['"]$/; + +function createEntryName(entry: RampEntry, rampCategory: string, lastIndex: number): string { + if (rampCategory === 'color') { + // if the color entry has a hex value, use the full hex value as the name (without the #) + const rawText = serialize(entry.raw); + if (HEX_COLOR.test(rawText)) { + return 'rgb' + rawText.slice(2, -1); + } + } + // otherwise use the prefix with a number + return `${rampCategory}${lastIndex}`; +} diff --git a/scripts/src/codegen/file.test.ts b/scripts/src/codegen/file.test.ts new file mode 100644 index 00000000000..30d7cc3ebd3 --- /dev/null +++ b/scripts/src/codegen/file.test.ts @@ -0,0 +1,41 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { describe, it } from 'node:test'; + +import { GeneratedFile, makeComment } from './file.ts'; + +describe('GeneratedFile', () => { + it('renders, reports whether the file is current, and writes only changes', () => { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'generated-file-')); + try { + const target = path.join(directory, 'nested', 'tokens.generated.ts'); + const create = (value: string) => { + const file = new GeneratedFile(target); + file.header = makeComment('Generated.', 'line'); + file.add('\n', `export const value = '${value}';`); + return file; + }; + + const first = create('a'); + assert.equal(first.render(), "// Generated.\n\nexport const value = 'a';\n"); + assert.equal(first.isCurrent(), false); + assert.equal(first.commit(), true); + assert.equal(fs.readFileSync(target, 'utf8'), first.render()); + + const modified = fs.statSync(target).mtimeMs; + const same = create('a'); + assert.equal(same.isCurrent(), true); + assert.equal(same.commit(), false); + assert.equal(fs.statSync(target).mtimeMs, modified); + + const changed = create('b'); + assert.equal(changed.isCurrent(), false); + assert.equal(changed.commit(), true); + assert.equal(fs.readFileSync(target, 'utf8'), "// Generated.\n\nexport const value = 'b';\n"); + } finally { + fs.rmSync(directory, { recursive: true, force: true }); + } + }); +}); diff --git a/scripts/src/codegen/file.ts b/scripts/src/codegen/file.ts new file mode 100644 index 00000000000..76991422adf --- /dev/null +++ b/scripts/src/codegen/file.ts @@ -0,0 +1,100 @@ +import { FSEntry } from '@rnx-kit/tools-filesystem'; + +export type Chunk = { + /** + * Returns the output of the chunk as a string. + */ + output(): string; +}; + +export type OutputFragment = string | Chunk; +export type Output = OutputFragment | Output[]; + +export type Comment = Chunk & { + text: string | string[]; + type?: 'block' | 'line'; +}; + +export function makeComment(text: string | string[], type: 'block' | 'line' = 'block'): Comment { + const payload = { text, type }; + return { ...payload, output: () => writeComment(payload.text, payload.type) }; +} + +/** + * A generated file is just a collection of chunks serialized to a file. It has a header comment that can be + * modified if desired. + * - Chunks will be written in order. + * - The file will not be touched if no changes need to be written + */ +export class GeneratedFile { + private _content: Output[] = []; + private _entry: FSEntry; + + /** initialize the codegen file with the given path */ + constructor(path: string) { + this._entry = new FSEntry(path); + } + + /** public header comment */ + header = makeComment(`WARNING: This file is auto-generated. Do not edit it manually.`); + + /** path of the generated file */ + get path() { + return this._entry.path; + } + + /** add content to the generated file */ + add(...content: Output[]) { + this._content.push(...content); + } + + /** the full text of the generated file */ + render(): string { + let content = this.header.output(); + if (this._content.length > 0) { + content += '\n' + serialize(this._content); + } + if (!content.endsWith('\n')) { + content += '\n'; + } + return content; + } + + /** whether the file on disk already holds the generated content */ + isCurrent(): boolean { + return this._entry.exists && this._entry.content === this.render(); + } + + /** + * write the generated file to disk when its content changed + * @returns true when the file was written + */ + commit(): boolean { + const content = this.render(); + // load the current content first so an unchanged file is not rewritten + if (this._entry.exists && this._entry.content === content) { + return false; + } + this._entry.content = content; + this._entry.writeContentsSync(); + return true; + } +} + +/** + * get the output text for one or more strings or chunks + */ +export function serialize(content: Output): string { + if (Array.isArray(content)) { + return content.map(serialize).join(''); + } + return typeof content === 'string' ? content : content.output(); +} + +function writeComment(text: string | string[], type: 'block' | 'line'): string { + const lines = Array.isArray(text) ? text : text.split('\n'); + if (type === 'line') { + return lines.map((line) => `// ${line}`).join('\n'); + } + return `/**\n${lines.map((line) => ` * ${line}`).join('\n')}\n */`; +} diff --git a/scripts/src/codegen/valuePool.test.ts b/scripts/src/codegen/valuePool.test.ts new file mode 100644 index 00000000000..ccba7b4abfb --- /dev/null +++ b/scripts/src/codegen/valuePool.test.ts @@ -0,0 +1,354 @@ +import assert from 'node:assert/strict'; +import { createRequire } from 'node:module'; +import { describe, it } from 'node:test'; + +import { CodeExpression, expression, ValuePool } from './valuePool.ts'; + +type AstNode = { + type: string; + name?: string; + value?: unknown; + operator?: string; + argument?: AstNode; + expression?: AstNode; + elements?: (AstNode | null)[]; + properties?: AstNode[]; + key?: AstNode; + computed?: boolean; + callee?: AstNode; + arguments?: AstNode[]; + declaration?: AstNode | null; + declarations?: AstNode[]; + kind?: string; + id?: AstNode; + init?: AstNode | null; + body?: AstNode[]; + program?: AstNode; +}; + +const babel = createRequire(import.meta.url)('@babel/core') as { + parseSync(code: string, options: Record<string, unknown>): AstNode | null; +}; + +/** + * Read the exported values of generated code by interpreting its literals, references, and spreads as data. The code + * is parsed, never run. A call evaluates to `{ call, args }`, and an external identifier to `{ external }`. + */ +function readExports(code: string, externals: readonly string[] = ['fontWeightBold']): Record<string, unknown> { + const file = babel.parseSync(code, { + babelrc: false, + configFile: false, + filename: 'generated.ts', + parserOpts: { plugins: ['typescript'] }, + }); + const scope = new Map<string, unknown>(externals.map((name) => [name, { external: name }])); + const exported: Record<string, unknown> = {}; + for (const statement of file!.program!.body!) { + const isExport = statement.type === 'ExportNamedDeclaration'; + const declaration = isExport ? statement.declaration! : statement; + if (declaration.type === 'ImportDeclaration') { + continue; + } + assert.equal(declaration.type, 'VariableDeclaration'); + assert.equal(declaration.kind, 'const'); + for (const declarator of declaration.declarations!) { + const name = declarator.id!.name!; + assert.ok(!scope.has(name), `${name} is declared twice`); + scope.set(name, evaluate(declarator.init!, scope)); + if (isExport) { + exported[name] = scope.get(name); + } + } + } + return exported; +} + +function evaluate(node: AstNode, scope: ReadonlyMap<string, unknown>): unknown { + switch (node.type) { + case 'StringLiteral': + case 'NumericLiteral': + case 'BooleanLiteral': + return node.value; + case 'NullLiteral': + return null; + case 'Identifier': + if (node.name === 'undefined') { + return undefined; + } + assert.ok(scope.has(node.name!), `${node.name} is referenced before it is declared`); + return scope.get(node.name!); + case 'UnaryExpression': + assert.equal(node.operator, '-'); + return -(evaluate(node.argument!, scope) as number); + case 'TSAsExpression': + case 'TSSatisfiesExpression': + return evaluate(node.expression!, scope); + case 'ArrayExpression': + return node.elements!.map((element) => evaluate(element!, scope)); + case 'ObjectExpression': { + const result: Record<string, unknown> = {}; + for (const property of node.properties!) { + if (property.type === 'SpreadElement') { + Object.assign(result, evaluate(property.argument!, scope)); + } else { + assert.equal(property.type, 'ObjectProperty'); + assert.ok(!property.computed); + const key = property.key!.type === 'Identifier' ? property.key!.name! : String(property.key!.value); + result[key] = evaluate((property as { value: AstNode }).value, scope); + } + } + return result; + } + case 'CallExpression': + return { call: node.callee!.name, args: node.arguments!.map((argument) => evaluate(argument, scope)) }; + default: + throw new Error(`Unexpected ${node.type} in generated code.`); + } +} + +/** The data a value is expected to read back as: expressions become calls and undefined properties disappear. */ +function expected(value: unknown): unknown { + if (value instanceof CodeExpression) { + const open = value.code.indexOf('('); + return open < 0 ? { external: value.code } : { call: value.code.slice(0, open), args: [value.code.slice(open + 2, -2)] }; + } + if (Array.isArray(value)) { + return value.map(expected); + } + if (value && typeof value === 'object') { + return Object.fromEntries( + Object.entries(value) + .filter(([, item]) => item !== undefined) + .map(([key, item]) => [key, expected(item)]), + ); + } + return value; +} + +function roundTrip(pool: ValuePool, declarations: Record<string, unknown>) { + const code = pool.output(); + assert.deepEqual(readExports(code), expected(declarations)); + return code; +} + +const platformColor = (name: string) => expression(`PlatformColor('${name}')`, { pure: true, name: `platformColor${name}` }); + +describe('ValuePool', () => { + it('emits an equal value once and aliases equal declarations', () => { + const value = { shadow2: { ambient: { x: 0, y: 0, blur: 2, color: '#0000003d' }, key: { x: 0, y: 1, blur: 2, color: '#00000047' } } }; + const pool = new ValuePool(); + pool.declare('darkShadows', value, { type: 'Shadows' }); + pool.declare('hcShadows', structuredClone(value), { type: 'Shadows' }); + const code = roundTrip(pool, { darkShadows: value, hcShadows: value }); + assert.match(code, /^export const hcShadows: Shadows = darkShadows;$/m); + assert.equal(code.match(/#0000003d/g)?.length, 1); + }); + + it('shares entries in ancestors that spread the ancestors of larger member sets', () => { + const shared = { a1: '#000001', a2: '#000002', a3: '#000003', a4: '#000004' }; + const nonContrast = { b1: '#000011', b2: '#000012', b3: '#000013', b4: '#000014' }; + const dark = { c1: '#000021', c2: '#000022', c3: '#000023', c4: '#000024' }; + const declarations = { + lightColors: { ...shared, ...nonContrast, c1: '#ffff21', c2: '#ffff22', c3: '#ffff23', c4: '#ffff24' }, + darkColors: { ...shared, ...nonContrast, ...dark, d1: '#000031' }, + dimColors: { ...shared, ...nonContrast, ...dark, d1: '#000041' }, + contrastColors: { ...shared, b1: 'red', b2: 'green', b3: 'blue', b4: 'gray', c1: 'red', c2: 'green', c3: 'blue', c4: 'gray' }, + }; + const pool = new ValuePool(); + for (const [name, value] of Object.entries(declarations)) { + pool.declare(name, value, { type: 'Colors' }); + } + const code = roundTrip(pool, declarations); + assert.match(code, /^const sharedColors = \{$/m); + assert.match(code, /^const lightDarkDimColors = \{\n {2}\.\.\.sharedColors,$/m); + assert.match(code, /^const darkDimColors = \{\n {2}\.\.\.lightDarkDimColors,$/m); + assert.match(code, /^export const darkColors: Colors = \{\n {2}\.\.\.darkDimColors,\n {2}d1: '#000031',\n\};$/m); + assert.match(code, /^export const contrastColors: Colors = \{\n {2}\.\.\.sharedColors,$/m); + assert.equal(code.match(/a1: /g)?.length, 1); + }); + + it('shares entries of objects held under the same key', () => { + const color = Object.fromEntries(Array.from({ length: 8 }, (_, index) => [`neutral${index}`, ['#ffffff', `#00000${index}`]])); + const common = { spacing: { small: 4, large: 16 }, radius: { small: 2, large: 8 }, stroke: { thin: 1 }, motion: { fast: 100 } }; + const declarations = { + coolTokenInput: { ...common, color: { ...color, brand: ['#0000ff', '#8888ff'] } }, + warmTokenInput: { ...structuredClone(common), color: { ...color, brand: ['#ff8800', '#ffaa44'] } }, + }; + const pool = new ValuePool(); + pool.declare('coolTokenInput', declarations.coolTokenInput, { type: 'TokenInput' }); + pool.declare('warmTokenInput', declarations.warmTokenInput, { type: 'TokenInput' }); + const code = roundTrip(pool, declarations); + assert.match(code, /^const sharedTokenInput = \{\n {2}spacing: /m); + assert.match(code, /^const sharedTokenInputColor = \{$/m); + assert.match(code, /^ {2}color: \{ \.\.\.sharedTokenInputColor, brand: \['#0000ff', '#8888ff'\] \},$/m); + assert.match(code, /^const rgbffffff = '#ffffff';$/m); + }); + + it('keeps values inline when sharing them would grow the output', () => { + const declarations = { first: { a: 'ab', b: 1000000, c: [1, 2] }, second: { a: 'ab', b: 1000000, c: [1, 2], d: true } }; + const pool = new ValuePool({ ancestors: false }); + pool.declare('first', declarations.first); + pool.declare('second', declarations.second); + const code = roundTrip(pool, declarations); + assert.doesNotMatch(code, /^const /m); + }); + + it('hoists repeated values with const assertions and pure calls', () => { + const entry = { rest: ['#242424', '#ffffff'], type: 'inverted' }; + const declarations = { + tokens: { + a: entry, + b: structuredClone(entry), + c: { rest: ['#6f6f6f', '#929292'], type: 'inverted' }, + d: { rest: ['#6f6f6f', '#929292'], type: 'inverted' }, + e: platformColor('ButtonFace'), + f: platformColor('ButtonFace'), + }, + }; + const pool = new ValuePool(); + pool.declare('tokens', declarations.tokens); + const code = roundTrip(pool, declarations); + assert.match(code, /^const inverted = 'inverted';$/m); + assert.match(code, /^const platformColorButtonFace = \/\* @__PURE__ \*\/ PlatformColor\('ButtonFace'\);$/m); + assert.match(code, /^const a = \{ rest: \['#242424', '#ffffff'\], type: inverted \} as const;$/m); + assert.match(code, /^ {2}b: a,$/m); + }); + + it('names values without colliding with reserved names or declarations', () => { + const sequence = [1, 2, 3, 4, 5, 6]; + const declarations = { + first: { value: sequence, other: [...sequence], label: 'default', again: 'default' }, + deep: { x: [...sequence] }, + }; + const pool = new ValuePool({ ancestors: false, name: (value) => (Array.isArray(value) ? 'deep' : undefined) }); + pool.reserve('defaultValue'); + pool.declare('first', declarations.first); + pool.declare('deep', declarations.deep); + const code = roundTrip(pool, declarations); + assert.match(code, /^const deep1 = \[1, 2, 3, 4, 5, 6\] as const;$/m); + assert.match(code, /^const defaultValue1 = 'default';$/m); + }); + + it('emits a declaration before the declarations that reference it', () => { + const shared = { a: '#123456', b: '#654321', c: 'something long enough to share' }; + const declarations = { outer: { first: shared, second: shared }, inner: shared }; + const pool = new ValuePool(); + pool.declare('outer', declarations.outer); + pool.declare('inner', declarations.inner); + const code = roundTrip(pool, declarations); + assert.ok(code.indexOf('export const inner') < code.indexOf('export const outer')); + assert.match(code, /^ {2}first: inner,$/m); + }); + + it('declares a value with different types once and references it from each declaration', () => { + const value = { a: '#123456', b: '#654321' }; + const pool = new ValuePool(); + pool.declare('first', value, { type: 'First' }); + pool.declare('second', structuredClone(value), { type: 'Second' }); + const code = roundTrip(pool, { first: value, second: value }); + assert.match(code, /^export const first: First = firstValue;$/m); + assert.match(code, /^export const second: Second = firstValue;$/m); + }); + + it('formats declarations, comments, and satisfies clauses', () => { + const pool = new ValuePool(); + pool.declare( + 'tokens', + { a: 'x', 'b-c': 1, 0: null, d: undefined, e: [] }, + { comment: 'Tokens.', satisfies: 'Tokens', exported: false }, + ); + assert.equal(pool.output(), "/** Tokens. */\nconst tokens = {\n 0: null,\n a: 'x',\n 'b-c': 1,\n e: [],\n} satisfies Tokens;\n"); + }); + + it('reduces the estimated size by sharing ancestors', () => { + const base = Object.fromEntries( + Array.from({ length: 30 }, (_, index) => [`neutralForeground${index}`, `#0000${String(index).padStart(2, '0')}`]), + ); + const create = (ancestors: boolean) => { + const pool = new ValuePool({ ancestors }); + pool.declare('lightColors', { ...base, accent: '#ff0000' }, { type: 'Colors' }); + pool.declare('darkColors', { ...base, accent: '#00ff00' }, { type: 'Colors' }); + return pool.estimatedSize; + }; + assert.ok(create(true) < create(false) * 0.6); + }); + + it('round-trips random values', () => { + let seed = 7; + // mulberry32 + const random = (limit: number) => { + seed = (seed + 0x6d2b79f5) | 0; + let value = Math.imul(seed ^ (seed >>> 15), 1 | seed); + value = (value + Math.imul(value ^ (value >>> 7), 61 | value)) ^ value; + return Math.floor((((value ^ (value >>> 14)) >>> 0) / 4294967296) * limit); + }; + const leaves = [ + '#ffffff', + '#000000', + 'inverted', + 'a', + 0, + 1, + 2.5, + -1, + true, + null, + platformColor('Window'), + expression('fontWeightBold'), + ]; + const createObject = (depth: number): Record<string, unknown> => + Object.fromEntries(Array.from({ length: 2 + random(8) }, () => [`key${random(10)}`, createValue(depth + 1)])); + const createValue = (depth: number): unknown => { + const choice = random(depth > 2 ? 2 : 4); + if (choice < 2) { + return leaves[random(leaves.length)]; + } + return choice === 2 ? Array.from({ length: random(4) }, () => createValue(depth + 1)) : createObject(depth); + }; + // Derive a variant by replacing, removing, and adding some entries, recursively in nested objects. + const vary = (value: unknown, depth: number): unknown => { + if (!value || typeof value !== 'object' || Array.isArray(value) || value instanceof CodeExpression) { + return random(4) === 0 ? createValue(depth) : value; + } + const result: Record<string, unknown> = {}; + for (const [key, item] of Object.entries(value)) { + const choice = random(8); + if (choice > 1) { + result[key] = choice < 4 ? vary(item, depth + 1) : item; + } else if (choice === 1) { + result[key] = createValue(depth + 1); + } + } + if (random(3) === 0) { + result[`added${random(3)}`] = createValue(depth + 1); + } + return result; + }; + let spreads = 0; + for (let run = 0; run < 200; run++) { + const declarations: Record<string, unknown> = {}; + const pool = new ValuePool({ identifierSize: 1 + random(2) }).reserve('fontWeightBold'); + const base = { ...createObject(2), nested: createValue(1), more: createValue(1) }; + for (let index = 0; index < 2 + random(5); index++) { + const value = random(6) === 0 ? createValue(1) : vary(base, 1); + declarations[`variant${index}Tokens`] = value; + pool.declare(`variant${index}Tokens`, value, { type: random(4) === 0 ? undefined : 'Tokens' }); + } + spreads += roundTrip(pool, declarations).includes('...') ? 1 : 0; + } + assert.ok(spreads > 50, `only ${spreads} runs shared ancestors`); + }); + + it('rejects values it cannot emit', () => { + assert.throws(() => new ValuePool().declare('value', new Date()), /not a plain object/); + assert.throws(() => new ValuePool().declare('value', () => 1), /unsupported function/); + const circular: Record<string, unknown> = {}; + circular.self = circular; + assert.throws(() => new ValuePool().declare('value', circular), /circular/); + assert.throws(() => new ValuePool().declare('default', 1), /not a valid declaration name/); + const pool = new ValuePool().declare('value', 1); + assert.throws(() => pool.declare('value', 2), /already declared/); + pool.output(); + assert.throws(() => pool.declare('other', 1), /already been emitted/); + }); +}); diff --git a/scripts/src/codegen/valuePool.ts b/scripts/src/codegen/valuePool.ts new file mode 100644 index 00000000000..17210711617 --- /dev/null +++ b/scripts/src/codegen/valuePool.ts @@ -0,0 +1,999 @@ +import type { Chunk } from './file.ts'; + +/** Options for a {@link CodeExpression}. */ +export type ExpressionOptions = { + /** Base name for the constant when the expression is hoisted. */ + name?: string; + /** Marks a call as free of side effects, so bundlers can drop it when it is unused. */ + pure?: boolean; + /** Estimated minified size in bytes. Defaults to an estimate that counts each identifier as a mangled name. */ + size?: number; +}; + +/** JavaScript emitted verbatim, such as an imported identifier or a call. */ +export class CodeExpression { + readonly code: string; + readonly name: string | undefined; + readonly pure: boolean; + readonly size: number | undefined; + + constructor(code: string, options: ExpressionOptions = {}) { + this.code = code; + this.name = options.name; + this.pure = options.pure ?? false; + this.size = options.size; + } +} + +/** Create a {@link CodeExpression}. */ +export function expression(code: string, options?: ExpressionOptions): CodeExpression { + return new CodeExpression(code, options); +} + +/** Values a {@link ValuePool} can emit. Objects must be plain objects; object properties set to undefined are omitted. */ +export type CodeValue = + | string + | number + | boolean + | null + | undefined + | CodeExpression + | readonly CodeValue[] + | { readonly [key: string]: CodeValue }; + +/** Property keys and array indices from a declaration to a value. The first segment is the declaration name. */ +export type ValuePath = readonly (string | number)[]; + +/** Options for a {@link ValuePool}. */ +export type ValuePoolOptions = { + /** Base name for a hoisted value. Return undefined to use the default name. */ + name?: (value: unknown, path: ValuePath) => string | undefined; + /** Extract entries that declarations of the same family share into common ancestor objects. Defaults to true. */ + ancestors?: boolean; + /** Add `as const` to hoisted arrays and objects, so literal and tuple types survive hoisting. Defaults to true. */ + constAssertions?: boolean; + /** Estimated length of a minified identifier, used to decide what to share. Defaults to 2. */ + identifierSize?: number; + /** Line width for formatting. Defaults to 140. */ + printWidth?: number; +}; + +/** Options for a declaration added with {@link ValuePool.declare}. */ +export type DeclarationOptions = { + /** Export the declaration. Defaults to true. */ + exported?: boolean; + /** Type annotation, as in `const name: Type`. */ + type?: string; + /** Type for a `satisfies` clause. */ + satisfies?: string; + /** Documentation comment for the declaration. */ + comment?: string | string[]; + /** Object declarations in the same family share ancestors. Defaults to the type annotation. */ + family?: string; +}; + +type Entry = readonly [key: string, node: ValueNode]; + +type Family = { + /** Declaration names of the family's object members, in declaration order. */ + readonly roots: readonly string[]; + /** Common camel-case suffix of the root names, such as `Shadows`. Empty when the names share none. */ + readonly suffix: string; + readonly name: string; +}; + +type AncestorInfo = { + readonly family: Family; + /** Declaration names whose value includes this ancestor. */ + readonly roots: readonly string[]; + /** Property keys from the declarations to the objects that spread this ancestor. */ + readonly path: readonly string[]; +}; + +type ValueNode = { + readonly id: number; + readonly kind: 'literal' | 'expression' | 'array' | 'object'; + /** The value and path where the node first occurred, for naming. */ + readonly source: unknown; + readonly path: ValuePath; + readonly literal?: string | number | boolean | null | undefined; + readonly expression?: CodeExpression; + readonly items?: readonly ValueNode[]; + /** Object entries in first-occurrence order. */ + readonly entries?: readonly Entry[]; + readonly lookup?: ReadonlyMap<string, ValueNode>; + /** Ancestor objects this object spreads; `own` holds the entries they do not cover. */ + spreads?: ValueNode[]; + own?: Entry[]; + ancestor?: AncestorInfo; +}; + +type Declaration = { + readonly name: string; + readonly node: ValueNode; + readonly options: DeclarationOptions; + readonly family: string; + readonly index: number; +}; + +type Item = { + readonly node: ValueNode; + /** The declaration this item emits; undefined for a hoisted constant. */ + readonly declaration?: Declaration; + readonly rank: readonly (number | string)[]; + readonly group: string; + dependencies: Item[]; +}; + +const identifierPattern = /^[A-Za-z_$][\w$]*$/; +const indexPattern = /^(?:0|[1-9]\d*)$/; +const hexColorPattern = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/; +const wordPattern = /^[A-Za-z][A-Za-z0-9]{0,23}$/; +const reservedWords = new Set( + ( + 'arguments await break case catch class const continue debugger default delete do else enum eval export extends false ' + + 'finally for function if implements import in instanceof interface let new null package private protected public ' + + 'return static super switch this throw true try typeof undefined var void while with yield NaN Infinity' + ).split(' '), +); +const maxHoistingPasses = 8; + +function formatPath(path: ValuePath): string { + return path.map((segment, index) => (typeof segment === 'number' ? `[${segment}]` : index === 0 ? segment : `.${segment}`)).join(''); +} + +function quote(value: string): string { + let text = "'"; + for (const char of value) { + if (char === "'" || char === '\\') { + text += `\\${char}`; + } else if (char === '\n') { + text += '\\n'; + } else if (char === '\r') { + text += '\\r'; + } else if (char === '\u2028' || char === '\u2029') { + text += char === '\u2028' ? '\\u2028' : '\\u2029'; + } else { + text += char; + } + } + return `${text}'`; +} + +function literalCode(value: ValueNode['literal']): string { + if (typeof value === 'string') { + return quote(value); + } + if (typeof value === 'number' && Object.is(value, -0)) { + return '-0'; + } + return String(value); +} + +function propertyKey(key: string): string { + return identifierPattern.test(key) || indexPattern.test(key) ? key : quote(key); +} + +/** Minified size of a number as esbuild prints it, such as `.5` for 0.5 and `1e3` for 1000. */ +function numberSize(value: number): number { + let text = Object.is(value, -0) ? '-0' : String(value); + if (text.startsWith('0.') || text.startsWith('-0.')) { + text = text.replace('0.', '.'); + } + if (Number.isInteger(value) && Math.abs(value) >= 1000) { + let zeros = 0; + while (text[text.length - 1 - zeros] === '0') { + zeros++; + } + if (zeros >= 3) { + return text.length - zeros + 1 + String(zeros).length; + } + } + return text.length; +} + +function literalSize(value: ValueNode['literal']): number { + switch (typeof value) { + case 'string': + return JSON.stringify(value).length; + case 'number': + return numberSize(value); + case 'boolean': + return 2; + case 'undefined': + return 6; + default: + return 4; + } +} + +function keySize(key: string): number { + return identifierPattern.test(key) || indexPattern.test(key) ? key.length : JSON.stringify(key).length; +} + +function isIdentifierStart(char: string): boolean { + return (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || char === '_' || char === '$'; +} + +function isIdentifierPart(char: string): boolean { + return isIdentifierStart(char) || (char >= '0' && char <= '9'); +} + +/** Visit the code outside string literals, reporting identifiers and the other characters a minifier keeps. */ +function scanCode(code: string, onIdentifier: (name: string, isProperty: boolean) => void, onOther: (length: number) => void) { + let previous = ''; + let index = 0; + while (index < code.length) { + const char = code[index]; + if (char === "'" || char === '"' || char === '`') { + let end = index + 1; + while (end < code.length && code[end] !== char) { + end += code[end] === '\\' ? 2 : 1; + } + onOther(Math.min(end + 1, code.length) - index); + previous = char; + index = end + 1; + } else if (isIdentifierStart(char)) { + let end = index + 1; + while (end < code.length && isIdentifierPart(code[end])) { + end++; + } + onIdentifier(code.slice(index, end), previous === '.'); + previous = 'a'; + index = end; + } else { + if (char.trim() !== '') { + onOther(1); + previous = char; + } + index++; + } + } +} + +function expressionSize(value: CodeExpression, identifierSize: number): number { + if (value.size !== undefined) { + return value.size; + } + let size = 0; + scanCode( + value.code, + (name, isProperty) => (size += isProperty ? name.length : identifierSize), + (length) => (size += length), + ); + return size; +} + +function expressionCode(value: CodeExpression): string { + return value.pure ? `/* @__PURE__ */ ${value.code}` : value.code; +} + +function capitalize(text: string): string { + return text.charAt(0).toUpperCase() + text.slice(1); +} + +/** Convert text to a valid identifier, camel-casing across invalid characters. */ +function toIdentifier(text: string): string { + let name = ''; + let upper = false; + for (const char of text) { + if (isIdentifierPart(char)) { + name += upper && name ? char.toUpperCase() : char; + upper = false; + } else { + upper = true; + } + } + if (!name) { + return 'value'; + } + if (!isIdentifierStart(name[0])) { + name = `_${name}`; + } + return reservedWords.has(name) ? `${name}Value` : name; +} + +function splitWords(name: string): string[] { + const words: string[] = []; + let start = 0; + for (let index = 1; index < name.length; index++) { + if (name[index] >= 'A' && name[index] <= 'Z') { + words.push(name.slice(start, index)); + start = index; + } + } + words.push(name.slice(start)); + return words; +} + +function createFamily(name: string, roots: readonly string[]): Family { + const words = roots.map(splitWords); + const suffix: string[] = []; + for (;;) { + const position = suffix.length + 1; + const word = words[0][words[0].length - position]; + if (!words.every((list) => list.length > position && list[list.length - position] === word)) { + break; + } + suffix.unshift(word); + } + return { name, roots, suffix: suffix.join('') }; +} + +function ancestorName({ family, roots, path }: AncestorInfo): string { + const pathPart = path.map((key) => capitalize(toIdentifier(key))).join(''); + if (!family.suffix) { + return toIdentifier(`shared ${family.name} ${pathPart}`); + } + if (family.roots.every((root) => roots.includes(root))) { + return `shared${family.suffix}${pathPart}`; + } + const prefixes = family.roots.filter((root) => roots.includes(root)).map((root) => root.slice(0, root.length - family.suffix.length)); + return toIdentifier(prefixes.map((prefix, index) => (index === 0 ? prefix : capitalize(prefix))).join('') + family.suffix + pathPart); +} + +function compareRank(left: readonly (number | string)[], right: readonly (number | string)[]): number { + for (let index = 0; index < Math.min(left.length, right.length); index++) { + if (left[index] !== right[index]) { + return left[index] < right[index] ? -1 : 1; + } + } + return left.length - right.length; +} + +function writeDocComment(text: string | string[]): string { + const lines = Array.isArray(text) ? text : text.split('\n'); + return lines.length === 1 ? `/** ${lines[0]} */` : `/**\n${lines.map((line) => (line ? ` * ${line}` : ' *')).join('\n')}\n */`; +} + +/** + * A value pool emits constant declarations and minimizes their minified size. Equal values are emitted once and shared, + * which a size model decides per value: strings, expressions, arrays, and objects are hoisted into constants when that + * is smaller than repeating them. Object declarations in the same family share common ancestor objects: entries that + * several members hold are emitted once in an ancestor that the members spread, recursively for nested objects, and + * ancestors spread the ancestors of larger member sets. Hex color strings are named `rgb<hex>`, as a Ramp names them. + * + * Shared objects and ancestors change the key order of emitted objects. Declarations are emitted in dependency order. + */ +export class ValuePool implements Chunk { + private readonly _ancestors: boolean; + private readonly _constAssertions: boolean; + private readonly _identifierSize: number; + private readonly _printWidth: number; + private readonly _name: ValuePoolOptions['name']; + private readonly _declarations: Declaration[] = []; + private readonly _reserved = new Set<string>(); + private readonly _nodes = new Map<string, ValueNode>(); + private readonly _canonicalSizes = new Map<ValueNode, number>(); + private _names = new Map<ValueNode, string>(); + private _output: string | undefined; + private _size = 0; + + constructor(options: ValuePoolOptions = {}) { + this._ancestors = options.ancestors ?? true; + this._constAssertions = options.constAssertions ?? true; + this._identifierSize = options.identifierSize ?? 2; + this._printWidth = options.printWidth ?? 140; + this._name = options.name; + } + + /** Reserve names, such as imports, that hoisted constants must not use. */ + reserve(...names: string[]): this { + this.assertOpen(); + for (const name of names) { + this._reserved.add(name); + } + return this; + } + + /** Declare a constant. Declarations are emitted in the order they are declared, after the values they reference. */ + declare(name: string, value: unknown, options: DeclarationOptions = {}): this { + this.assertOpen(); + if (!identifierPattern.test(name) || reservedWords.has(name)) { + throw new Error(`${name} is not a valid declaration name.`); + } + if (this._declarations.some((declaration) => declaration.name === name)) { + throw new Error(`${name} is already declared.`); + } + const node = this.intern(value, [name], new Set()); + const family = options.family ?? options.type ?? options.satisfies ?? ''; + this._declarations.push({ name, node, options, family, index: this._declarations.length }); + return this; + } + + /** Estimated minified size in bytes of the emitted declarations. */ + get estimatedSize(): number { + this.resolve(); + return this._size; + } + + output(): string { + return this.resolve(); + } + + private assertOpen() { + if (this._output !== undefined) { + throw new Error('The value pool has already been emitted.'); + } + } + + private intern(value: unknown, path: ValuePath, active: Set<object>): ValueNode { + if (value instanceof CodeExpression) { + return this.node(`e${value.code}`, { kind: 'expression', expression: value }, value, path); + } + switch (typeof value) { + case 'string': + return this.node(`s${value}`, { kind: 'literal', literal: value }, value, path); + case 'number': + return this.node(`n${Object.is(value, -0) ? '-0' : String(value)}`, { kind: 'literal', literal: value }, value, path); + case 'boolean': + case 'undefined': + return this.node(`l${value}`, { kind: 'literal', literal: value }, value, path); + case 'object': + break; + default: + throw new Error(`${formatPath(path)} is an unsupported ${typeof value} value.`); + } + if (value === null) { + return this.node('lnull', { kind: 'literal', literal: null }, value, path); + } + if (active.has(value)) { + throw new Error(`${formatPath(path)} is circular.`); + } + active.add(value); + try { + if (Array.isArray(value)) { + const items = Array.from(value as unknown[], (item, index) => this.intern(item, [...path, index], active)); + return this.node(`a${items.map((item) => item.id).join(',')}`, { kind: 'array', items }, value, path); + } + const prototype: unknown = Object.getPrototypeOf(value); + if (prototype !== Object.prototype && prototype !== null) { + throw new Error(`${formatPath(path)} is not a plain object.`); + } + const entries: Entry[] = []; + for (const [key, item] of Object.entries(value)) { + if (key === '__proto__') { + throw new Error(`${formatPath(path)} has an unsupported __proto__ key.`); + } + if (item !== undefined) { + entries.push([key, this.intern(item, [...path, key], active)]); + } + } + return this.objectNode(entries, value, path); + } finally { + active.delete(value); + } + } + + private objectNode(entries: readonly Entry[], source: unknown, path: ValuePath): ValueNode { + const key = `o${entries + .map(([name, node]) => `${JSON.stringify(name)}:${node.id}`) + .sort() + .join(',')}`; + return this.node(key, { kind: 'object', entries, lookup: new Map(entries) }, source, path); + } + + private node(key: string, shape: Omit<ValueNode, 'id' | 'source' | 'path'>, source: unknown, path: ValuePath): ValueNode { + let node = this._nodes.get(key); + if (!node) { + node = { ...shape, id: this._nodes.size, source, path }; + this._nodes.set(key, node); + } + return node; + } + + private extractFamilies() { + const families = new Map<string, Declaration[]>(); + for (const declaration of this._declarations) { + const list = families.get(declaration.family) ?? []; + list.push(declaration); + families.set(declaration.family, list); + } + for (const [name, declarations] of families) { + const objects = declarations.filter(({ node }) => node.kind === 'object'); + const members: ValueNode[] = []; + const memberRoots: string[][] = []; + for (const { name: root, node } of objects) { + const index = members.indexOf(node); + if (index >= 0) { + memberRoots[index].push(root); + } else { + members.push(node); + memberRoots.push([root]); + } + } + if (members.length >= 2) { + const family = createFamily( + name, + objects.map((declaration) => declaration.name), + ); + this.extractAncestors(family, members, memberRoots, []); + } + } + } + + /** + * Group the entries of distinct objects by the set of objects that hold them, and move each group that is smaller + * shared into an ancestor object. An ancestor spreads the ancestors of the smallest larger sets that contain its set, + * and each object spreads the ancestors of the smallest sets that contain it. Objects held under the same key recurse. + */ + private extractAncestors( + family: Family, + nodes: readonly ValueNode[], + nodeRoots: readonly (readonly string[])[], + path: readonly string[], + ) { + const members = nodes.flatMap((node, index) => (node.spreads ? [] : [{ node, roots: nodeRoots[index] }])); + if (members.length < 2) { + return; + } + type Group = { members: number[]; entries: Entry[]; node?: ValueNode }; + const groups = new Map<string, Group>(); + const keys = new Set(members.flatMap(({ node }) => node.entries!.map(([key]) => key))); + for (const key of keys) { + const holders = new Map<ValueNode, number[]>(); + members.forEach(({ node }, index) => { + const value = node.lookup!.get(key); + if (value) { + const list = holders.get(value); + if (list) { + list.push(index); + } else { + holders.set(value, [index]); + } + } + }); + for (const [value, indices] of holders) { + if (indices.length >= 2) { + const signature = indices.join(','); + const group = groups.get(signature) ?? { members: indices, entries: [] }; + group.entries.push([key, value]); + groups.set(signature, group); + } + } + const objects = [...holders.keys()].filter((value) => value.kind === 'object'); + if (objects.length >= 2) { + const roots = objects.map((value) => holders.get(value)!.flatMap((index) => members[index].roots)); + this.extractAncestors(family, objects, roots, [...path, key]); + } + } + + const chosen = [...groups.values()].filter((group) => this.ancestorBenefit(group.members.length, group.entries) > 0); + const contains = (outer: Group, inner: Group) => + outer.members.length > inner.members.length && inner.members.every((index) => outer.members.includes(index)); + const smallest = (list: Group[]) => list.filter((group) => !list.some((other) => contains(group, other))); + // Create larger sets first, so the ancestors a set spreads exist before it. + chosen.sort((left, right) => right.members.length - left.members.length); + for (const group of chosen) { + const parents = smallest(chosen.filter((other) => contains(other, group))).map((parent) => parent.node!); + const content = new Map<string, ValueNode>(parents.flatMap((parent) => parent.entries!)); + for (const [key, value] of group.entries) { + content.set(key, value); + } + const node = this.objectNode([...content], undefined, []); + if (!node.spreads && parents.length > 0) { + node.spreads = parents; + node.own = group.entries; + } + node.ancestor ??= { family, roots: group.members.flatMap((index) => members[index].roots), path }; + group.node = node; + } + members.forEach(({ node }, index) => { + const required = chosen.filter((group) => group.members.includes(index)); + if (required.length === 0 || required.some((group) => group.node === node)) { + return; + } + const covered = new Set(required.flatMap((group) => group.entries.map(([key]) => key))); + node.spreads = smallest(required).map((group) => group.node!); + node.own = node.entries!.filter(([key]) => !covered.has(key)); + }); + } + + /** Bytes saved by emitting entries that `count` objects share once, in an ancestor the objects spread. */ + private ancestorBenefit(count: number, entries: readonly Entry[]): number { + const identifierSize = this._identifierSize; + let size = 0; + for (const [key, value] of entries) { + size += keySize(key) + 2 + Math.min(this.canonicalSize(value), identifierSize); + } + // The ancestor costs a declaration and braces; each object spreads it. + return (count - 1) * size - (identifierSize + 4) - count * (identifierSize + 4); + } + + /** Throw unless the spreads and own entries of an object reproduce exactly its entries. */ + private verifyPlan(node: ValueNode) { + const merged = new Map<string, ValueNode>(); + const add = (source: ValueNode) => { + for (const spread of source.spreads ?? []) { + add(spread); + } + for (const [key, value] of source.spreads ? source.own! : source.entries!) { + if ((merged.get(key) ?? value) !== value) { + throw new Error(`Ancestors of ${formatPath(node.path)} disagree on ${key}.`); + } + merged.set(key, value); + } + }; + add(node); + const lookup = node.lookup!; + if (merged.size !== lookup.size || [...merged].some(([key, value]) => lookup.get(key) !== value)) { + throw new Error(`Ancestors of ${formatPath(node.path)} do not reproduce it.`); + } + } + + private canonicalSize(node: ValueNode): number { + let size = this._canonicalSizes.get(node); + if (size === undefined) { + size = this.contentSize(node, (child) => this.canonicalSize(child), false); + this._canonicalSizes.set(node, size); + } + return size; + } + + /** Minified size of a value, given the size of each child reference. */ + private contentSize(node: ValueNode, childSize: (child: ValueNode) => number, usePlan: boolean): number { + switch (node.kind) { + case 'literal': + return literalSize(node.literal); + case 'expression': + return expressionSize(node.expression!, this._identifierSize); + case 'array': { + const items = node.items!; + return items.reduce((size, item) => size + childSize(item), 1 + Math.max(items.length, 1)); + } + default: { + const spreads = usePlan ? (node.spreads ?? []) : []; + const entries = usePlan && node.spreads ? node.own! : node.entries!; + const parts = spreads.length + entries.length; + const size = 1 + Math.max(parts, 1) + spreads.length * (3 + this._identifierSize); + return entries.reduce((total, [key, value]) => total + keySize(key) + 1 + childSize(value), size); + } + } + } + + private resolve(): string { + if (this._output !== undefined) { + return this._output; + } + if (this._ancestors) { + this.extractFamilies(); + } + for (const node of this._nodes.values()) { + if (node.spreads) { + this.verifyPlan(node); + } + } + const heights = new Map<ValueNode, number>(); + const visit = (node: ValueNode): number => { + let height = heights.get(node); + if (height === undefined) { + height = Math.max(-1, ...children(node).map(visit)) + 1; + heights.set(node, height); + } + return height; + }; + this._declarations.forEach(({ node }) => visit(node)); + // Parents before children. + const nodes = [...heights.keys()].sort((left, right) => heights.get(right)! - heights.get(left)! || left.id - right.id); + + // The first declaration of a value emits it, and later declarations reference it. A value declared with different + // types is emitted as a constant that every declaration references, so each declaration checks its own type. + const owners = new Map<ValueNode, Declaration>(); + const detached = new Set<ValueNode>(); + for (const declaration of this._declarations) { + const owner = owners.get(declaration.node); + if (!owner) { + owners.set(declaration.node, declaration); + } else if (owner.options.type !== declaration.options.type || owner.options.satisfies !== declaration.options.satisfies) { + detached.add(declaration.node); + } + } + detached.forEach((node) => owners.delete(node)); + const forced = new Set(nodes.filter((node) => node.ancestor || owners.has(node) || detached.has(node))); + const aliases = this._declarations.filter((declaration) => owners.get(declaration.node) !== declaration).length; + + const declared = this.chooseDeclared(nodes, forced, aliases); + const groups = this.assignNames(nodes, declared, owners); + this._output = this.render(nodes, heights, declared, owners, groups); + return this._output; + } + + /** + * Choose the values to declare. Parents are decided before their children, because a declared parent emits its + * children once. Each pass measures values with the previous pass's choices, and the smallest result wins. + */ + private chooseDeclared(nodes: readonly ValueNode[], forced: ReadonlySet<ValueNode>, aliases: number): Set<ValueNode> { + const identifierSize = this._identifierSize; + let sizes = this.measure(nodes, forced); + let best: { declared: Set<ValueNode>; size: number } | undefined; + let previous: Set<ValueNode> | undefined; + for (let pass = 0; pass < maxHoistingPasses; pass++) { + const counts = new Map<ValueNode, number>(); + this._declarations.forEach(({ node }) => counts.set(node, (counts.get(node) ?? 0) + 1)); + const declared = new Set(forced); + for (const node of nodes) { + const count = counts.get(node) ?? 0; + const size = sizes.get(node)!; + const hoistable = node.kind !== 'literal' || typeof node.literal === 'string'; + if (hoistable && !declared.has(node) && count * size > size + identifierSize + 2 + count * identifierSize) { + declared.add(node); + } + const emitted = declared.has(node) ? 1 : count; + for (const child of children(node)) { + counts.set(child, (counts.get(child) ?? 0) + emitted); + } + } + sizes = this.measure(nodes, declared); + let size = aliases * (2 * identifierSize + 2); + declared.forEach((node) => (size += identifierSize + 2 + sizes.get(node)!)); + if (!best || size < best.size) { + best = { declared, size }; + } + if (previous?.size === declared.size && [...declared].every((node) => previous!.has(node))) { + break; + } + previous = declared; + } + this._size = best!.size; + return best!.declared; + } + + /** Minified size of each value, children first, where declared children cost a reference. */ + private measure(nodes: readonly ValueNode[], declared: ReadonlySet<ValueNode>): Map<ValueNode, number> { + const sizes = new Map<ValueNode, number>(); + for (let index = nodes.length - 1; index >= 0; index--) { + const node = nodes[index]; + sizes.set( + node, + this.contentSize(node, (child) => (declared.has(child) ? this._identifierSize : sizes.get(child)!), true), + ); + } + return sizes; + } + + /** Name every declared value and return the group each hoisted value is listed with. */ + private assignNames(nodes: readonly ValueNode[], declared: ReadonlySet<ValueNode>, owners: ReadonlyMap<ValueNode, Declaration>) { + const names = new Map<ValueNode, string>(); + const taken = new Set([...this._reserved, ...this._declarations.map(({ name }) => name)]); + for (const node of nodes) { + if (node.expression) { + scanCode( + node.expression.code, + (name, isProperty) => !isProperty && taken.add(name), + () => undefined, + ); + } + } + owners.forEach((declaration, node) => names.set(node, declaration.name)); + const unique = (base: string) => { + let name = base; + for (let index = 2; taken.has(name); index++) { + name = `${base}${index}`; + } + taken.add(name); + return name; + }; + const pending = nodes.filter((node) => declared.has(node) && !names.has(node)).sort((left, right) => left.id - right.id); + const groups = new Map<ValueNode, string>(); + const byBase = new Map<string, ValueNode[]>(); + for (const node of pending) { + if (node.ancestor) { + names.set(node, unique(ancestorName(node.ancestor))); + } else { + const base = this.baseName(node); + const list = byBase.get(base); + if (list) { + list.push(node); + } else { + byBase.set(base, [node]); + } + groups.set(node, base); + } + } + for (const [base, list] of byBase) { + if (list.length === 1 && !taken.has(base)) { + names.set(list[0], unique(base)); + continue; + } + let index = 1; + for (const node of list) { + while (taken.has(`${base}${index}`)) { + index++; + } + names.set(node, unique(`${base}${index}`)); + } + } + this._names = names; + return groups; + } + + private baseName(node: ValueNode): string { + const custom = this._name?.(node.source, node.path); + if (custom) { + return toIdentifier(custom); + } + if (typeof node.literal === 'string') { + if (hexColorPattern.test(node.literal)) { + return `rgb${node.literal.slice(1)}`; + } + if (wordPattern.test(node.literal)) { + return toIdentifier(node.literal); + } + } + if (node.expression?.name) { + return toIdentifier(node.expression.name); + } + for (let index = node.path.length - 1; index > 0; index--) { + const segment = node.path[index]; + if (typeof segment === 'string') { + return toIdentifier(segment); + } + } + return node.path.length === 1 ? `${node.path[0]}Value` : 'value'; + } + + private render( + nodes: readonly ValueNode[], + heights: ReadonlyMap<ValueNode, number>, + declared: ReadonlySet<ValueNode>, + owners: ReadonlyMap<ValueNode, Declaration>, + groups: ReadonlyMap<ValueNode, string>, + ): string { + const items: Item[] = []; + const emitters = new Map<ValueNode, Item>(); + for (const node of nodes) { + if (declared.has(node) && !owners.has(node)) { + // Hoisted values are listed in blocks by kind and height: strings and expressions by name, then arrays and + // objects by base name and first occurrence. Ancestors follow, then the declarations. + const height = heights.get(node)!; + const kind = node.kind === 'literal' || node.kind === 'expression' ? node.kind : 'value'; + const order = kind === 'value' ? [groups.get(node)!, node.id] : [this._names.get(node)!]; + const rank = node.ancestor ? [1, height, node.id] : [0, height, kind, ...order]; + const item: Item = { node, rank, group: `${kind}:${height}`, dependencies: [] }; + emitters.set(node, item); + items.push(item); + } + } + for (const declaration of this._declarations) { + const item: Item = { node: declaration.node, declaration, rank: [2, declaration.index], group: 'declaration', dependencies: [] }; + if (owners.get(declaration.node) === declaration) { + emitters.set(declaration.node, item); + } + items.push(item); + } + for (const item of items) { + const emits = emitters.get(item.node) === item; + item.dependencies = (emits ? this.references(item.node, declared) : [item.node]).map((node) => emitters.get(node)!); + } + + // Emit in rank order, holding each item until the items it references are emitted. + const emitted = new Set<Item>(); + let text = ''; + let previous: { group: string; multiline: boolean } | undefined; + while (emitted.size < items.length) { + let next: Item | undefined; + for (const item of items) { + if ( + !emitted.has(item) && + item.dependencies.every((dependency) => emitted.has(dependency)) && + (!next || compareRank(item.rank, next.rank) < 0) + ) { + next = item; + } + } + if (!next) { + throw new Error('Declarations reference each other circularly.'); + } + emitted.add(next); + const code = next.declaration ? this.renderDeclaration(next.declaration, owners) : this.renderConstant(next.node); + const multiline = code.includes('\n'); + if (previous) { + text += multiline || previous.multiline || previous.group !== next.group ? '\n\n' : '\n'; + } + text += code; + previous = { group: next.group, multiline }; + } + return text ? `${text}\n` : ''; + } + + /** Declared values that the emitted form of a value references. */ + private references(node: ValueNode, declared: ReadonlySet<ValueNode>): ValueNode[] { + const found = new Set<ValueNode>(); + const visit = (current: ValueNode) => { + for (const child of children(current)) { + if (declared.has(child)) { + found.add(child); + } else { + visit(child); + } + } + }; + visit(node); + return [...found]; + } + + private renderConstant(node: ValueNode): string { + const prefix = `const ${this._names.get(node)} = `; + const suffix = this._constAssertions && (node.kind === 'array' || node.kind === 'object') ? ' as const' : ''; + return `${prefix}${this.format(node, 0, prefix.length, suffix.length + 1, Boolean(node.ancestor), node)}${suffix};`; + } + + private renderDeclaration(declaration: Declaration, owners: ReadonlyMap<ValueNode, Declaration>): string { + const { name, node, options } = declaration; + const prefix = `${options.exported === false ? '' : 'export '}const ${name}${options.type ? `: ${options.type}` : ''} = `; + const suffix = options.satisfies ? ` satisfies ${options.satisfies}` : ''; + const value = + owners.get(node) === declaration ? this.format(node, 0, prefix.length, suffix.length + 1, true, node) : this._names.get(node); + const comment = options.comment ? `${writeDocComment(options.comment)}\n` : ''; + return `${comment}${prefix}${value}${suffix};`; + } + + /** + * Format a value that starts at `column` and is followed by `trailing` characters. Arrays and objects stay on one line + * when they fit, unless `multiline` is set. `self` is the value being declared, which is expanded rather than named. + */ + private format(node: ValueNode, depth: number, column: number, trailing: number, multiline: boolean, self?: ValueNode): string { + const inline = this.inline(node, self); + const parts = this.parts(node, self); + if (!parts || parts.length === 0 || (!multiline && column + inline.length + trailing <= this._printWidth)) { + return inline; + } + const indent = ' '.repeat(depth + 1); + const lines = parts.map(([key, value]) => { + if (!value) { + return `${indent}${key},`; + } + const prefix = key === undefined ? indent : `${indent}${propertyKey(key)}: `; + return `${prefix}${this.format(value, depth + 1, prefix.length, 1, false)},`; + }); + const [open, close] = node.kind === 'array' ? ['[', ']'] : ['{', '}']; + return `${open}\n${lines.join('\n')}\n${' '.repeat(depth)}${close}`; + } + + private inline(node: ValueNode, self?: ValueNode): string { + const parts = this.parts(node, self); + if (!parts) { + return node !== self && this._names.has(node) + ? this._names.get(node)! + : node.expression + ? expressionCode(node.expression) + : literalCode(node.literal); + } + const text = parts.map(([key, value]) => { + const code = value ? this.inline(value) : ''; + return key === undefined ? code : value ? `${propertyKey(key)}: ${code}` : key; + }); + if (node.kind === 'array') { + return `[${text.join(', ')}]`; + } + return text.length > 0 ? `{ ${text.join(', ')} }` : '{}'; + } + + /** + * The parts of an array or object to emit, or undefined for a reference or a scalar. A part with a key and no value + * is a spread or shorthand property, emitted as the key. + */ + private parts(node: ValueNode, self?: ValueNode): [key: string | undefined, value: ValueNode | undefined][] | undefined { + if ((node !== self && this._names.has(node)) || (node.kind !== 'array' && node.kind !== 'object')) { + return undefined; + } + if (node.kind === 'array') { + return node.items!.map((item) => [undefined, item]); + } + const spreads = (node.spreads ?? []).map((spread): [string, undefined] => [`...${this._names.get(spread)}`, undefined]); + const entries = (node.spreads ? node.own! : node.entries!).map(([key, value]): [string, ValueNode | undefined] => + this._names.get(value) === key ? [key, undefined] : [key, value], + ); + return [...spreads, ...entries]; + } +} + +function children(node: ValueNode): readonly ValueNode[] { + if (node.kind === 'array') { + return node.items!; + } + if (node.kind !== 'object') { + return []; + } + return [...(node.spreads ?? []), ...(node.spreads ? node.own! : node.entries!).map(([, value]) => value)]; +} diff --git a/scripts/src/index.ts b/scripts/src/index.ts index 086ce68e4e5..7a3bb9a8752 100644 --- a/scripts/src/index.ts +++ b/scripts/src/index.ts @@ -7,3 +7,8 @@ export type { Constants, ConstValue, CodegenTargetFile, ReExports } from './code export { jsonToCodegenTargetFile, processPlatformJsonFiles } from './codegen/json.ts'; export { writeConstExports, writeExportConst } from './codegen/constants.ts'; export { outputCodegenFile } from './codegen/genFile.ts'; +export { makeComment, GeneratedFile, serialize } from './codegen/file.ts'; +export type { Chunk, Output, Comment } from './codegen/file.ts'; +export { Ramp } from './codegen/content.ts'; +export { CodeExpression, expression, ValuePool } from './codegen/valuePool.ts'; +export type { CodeValue, DeclarationOptions, ExpressionOptions, ValuePath, ValuePoolOptions } from './codegen/valuePool.ts'; diff --git a/yarn.lock b/yarn.lock index 94e1a01dd35..024de760153 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2966,7 +2966,6 @@ __metadata: dependencies: "@babel/core": "catalog:" "@fluentui-react-native/design": "workspace:*" - "@fluentui-react-native/framework-base": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@office-iss/react-native-win32": "npm:^0.81.8" "@react-native-community/cli": "npm:^20.0.0" @@ -2975,7 +2974,6 @@ __metadata: "@react-native/babel-preset": "npm:^0.81.0" "@react-native/metro-config": "npm:^0.81.0" "@types/react": "npm:~19.1.4" - assert-never: "npm:^1.2.1" react: "npm:19.1.4" react-native: "npm:^0.81.6" react-native-macos: "npm:^0.81.0"