@oxyhq/bloom 0.35.8 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.js +148 -0
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js +166 -0
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/index.js +13 -0
- package/lib/commonjs/frosted-icon-button/index.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/index.web.js +13 -0
- package/lib/commonjs/frosted-icon-button/index.web.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/shared.js +112 -0
- package/lib/commonjs/frosted-icon-button/shared.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/types.js +6 -0
- package/lib/commonjs/frosted-icon-button/types.js.map +1 -0
- package/lib/commonjs/index.js +10 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +46 -37
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/theme/build-theme.js +31 -43
- package/lib/commonjs/theme/build-theme.js.map +1 -1
- package/lib/commonjs/theme/color-engine/cam16.js +161 -0
- package/lib/commonjs/theme/color-engine/cam16.js.map +1 -0
- package/lib/commonjs/theme/color-engine/color-role.js +183 -0
- package/lib/commonjs/theme/color-engine/color-role.js.map +1 -0
- package/lib/commonjs/theme/color-engine/color-roles.js +416 -0
- package/lib/commonjs/theme/color-engine/color-roles.js.map +1 -0
- package/lib/commonjs/theme/color-engine/color-utils.js +157 -0
- package/lib/commonjs/theme/color-engine/color-utils.js.map +1 -0
- package/lib/commonjs/theme/color-engine/contrast-curve.js +32 -0
- package/lib/commonjs/theme/color-engine/contrast-curve.js.map +1 -0
- package/lib/commonjs/theme/color-engine/contrast.js +70 -0
- package/lib/commonjs/theme/color-engine/contrast.js.map +1 -0
- package/lib/commonjs/theme/color-engine/dislike-analyzer.js +26 -0
- package/lib/commonjs/theme/color-engine/dislike-analyzer.js.map +1 -0
- package/lib/commonjs/theme/color-engine/dynamic-scheme.js +70 -0
- package/lib/commonjs/theme/color-engine/dynamic-scheme.js.map +1 -0
- package/lib/commonjs/theme/color-engine/hct-solver.js +236 -0
- package/lib/commonjs/theme/color-engine/hct-solver.js.map +1 -0
- package/lib/commonjs/theme/color-engine/hct.js +67 -0
- package/lib/commonjs/theme/color-engine/hct.js.map +1 -0
- package/lib/commonjs/theme/color-engine/index.js +173 -0
- package/lib/commonjs/theme/color-engine/index.js.map +1 -0
- package/lib/commonjs/theme/color-engine/lab-point-provider.js +32 -0
- package/lib/commonjs/theme/color-engine/lab-point-provider.js.map +1 -0
- package/lib/commonjs/theme/color-engine/math-utils.js +77 -0
- package/lib/commonjs/theme/color-engine/math-utils.js.map +1 -0
- package/lib/commonjs/theme/color-engine/quantizer-map.js +24 -0
- package/lib/commonjs/theme/color-engine/quantizer-map.js.map +1 -0
- package/lib/commonjs/theme/color-engine/quantizer-wu.js +266 -0
- package/lib/commonjs/theme/color-engine/quantizer-wu.js.map +1 -0
- package/lib/commonjs/theme/color-engine/scheme-variants.js +102 -0
- package/lib/commonjs/theme/color-engine/scheme-variants.js.map +1 -0
- package/lib/commonjs/theme/color-engine/score.js +80 -0
- package/lib/commonjs/theme/color-engine/score.js.map +1 -0
- package/lib/commonjs/theme/color-engine/seed-from-image.js +73 -0
- package/lib/commonjs/theme/color-engine/seed-from-image.js.map +1 -0
- package/lib/commonjs/theme/color-engine/tonal-palette.js +95 -0
- package/lib/commonjs/theme/color-engine/tonal-palette.js.map +1 -0
- package/lib/commonjs/theme/color-engine/tone-delta-pair.js +26 -0
- package/lib/commonjs/theme/color-engine/tone-delta-pair.js.map +1 -0
- package/lib/commonjs/theme/color-engine/variant.js +26 -0
- package/lib/commonjs/theme/color-engine/variant.js.map +1 -0
- package/lib/commonjs/theme/color-engine/viewing-conditions.js +61 -0
- package/lib/commonjs/theme/color-engine/viewing-conditions.js.map +1 -0
- package/lib/commonjs/theme/color-presets.js +44 -572
- package/lib/commonjs/theme/color-presets.js.map +1 -1
- package/lib/commonjs/theme/preset-vars.js +64 -47
- package/lib/commonjs/theme/preset-vars.js.map +1 -1
- package/lib/module/frosted-icon-button/FrostedIconButton.js +143 -0
- package/lib/module/frosted-icon-button/FrostedIconButton.js.map +1 -0
- package/lib/module/frosted-icon-button/FrostedIconButton.web.js +161 -0
- package/lib/module/frosted-icon-button/FrostedIconButton.web.js.map +1 -0
- package/lib/module/frosted-icon-button/index.js +4 -0
- package/lib/module/frosted-icon-button/index.js.map +1 -0
- package/lib/module/frosted-icon-button/index.web.js +11 -0
- package/lib/module/frosted-icon-button/index.web.js.map +1 -0
- package/lib/module/frosted-icon-button/shared.js +107 -0
- package/lib/module/frosted-icon-button/shared.js.map +1 -0
- package/lib/module/frosted-icon-button/types.js +4 -0
- package/lib/module/frosted-icon-button/types.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/theme/build-theme.js +32 -44
- package/lib/module/theme/build-theme.js.map +1 -1
- package/lib/module/theme/color-engine/cam16.js +155 -0
- package/lib/module/theme/color-engine/cam16.js.map +1 -0
- package/lib/module/theme/color-engine/color-role.js +177 -0
- package/lib/module/theme/color-engine/color-role.js.map +1 -0
- package/lib/module/theme/color-engine/color-roles.js +411 -0
- package/lib/module/theme/color-engine/color-roles.js.map +1 -0
- package/lib/module/theme/color-engine/color-utils.js +135 -0
- package/lib/module/theme/color-engine/color-utils.js.map +1 -0
- package/lib/module/theme/color-engine/contrast-curve.js +26 -0
- package/lib/module/theme/color-engine/contrast-curve.js.map +1 -0
- package/lib/module/theme/color-engine/contrast.js +61 -0
- package/lib/module/theme/color-engine/contrast.js.map +1 -0
- package/lib/module/theme/color-engine/dislike-analyzer.js +20 -0
- package/lib/module/theme/color-engine/dislike-analyzer.js.map +1 -0
- package/lib/module/theme/color-engine/dynamic-scheme.js +65 -0
- package/lib/module/theme/color-engine/dynamic-scheme.js.map +1 -0
- package/lib/module/theme/color-engine/hct-solver.js +231 -0
- package/lib/module/theme/color-engine/hct-solver.js.map +1 -0
- package/lib/module/theme/color-engine/hct.js +61 -0
- package/lib/module/theme/color-engine/hct.js.map +1 -0
- package/lib/module/theme/color-engine/index.js +57 -0
- package/lib/module/theme/color-engine/index.js.map +1 -0
- package/lib/module/theme/color-engine/lab-point-provider.js +25 -0
- package/lib/module/theme/color-engine/lab-point-provider.js.map +1 -0
- package/lib/module/theme/color-engine/math-utils.js +65 -0
- package/lib/module/theme/color-engine/math-utils.js.map +1 -0
- package/lib/module/theme/color-engine/quantizer-map.js +20 -0
- package/lib/module/theme/color-engine/quantizer-map.js.map +1 -0
- package/lib/module/theme/color-engine/quantizer-wu.js +261 -0
- package/lib/module/theme/color-engine/quantizer-wu.js.map +1 -0
- package/lib/module/theme/color-engine/scheme-variants.js +93 -0
- package/lib/module/theme/color-engine/scheme-variants.js.map +1 -0
- package/lib/module/theme/color-engine/score.js +75 -0
- package/lib/module/theme/color-engine/score.js.map +1 -0
- package/lib/module/theme/color-engine/seed-from-image.js +67 -0
- package/lib/module/theme/color-engine/seed-from-image.js.map +1 -0
- package/lib/module/theme/color-engine/tonal-palette.js +89 -0
- package/lib/module/theme/color-engine/tonal-palette.js.map +1 -0
- package/lib/module/theme/color-engine/tone-delta-pair.js +21 -0
- package/lib/module/theme/color-engine/tone-delta-pair.js.map +1 -0
- package/lib/module/theme/color-engine/variant.js +22 -0
- package/lib/module/theme/color-engine/variant.js.map +1 -0
- package/lib/module/theme/color-engine/viewing-conditions.js +55 -0
- package/lib/module/theme/color-engine/viewing-conditions.js.map +1 -0
- package/lib/module/theme/color-presets.js +44 -572
- package/lib/module/theme/color-presets.js.map +1 -1
- package/lib/module/theme/preset-vars.js +64 -46
- package/lib/module/theme/preset-vars.js.map +1 -1
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.d.ts +5 -0
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts +5 -0
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.d.ts +3 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts +3 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts +60 -0
- package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/types.d.ts +69 -0
- package/lib/typescript/commonjs/frosted-icon-button/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +2 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts +26 -0
- package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts +36 -0
- package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts +58 -0
- package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts +32 -0
- package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts +9 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts +12 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts +11 -0
- package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts +47 -0
- package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts +6 -0
- package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/hct.d.ts +20 -0
- package/lib/typescript/commonjs/theme/color-engine/hct.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/index.d.ts +44 -0
- package/lib/typescript/commonjs/theme/color-engine/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts +6 -0
- package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts +46 -0
- package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts +3 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts +3 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts +23 -0
- package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/score.d.ts +8 -0
- package/lib/typescript/commonjs/theme/color-engine/score.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts +13 -0
- package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts +24 -0
- package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts +19 -0
- package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/variant.d.ts +19 -0
- package/lib/typescript/commonjs/theme/color-engine/variant.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts +18 -0
- package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-presets.d.ts +25 -20
- package/lib/typescript/commonjs/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/preset-vars.d.ts +16 -12
- package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.d.ts +5 -0
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts +5 -0
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/index.d.ts +3 -0
- package/lib/typescript/module/frosted-icon-button/index.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/index.web.d.ts +3 -0
- package/lib/typescript/module/frosted-icon-button/index.web.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/shared.d.ts +60 -0
- package/lib/typescript/module/frosted-icon-button/shared.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/types.d.ts +69 -0
- package/lib/typescript/module/frosted-icon-button/types.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +2 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-engine/cam16.d.ts +26 -0
- package/lib/typescript/module/theme/color-engine/cam16.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/color-role.d.ts +36 -0
- package/lib/typescript/module/theme/color-engine/color-role.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/color-roles.d.ts +58 -0
- package/lib/typescript/module/theme/color-engine/color-roles.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/color-utils.d.ts +32 -0
- package/lib/typescript/module/theme/color-engine/color-utils.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts +9 -0
- package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/contrast.d.ts +12 -0
- package/lib/typescript/module/theme/color-engine/contrast.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts +11 -0
- package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts +47 -0
- package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/hct-solver.d.ts +6 -0
- package/lib/typescript/module/theme/color-engine/hct-solver.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/hct.d.ts +20 -0
- package/lib/typescript/module/theme/color-engine/hct.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/index.d.ts +44 -0
- package/lib/typescript/module/theme/color-engine/index.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts +6 -0
- package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/math-utils.d.ts +46 -0
- package/lib/typescript/module/theme/color-engine/math-utils.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts +3 -0
- package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts +3 -0
- package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts +23 -0
- package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/score.d.ts +8 -0
- package/lib/typescript/module/theme/color-engine/score.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts +13 -0
- package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts +24 -0
- package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts +19 -0
- package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/variant.d.ts +19 -0
- package/lib/typescript/module/theme/color-engine/variant.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts +18 -0
- package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-presets.d.ts +25 -20
- package/lib/typescript/module/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/module/theme/preset-vars.d.ts +16 -12
- package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
- package/package.json +17 -1
- package/src/__tests__/BloomThemeProvider.test.tsx +9 -4
- package/src/__tests__/FrostedIconButton.test.tsx +137 -0
- package/src/__tests__/FrostedIconButton.web.test.tsx +246 -0
- package/src/__tests__/native-root-vars.test.ts +8 -4
- package/src/__tests__/preset-vars.test.ts +66 -37
- package/src/__tests__/theme.test.ts +20 -12
- package/src/frosted-icon-button/FrostedIconButton.stories.tsx +65 -0
- package/src/frosted-icon-button/FrostedIconButton.tsx +156 -0
- package/src/frosted-icon-button/FrostedIconButton.web.tsx +207 -0
- package/src/frosted-icon-button/index.ts +2 -0
- package/src/frosted-icon-button/index.web.ts +9 -0
- package/src/frosted-icon-button/shared.ts +118 -0
- package/src/frosted-icon-button/types.ts +81 -0
- package/src/index.ts +2 -0
- package/src/index.web.ts +2 -0
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +509 -509
- package/src/theme/__tests__/__snapshots__/visual-gallery.test.tsx.snap +613 -613
- package/src/theme/__tests__/color-engine-golden.test.ts +81 -0
- package/src/theme/__tests__/fixtures/color-engine-golden.json +1 -0
- package/src/theme/__tests__/golden-tokens.test.ts +6 -7
- package/src/theme/__tests__/runtime-contract.test.ts +8 -8
- package/src/theme/__tests__/theme-colors-parity.test.ts +44 -88
- package/src/theme/build-theme.ts +32 -44
- package/src/theme/color-engine/cam16.ts +179 -0
- package/src/theme/color-engine/color-role.ts +217 -0
- package/src/theme/color-engine/color-roles.ts +435 -0
- package/src/theme/color-engine/color-utils.ts +157 -0
- package/src/theme/color-engine/contrast-curve.ts +25 -0
- package/src/theme/color-engine/contrast.ts +59 -0
- package/src/theme/color-engine/dislike-analyzer.ts +19 -0
- package/src/theme/color-engine/dynamic-scheme.ts +90 -0
- package/src/theme/color-engine/hct-solver.ts +263 -0
- package/src/theme/color-engine/hct.ts +69 -0
- package/src/theme/color-engine/index.ts +73 -0
- package/src/theme/color-engine/lab-point-provider.ts +26 -0
- package/src/theme/color-engine/math-utils.ts +69 -0
- package/src/theme/color-engine/quantizer-map.ts +17 -0
- package/src/theme/color-engine/quantizer-wu.ts +320 -0
- package/src/theme/color-engine/scheme-variants.ts +113 -0
- package/src/theme/color-engine/score.ts +82 -0
- package/src/theme/color-engine/seed-from-image.ts +64 -0
- package/src/theme/color-engine/tonal-palette.ts +94 -0
- package/src/theme/color-engine/tone-delta-pair.ts +21 -0
- package/src/theme/color-engine/variant.ts +18 -0
- package/src/theme/color-engine/viewing-conditions.ts +77 -0
- package/src/theme/color-presets.ts +54 -631
- package/src/theme/preset-vars.ts +65 -49
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Golden parity test for the Bloom colour engine.
|
|
3
|
+
*
|
|
4
|
+
* The engine is a dependency-free reimplementation of the Material Color
|
|
5
|
+
* Utilities algorithm. These fixtures were generated ONCE from the reference
|
|
6
|
+
* library and frozen; this test asserts Bloom's engine reproduces every role,
|
|
7
|
+
* for 5 seeds × 4 variants × light/dark, byte-for-byte. If the engine ever
|
|
8
|
+
* drifts from the reference algorithm, this fails — no runtime dependency on the
|
|
9
|
+
* reference is needed to keep the port honest.
|
|
10
|
+
*/
|
|
11
|
+
import golden from './fixtures/color-engine-golden.json';
|
|
12
|
+
import {
|
|
13
|
+
argbFromHex,
|
|
14
|
+
generateRoleColors,
|
|
15
|
+
seedHexFromImagePixels,
|
|
16
|
+
type RoleName,
|
|
17
|
+
type SchemeVariant,
|
|
18
|
+
} from '../color-engine';
|
|
19
|
+
|
|
20
|
+
const SEED_HEX: Record<string, string> = {
|
|
21
|
+
oxy: '#C46EDE',
|
|
22
|
+
blue: '#1D9BF0',
|
|
23
|
+
green: '#10B981',
|
|
24
|
+
pink: '#EC4899',
|
|
25
|
+
faircoin: '#9FFB50',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** `rgb(r g b)` (the engine's output form) → `#rrggbb` (the fixture form). */
|
|
29
|
+
function rgbToHex(rgb: string): string {
|
|
30
|
+
const match = rgb.match(/rgb\((\d+) (\d+) (\d+)\)/);
|
|
31
|
+
if (!match) {
|
|
32
|
+
throw new Error(`Expected an "rgb(r g b)" string, got: ${rgb}`);
|
|
33
|
+
}
|
|
34
|
+
return `#${[1, 2, 3].map((i) => Number(match[i]).toString(16).padStart(2, '0')).join('')}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const fixtures = golden as Record<string, Record<string, string>>;
|
|
38
|
+
|
|
39
|
+
describe('Bloom colour engine — golden parity with Material Color Utilities', () => {
|
|
40
|
+
for (const [combo, roles] of Object.entries(fixtures)) {
|
|
41
|
+
it(`reproduces every role for ${combo}`, () => {
|
|
42
|
+
const [seed, variant, mode] = combo.split('|');
|
|
43
|
+
if (seed === undefined || variant === undefined || mode === undefined) {
|
|
44
|
+
throw new Error(`malformed golden combo: ${combo}`);
|
|
45
|
+
}
|
|
46
|
+
const seedHex = SEED_HEX[seed];
|
|
47
|
+
if (seedHex === undefined) throw new Error(`no seed hex for preset "${seed}"`);
|
|
48
|
+
const generated = generateRoleColors({
|
|
49
|
+
seed: seedHex,
|
|
50
|
+
variant: variant as SchemeVariant,
|
|
51
|
+
isDark: mode === 'dark',
|
|
52
|
+
});
|
|
53
|
+
for (const [role, expectedHex] of Object.entries(roles)) {
|
|
54
|
+
expect(rgbToHex(generated[role as RoleName])).toBe(expectedHex);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/** Build a flat ARGB pixel array from `[hex, count]` pairs. */
|
|
61
|
+
function image(colors: Array<[string, number]>): number[] {
|
|
62
|
+
const pixels: number[] = [];
|
|
63
|
+
for (const [hex, count] of colors) {
|
|
64
|
+
const argb = argbFromHex(hex);
|
|
65
|
+
for (let i = 0; i < count; i++) pixels.push(argb);
|
|
66
|
+
}
|
|
67
|
+
return pixels;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
describe('seed extraction from an image (deterministic)', () => {
|
|
71
|
+
const cases: Array<[string, Array<[string, number]>, string]> = [
|
|
72
|
+
['a purple-dominant photo', [['#C46EDE', 900], ['#1D9BF0', 80], ['#ffffff', 400], ['#101014', 300]], '#c46ede'],
|
|
73
|
+
['a pink/green photo', [['#EC6094', 600], ['#10B981', 500], ['#F59E0B', 200], ['#000000', 700]], '#ec6094'],
|
|
74
|
+
['a teal photo', [['#005c67', 1000], ['#14b8a6', 300], ['#eeeeee', 600]], '#005c67'],
|
|
75
|
+
];
|
|
76
|
+
for (const [label, colors, expectedSeed] of cases) {
|
|
77
|
+
it(`picks the dominant chromatic colour from ${label}`, () => {
|
|
78
|
+
expect(seedHexFromImagePixels(image(colors))).toBe(expectedSeed);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"oxy|vibrant|light":{"background":"#fff7fb","onBackground":"#211922","surface":"#fff7fb","surfaceDim":"#e4d6e3","surfaceBright":"#fff7fb","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#ffeffd","surfaceContainer":"#f9e9f7","surfaceContainerHigh":"#f3e4f1","surfaceContainerHighest":"#eddeeb","onSurface":"#211922","surfaceVariant":"#efddee","onSurfaceVariant":"#4f4350","inverseSurface":"#362d37","inverseOnSurface":"#fcecfa","outline":"#817381","outlineVariant":"#d2c1d2","shadow":"#000000","scrim":"#000000","surfaceTint":"#9c00c8","primary":"#9c00c8","onPrimary":"#ffffff","primaryContainer":"#fbd7ff","onPrimaryContainer":"#77009a","inversePrimary":"#f0b0ff","secondary":"#75546f","onSecondary":"#ffffff","secondaryContainer":"#ffd7f5","onSecondaryContainer":"#5b3d57","tertiary":"#834e6b","onTertiary":"#ffffff","tertiaryContainer":"#ffd8ea","onTertiaryContainer":"#683653","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"oxy|vibrant|dark":{"background":"#18111a","onBackground":"#eddeeb","surface":"#18111a","surfaceDim":"#18111a","surfaceBright":"#3f3640","surfaceContainerLowest":"#130c14","surfaceContainerLow":"#211922","surfaceContainer":"#251d26","surfaceContainerHigh":"#302731","surfaceContainerHighest":"#3b323c","onSurface":"#eddeeb","surfaceVariant":"#4f4350","onSurfaceVariant":"#d2c1d2","inverseSurface":"#eddeeb","inverseOnSurface":"#362d37","outline":"#9b8c9b","outlineVariant":"#4f4350","shadow":"#000000","scrim":"#000000","surfaceTint":"#f0b0ff","primary":"#f0b0ff","onPrimary":"#54006d","primaryContainer":"#77009a","onPrimaryContainer":"#fbd7ff","inversePrimary":"#9c00c8","secondary":"#e3bada","onSecondary":"#43273f","secondaryContainer":"#5b3d57","onSecondaryContainer":"#ffd7f5","tertiary":"#f6b3d5","onTertiary":"#4e203c","tertiaryContainer":"#683653","onTertiaryContainer":"#ffd8ea","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"oxy|expressive|light":{"background":"#fff7f9","onBackground":"#22191f","surface":"#fff7f9","surfaceDim":"#e6d6de","surfaceBright":"#fff7f9","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#fff0f7","surfaceContainer":"#fae9f2","surfaceContainerHigh":"#f4e4ec","surfaceContainerHighest":"#eedee7","onSurface":"#22191f","surfaceVariant":"#f3dcea","onSurfaceVariant":"#52424d","inverseSurface":"#372e34","inverseOnSurface":"#fdecf5","outline":"#84727e","outlineVariant":"#d6c0ce","shadow":"#000000","scrim":"#000000","surfaceTint":"#00696f","primary":"#00696f","onPrimary":"#ffffff","primaryContainer":"#90f2f9","onPrimaryContainer":"#004f53","inversePrimary":"#72d6dd","secondary":"#805159","onSecondary":"#ffffff","secondaryContainer":"#ffd9de","onSecondaryContainer":"#653b42","tertiary":"#775a1a","onTertiary":"#ffffff","tertiaryContainer":"#ffdea5","onTertiaryContainer":"#5d4202","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"oxy|expressive|dark":{"background":"#191117","onBackground":"#eedee7","surface":"#191117","surfaceDim":"#191117","surfaceBright":"#40363d","surfaceContainerLowest":"#130c11","surfaceContainerLow":"#22191f","surfaceContainer":"#261d23","surfaceContainerHigh":"#31272e","surfaceContainerHighest":"#3c3238","onSurface":"#eedee7","surfaceVariant":"#52424d","onSurfaceVariant":"#d6c0ce","inverseSurface":"#eedee7","inverseOnSurface":"#372e34","outline":"#9f8b98","outlineVariant":"#52424d","shadow":"#000000","scrim":"#000000","surfaceTint":"#72d6dd","primary":"#72d6dd","onPrimary":"#00373a","primaryContainer":"#004f53","onPrimaryContainer":"#90f2f9","inversePrimary":"#00696f","secondary":"#f2b7c0","onSecondary":"#4b252c","secondaryContainer":"#653b42","onSecondaryContainer":"#ffd9de","tertiary":"#e9c177","onTertiary":"#412d00","tertiaryContainer":"#5d4202","onTertiaryContainer":"#ffdea5","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"oxy|tonalSpot|light":{"background":"#fff7fb","onBackground":"#1f1a1f","surface":"#fff7fb","surfaceDim":"#e1d7de","surfaceBright":"#fff7fb","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#fbf1f8","surfaceContainer":"#f5ebf2","surfaceContainerHigh":"#f0e5ed","surfaceContainerHighest":"#eae0e7","onSurface":"#1f1a1f","surfaceVariant":"#ebdfe9","onSurfaceVariant":"#4c444c","inverseSurface":"#342f34","inverseOnSurface":"#f8eef5","outline":"#7e747d","outlineVariant":"#cfc3cd","shadow":"#000000","scrim":"#000000","surfaceTint":"#784f83","primary":"#784f83","onPrimary":"#ffffff","primaryContainer":"#fbd7ff","onPrimaryContainer":"#5e3869","inversePrimary":"#e7b6f1","secondary":"#6a596c","onSecondary":"#ffffff","secondaryContainer":"#f2dcf3","onSecondaryContainer":"#514154","tertiary":"#82524e","onTertiary":"#ffffff","tertiaryContainer":"#ffdad7","onTertiaryContainer":"#663b37","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"oxy|tonalSpot|dark":{"background":"#161217","onBackground":"#eae0e7","surface":"#161217","surfaceDim":"#161217","surfaceBright":"#3d373d","surfaceContainerLowest":"#110d12","surfaceContainerLow":"#1f1a1f","surfaceContainer":"#231e23","surfaceContainerHigh":"#2e282e","surfaceContainerHighest":"#393339","onSurface":"#eae0e7","surfaceVariant":"#4c444c","onSurfaceVariant":"#cfc3cd","inverseSurface":"#eae0e7","inverseOnSurface":"#342f34","outline":"#988e97","outlineVariant":"#4c444c","shadow":"#000000","scrim":"#000000","surfaceTint":"#e7b6f1","primary":"#e7b6f1","onPrimary":"#462151","primaryContainer":"#5e3869","onPrimaryContainer":"#fbd7ff","inversePrimary":"#784f83","secondary":"#d5c0d6","onSecondary":"#3a2b3d","secondaryContainer":"#514154","onSecondaryContainer":"#f2dcf3","tertiary":"#f5b7b2","onTertiary":"#4c2522","tertiaryContainer":"#663b37","onTertiaryContainer":"#ffdad7","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"oxy|neutral|light":{"background":"#fef8f9","onBackground":"#1d1b1c","surface":"#fef8f9","surfaceDim":"#ded9da","surfaceBright":"#fef8f9","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f8f2f4","surfaceContainer":"#f2ecee","surfaceContainerHigh":"#ede7e8","surfaceContainerHighest":"#e7e1e3","onSurface":"#1d1b1c","surfaceVariant":"#e7e1e3","onSurfaceVariant":"#494647","inverseSurface":"#323031","inverseOnSurface":"#f5eff1","outline":"#7a7678","outlineVariant":"#cac5c7","shadow":"#000000","scrim":"#000000","surfaceTint":"#675a68","primary":"#675a68","onPrimary":"#ffffff","primaryContainer":"#efddee","onPrimaryContainer":"#4f4350","inversePrimary":"#d2c1d2","secondary":"#645c64","onSecondary":"#ffffff","secondaryContainer":"#ebdfe9","onSecondaryContainer":"#4c444c","tertiary":"#6a596c","onTertiary":"#ffffff","tertiaryContainer":"#f2dcf3","onTertiaryContainer":"#514154","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"oxy|neutral|dark":{"background":"#151314","onBackground":"#e7e1e3","surface":"#151314","surfaceDim":"#151314","surfaceBright":"#3b383a","surfaceContainerLowest":"#0f0e0f","surfaceContainerLow":"#1d1b1c","surfaceContainer":"#211f20","surfaceContainerHigh":"#2b292b","surfaceContainerHighest":"#363435","onSurface":"#e7e1e3","surfaceVariant":"#494647","onSurfaceVariant":"#cac5c7","inverseSurface":"#e7e1e3","inverseOnSurface":"#323031","outline":"#949091","outlineVariant":"#494647","shadow":"#000000","scrim":"#000000","surfaceTint":"#d2c1d2","primary":"#d2c1d2","onPrimary":"#382d39","primaryContainer":"#4f4350","onPrimaryContainer":"#efddee","inversePrimary":"#675a68","secondary":"#cfc3cd","onSecondary":"#352e36","secondaryContainer":"#4c444c","onSecondaryContainer":"#ebdfe9","tertiary":"#d5c0d6","onTertiary":"#3a2b3d","tertiaryContainer":"#514154","onTertiaryContainer":"#f2dcf3","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"blue|vibrant|light":{"background":"#f7f9ff","onBackground":"#151c24","surface":"#f7f9ff","surfaceDim":"#d4dae5","surfaceBright":"#f7f9ff","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#edf4ff","surfaceContainer":"#e8eef9","surfaceContainerHigh":"#e2e9f4","surfaceContainerHighest":"#dce3ee","onSurface":"#151c24","surfaceVariant":"#dae3f1","onSurfaceVariant":"#3e4852","inverseSurface":"#2a3139","inverseOnSurface":"#eaf1fc","outline":"#6f7884","outlineVariant":"#bec7d4","shadow":"#000000","scrim":"#000000","surfaceTint":"#00629d","primary":"#00629d","onPrimary":"#ffffff","primaryContainer":"#cfe5ff","onPrimaryContainer":"#004a78","inversePrimary":"#99cbff","secondary":"#515e7d","onSecondary":"#ffffff","secondaryContainer":"#d9e2ff","onSecondaryContainer":"#3a4664","tertiary":"#595a8b","onTertiary":"#ffffff","tertiaryContainer":"#e1e0ff","onTertiaryContainer":"#414271","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"blue|vibrant|dark":{"background":"#0d141b","onBackground":"#dce3ee","surface":"#0d141b","surfaceDim":"#0d141b","surfaceBright":"#333a42","surfaceContainerLowest":"#080f16","surfaceContainerLow":"#151c24","surfaceContainer":"#192028","surfaceContainerHigh":"#242b33","surfaceContainerHighest":"#2e353e","onSurface":"#dce3ee","surfaceVariant":"#3e4852","onSurfaceVariant":"#bec7d4","inverseSurface":"#dce3ee","inverseOnSurface":"#2a3139","outline":"#88929e","outlineVariant":"#3e4852","shadow":"#000000","scrim":"#000000","surfaceTint":"#99cbff","primary":"#99cbff","onPrimary":"#003354","primaryContainer":"#004a78","onPrimaryContainer":"#cfe5ff","inversePrimary":"#00629d","secondary":"#b9c6ea","onSecondary":"#23304d","secondaryContainer":"#3a4664","onSecondaryContainer":"#d9e2ff","tertiary":"#c1c2f9","onTertiary":"#2a2b59","tertiaryContainer":"#414271","onTertiaryContainer":"#e1e0ff","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"blue|expressive|light":{"background":"#f9f9ff","onBackground":"#191c22","surface":"#f9f9ff","surfaceDim":"#d8d9e3","surfaceBright":"#f9f9ff","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f2f3fd","surfaceContainer":"#ecedf7","surfaceContainerHigh":"#e6e8f2","surfaceContainerHighest":"#e0e2ec","onSurface":"#191c22","surfaceVariant":"#dee2f2","onSurfaceVariant":"#414753","inverseSurface":"#2d3038","inverseOnSurface":"#eff0fa","outline":"#727785","outlineVariant":"#c1c6d6","shadow":"#000000","scrim":"#000000","surfaceTint":"#4c6722","primary":"#4c6722","onPrimary":"#ffffff","primaryContainer":"#cdee99","onPrimaryContainer":"#354e0b","inversePrimary":"#b1d180","secondary":"#77536c","onSecondary":"#ffffff","secondaryContainer":"#ffd7f0","onSecondaryContainer":"#5d3c54","tertiary":"#475e8a","onTertiary":"#ffffff","tertiaryContainer":"#d7e2ff","onTertiaryContainer":"#2f4671","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"blue|expressive|dark":{"background":"#10131a","onBackground":"#e0e2ec","surface":"#10131a","surfaceDim":"#10131a","surfaceBright":"#363941","surfaceContainerLowest":"#0b0e15","surfaceContainerLow":"#191c22","surfaceContainer":"#1d2027","surfaceContainerHigh":"#272a31","surfaceContainerHighest":"#32353c","onSurface":"#e0e2ec","surfaceVariant":"#414753","onSurfaceVariant":"#c1c6d6","inverseSurface":"#e0e2ec","inverseOnSurface":"#2d3038","outline":"#8b909f","outlineVariant":"#414753","shadow":"#000000","scrim":"#000000","surfaceTint":"#b1d180","primary":"#b1d180","onPrimary":"#213600","primaryContainer":"#354e0b","onPrimaryContainer":"#cdee99","inversePrimary":"#4c6722","secondary":"#e6bad7","onSecondary":"#45263d","secondaryContainer":"#5d3c54","onSecondaryContainer":"#ffd7f0","tertiary":"#b0c7f8","onTertiary":"#173059","tertiaryContainer":"#2f4671","onTertiaryContainer":"#d7e2ff","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"blue|tonalSpot|light":{"background":"#f7f9ff","onBackground":"#181c20","surface":"#f7f9ff","surfaceDim":"#d8dae0","surfaceBright":"#f7f9ff","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f2f3f9","surfaceContainer":"#eceef4","surfaceContainerHigh":"#e6e8ee","surfaceContainerHighest":"#e0e2e8","onSurface":"#181c20","surfaceVariant":"#dee3eb","onSurfaceVariant":"#42474e","inverseSurface":"#2d3135","inverseOnSurface":"#eff1f6","outline":"#72777f","outlineVariant":"#c2c7cf","shadow":"#000000","scrim":"#000000","surfaceTint":"#31628d","primary":"#31628d","onPrimary":"#ffffff","primaryContainer":"#cfe5ff","onPrimaryContainer":"#124a73","inversePrimary":"#9ccbfb","secondary":"#526070","onSecondary":"#ffffff","secondaryContainer":"#d5e4f7","onSecondaryContainer":"#3a4857","tertiary":"#695779","onTertiary":"#ffffff","tertiaryContainer":"#f0dbff","onTertiaryContainer":"#504060","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"blue|tonalSpot|dark":{"background":"#101418","onBackground":"#e0e2e8","surface":"#101418","surfaceDim":"#101418","surfaceBright":"#36393e","surfaceContainerLowest":"#0b0e12","surfaceContainerLow":"#181c20","surfaceContainer":"#1d2024","surfaceContainerHigh":"#272a2f","surfaceContainerHighest":"#32353a","onSurface":"#e0e2e8","surfaceVariant":"#42474e","onSurfaceVariant":"#c2c7cf","inverseSurface":"#e0e2e8","inverseOnSurface":"#2d3135","outline":"#8c9199","outlineVariant":"#42474e","shadow":"#000000","scrim":"#000000","surfaceTint":"#9ccbfb","primary":"#9ccbfb","onPrimary":"#003354","primaryContainer":"#124a73","onPrimaryContainer":"#cfe5ff","inversePrimary":"#31628d","secondary":"#b9c8da","onSecondary":"#243240","secondaryContainer":"#3a4857","onSecondaryContainer":"#d5e4f7","tertiary":"#d4bee6","onTertiary":"#392a49","tertiaryContainer":"#504060","onTertiaryContainer":"#f0dbff","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"blue|neutral|light":{"background":"#fbf9fa","onBackground":"#1b1c1d","surface":"#fbf9fa","surfaceDim":"#dbd9db","surfaceBright":"#fbf9fa","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f5f3f4","surfaceContainer":"#efedee","surfaceContainerHigh":"#eae7e9","surfaceContainerHighest":"#e4e2e3","onSurface":"#1b1c1d","surfaceVariant":"#e4e2e3","onSurfaceVariant":"#474748","inverseSurface":"#303031","inverseOnSurface":"#f2f0f1","outline":"#777778","outlineVariant":"#c8c6c7","shadow":"#000000","scrim":"#000000","surfaceTint":"#565f6b","primary":"#565f6b","onPrimary":"#ffffff","primaryContainer":"#dae3f1","onPrimaryContainer":"#3e4852","inversePrimary":"#bec7d4","secondary":"#5a5f66","onSecondary":"#ffffff","secondaryContainer":"#dee3eb","onSecondaryContainer":"#42474e","tertiary":"#526070","onTertiary":"#ffffff","tertiaryContainer":"#d5e4f7","onTertiaryContainer":"#3a4857","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"blue|neutral|dark":{"background":"#131314","onBackground":"#e4e2e3","surface":"#131314","surfaceDim":"#131314","surfaceBright":"#39393a","surfaceContainerLowest":"#0e0e0f","surfaceContainerLow":"#1b1c1d","surfaceContainer":"#1f2021","surfaceContainerHigh":"#2a2a2b","surfaceContainerHighest":"#343536","onSurface":"#e4e2e3","surfaceVariant":"#474748","onSurfaceVariant":"#c8c6c7","inverseSurface":"#e4e2e3","inverseOnSurface":"#303031","outline":"#919091","outlineVariant":"#474748","shadow":"#000000","scrim":"#000000","surfaceTint":"#bec7d4","primary":"#bec7d4","onPrimary":"#28313b","primaryContainer":"#3e4852","onPrimaryContainer":"#dae3f1","inversePrimary":"#565f6b","secondary":"#c2c7cf","onSecondary":"#2c3137","secondaryContainer":"#42474e","onSecondaryContainer":"#dee3eb","tertiary":"#b9c8da","onTertiary":"#243240","tertiaryContainer":"#3a4857","onTertiaryContainer":"#d5e4f7","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"green|vibrant|light":{"background":"#f0fdf2","onBackground":"#131e18","surface":"#f0fdf2","surfaceDim":"#d0ddd3","surfaceBright":"#f0fdf2","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#eaf7ed","surfaceContainer":"#e4f1e7","surfaceContainerHigh":"#deebe1","surfaceContainerHighest":"#d9e6dc","onSurface":"#131e18","surfaceVariant":"#d6e7db","onSurfaceVariant":"#3b4a41","inverseSurface":"#28332c","inverseOnSurface":"#e7f4ea","outline":"#6b7b71","outlineVariant":"#bacbbf","shadow":"#000000","scrim":"#000000","surfaceTint":"#006c49","primary":"#006c49","onPrimary":"#ffffff","primaryContainer":"#47ffb8","onPrimaryContainer":"#005236","inversePrimary":"#00e29d","secondary":"#3b665c","onSecondary":"#ffffff","secondaryContainer":"#bdecdf","onSecondaryContainer":"#224e45","tertiary":"#1a6967","onTertiary":"#ffffff","tertiaryContainer":"#a8efed","onTertiaryContainer":"#00504e","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"green|vibrant|dark":{"background":"#0b1610","onBackground":"#d9e6dc","surface":"#0b1610","surfaceDim":"#0b1610","surfaceBright":"#303c35","surfaceContainerLowest":"#06100b","surfaceContainerLow":"#131e18","surfaceContainer":"#17221c","surfaceContainerHigh":"#212c26","surfaceContainerHighest":"#2c3731","onSurface":"#d9e6dc","surfaceVariant":"#3b4a41","onSurfaceVariant":"#bacbbf","inverseSurface":"#d9e6dc","inverseOnSurface":"#28332c","outline":"#84958a","outlineVariant":"#3b4a41","shadow":"#000000","scrim":"#000000","surfaceTint":"#00e29d","primary":"#00e29d","onPrimary":"#003824","primaryContainer":"#005236","onPrimaryContainer":"#47ffb8","inversePrimary":"#006c49","secondary":"#a2d0c3","onSecondary":"#05372e","secondaryContainer":"#224e45","onSecondaryContainer":"#bdecdf","tertiary":"#8cd3d0","onTertiary":"#003736","tertiaryContainer":"#00504e","onTertiaryContainer":"#a8efed","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"green|expressive|light":{"background":"#f1fcf7","onBackground":"#141d1b","surface":"#f1fcf7","surfaceDim":"#d2dcd8","surfaceBright":"#f1fcf7","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#ecf6f1","surfaceContainer":"#e6f0ec","surfaceContainerHigh":"#e0eae6","surfaceContainerHighest":"#dbe5e0","onSurface":"#141d1b","surfaceVariant":"#d4e7e0","onSurfaceVariant":"#3a4a45","inverseSurface":"#29322f","inverseOnSurface":"#e9f3ee","outline":"#697b75","outlineVariant":"#b8cbc4","shadow":"#000000","scrim":"#000000","surfaceTint":"#914b26","primary":"#914b26","onPrimary":"#ffffff","primaryContainer":"#ffdbcb","onPrimaryContainer":"#743510","inversePrimary":"#ffb692","secondary":"#39656c","onSecondary":"#ffffff","secondaryContainer":"#bdeaf3","onSecondaryContainer":"#1f4d54","tertiary":"#1e695f","onTertiary":"#ffffff","tertiaryContainer":"#a9f0e3","onTertiaryContainer":"#005048","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"green|expressive|dark":{"background":"#0c1513","onBackground":"#dbe5e0","surface":"#0c1513","surfaceDim":"#0c1513","surfaceBright":"#323b38","surfaceContainerLowest":"#07100e","surfaceContainerLow":"#141d1b","surfaceContainer":"#18211f","surfaceContainerHigh":"#232c29","surfaceContainerHighest":"#2d3734","onSurface":"#dbe5e0","surfaceVariant":"#3a4a45","onSurfaceVariant":"#b8cbc4","inverseSurface":"#dbe5e0","inverseOnSurface":"#29322f","outline":"#83958f","outlineVariant":"#3a4a45","shadow":"#000000","scrim":"#000000","surfaceTint":"#ffb692","primary":"#ffb692","onPrimary":"#562000","primaryContainer":"#743510","onPrimaryContainer":"#ffdbcb","inversePrimary":"#914b26","secondary":"#a1ced6","onSecondary":"#00363d","secondaryContainer":"#1f4d54","onSecondaryContainer":"#bdeaf3","tertiary":"#8dd4c7","onTertiary":"#003731","tertiaryContainer":"#005048","onTertiaryContainer":"#a9f0e3","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"green|tonalSpot|light":{"background":"#f5fbf5","onBackground":"#171d19","surface":"#f5fbf5","surfaceDim":"#d6dbd6","surfaceBright":"#f5fbf5","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f0f5ef","surfaceContainer":"#eaefe9","surfaceContainerHigh":"#e4eae4","surfaceContainerHighest":"#dee4de","onSurface":"#171d19","surfaceVariant":"#dce5dd","onSurfaceVariant":"#404943","inverseSurface":"#2c322e","inverseOnSurface":"#edf2ec","outline":"#707973","outlineVariant":"#c0c9c1","shadow":"#000000","scrim":"#000000","surfaceTint":"#226a4c","primary":"#226a4c","onPrimary":"#ffffff","primaryContainer":"#aaf2cc","onPrimaryContainer":"#005236","inversePrimary":"#8ed5b0","secondary":"#4d6357","onSecondary":"#ffffff","secondaryContainer":"#d0e8d8","onSecondaryContainer":"#364b40","tertiary":"#3d6473","onTertiary":"#ffffff","tertiaryContainer":"#c0e9fb","onTertiaryContainer":"#244c5a","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"green|tonalSpot|dark":{"background":"#0f1511","onBackground":"#dee4de","surface":"#0f1511","surfaceDim":"#0f1511","surfaceBright":"#353b37","surfaceContainerLowest":"#0a0f0c","surfaceContainerLow":"#171d19","surfaceContainer":"#1b211d","surfaceContainerHigh":"#262b28","surfaceContainerHighest":"#303632","onSurface":"#dee4de","surfaceVariant":"#404943","onSurfaceVariant":"#c0c9c1","inverseSurface":"#dee4de","inverseOnSurface":"#2c322e","outline":"#8a938c","outlineVariant":"#404943","shadow":"#000000","scrim":"#000000","surfaceTint":"#8ed5b0","primary":"#8ed5b0","onPrimary":"#003824","primaryContainer":"#005236","onPrimaryContainer":"#aaf2cc","inversePrimary":"#226a4c","secondary":"#b4ccbd","onSecondary":"#20352a","secondaryContainer":"#364b40","onSecondaryContainer":"#d0e8d8","tertiary":"#a5cdde","onTertiary":"#063543","tertiaryContainer":"#244c5a","onTertiaryContainer":"#c0e9fb","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"green|neutral|light":{"background":"#fbf9f7","onBackground":"#1b1c1b","surface":"#fbf9f7","surfaceDim":"#dbdad8","surfaceBright":"#fbf9f7","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f5f3f1","surfaceContainer":"#efeeeb","surfaceContainerHigh":"#e9e8e6","surfaceContainerHighest":"#e3e2e0","onSurface":"#1b1c1b","surfaceVariant":"#e3e2e0","onSurfaceVariant":"#464745","inverseSurface":"#30312f","inverseOnSurface":"#f2f0ee","outline":"#777775","outlineVariant":"#c7c6c4","shadow":"#000000","scrim":"#000000","surfaceTint":"#536259","primary":"#536259","onPrimary":"#ffffff","primaryContainer":"#d6e7db","onPrimaryContainer":"#3b4a41","inversePrimary":"#bacbbf","secondary":"#58605a","onSecondary":"#ffffff","secondaryContainer":"#dce5dd","onSecondaryContainer":"#404943","tertiary":"#4d6357","onTertiary":"#ffffff","tertiaryContainer":"#d0e8d8","onTertiaryContainer":"#364b40","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"green|neutral|dark":{"background":"#121413","onBackground":"#e3e2e0","surface":"#121413","surfaceDim":"#121413","surfaceBright":"#383938","surfaceContainerLowest":"#0d0e0d","surfaceContainerLow":"#1b1c1b","surfaceContainer":"#1f201f","surfaceContainerHigh":"#292a29","surfaceContainerHighest":"#343534","onSurface":"#e3e2e0","surfaceVariant":"#464745","onSurfaceVariant":"#c7c6c4","inverseSurface":"#e3e2e0","inverseOnSurface":"#30312f","outline":"#91918f","outlineVariant":"#464745","shadow":"#000000","scrim":"#000000","surfaceTint":"#bacbbf","primary":"#bacbbf","onPrimary":"#25342b","primaryContainer":"#3b4a41","onPrimaryContainer":"#d6e7db","inversePrimary":"#536259","secondary":"#c0c9c1","onSecondary":"#2a322d","secondaryContainer":"#404943","onSecondaryContainer":"#dce5dd","tertiary":"#b4ccbd","onTertiary":"#20352a","tertiaryContainer":"#364b40","onTertiaryContainer":"#d0e8d8","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"pink|vibrant|light":{"background":"#fff8f8","onBackground":"#25181d","surface":"#fff8f8","surfaceDim":"#ecd4db","surfaceBright":"#fff8f8","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#fff0f3","surfaceContainer":"#ffe8ee","surfaceContainerHigh":"#fbe2e9","surfaceContainerHighest":"#f5dce3","onSurface":"#25181d","surfaceVariant":"#f8dbe3","onSurfaceVariant":"#554148","inverseSurface":"#3b2c31","inverseOnSurface":"#ffecf1","outline":"#887178","outlineVariant":"#dbbfc8","shadow":"#000000","scrim":"#000000","surfaceTint":"#b7006e","primary":"#b7006e","onPrimary":"#ffffff","primaryContainer":"#ffd9e4","onPrimaryContainer":"#8c0053","inversePrimary":"#ffb0cd","secondary":"#805159","onSecondary":"#ffffff","secondaryContainer":"#ffd9de","onSecondaryContainer":"#653b42","tertiary":"#8b4d4a","onTertiary":"#ffffff","tertiaryContainer":"#ffdad7","onTertiaryContainer":"#6f3634","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"pink|vibrant|dark":{"background":"#1c1014","onBackground":"#f5dce3","surface":"#1c1014","surfaceDim":"#1c1014","surfaceBright":"#45353a","surfaceContainerLowest":"#170b0f","surfaceContainerLow":"#25181d","surfaceContainer":"#291c21","surfaceContainerHigh":"#35262b","surfaceContainerHighest":"#403136","onSurface":"#f5dce3","surfaceVariant":"#554148","onSurfaceVariant":"#dbbfc8","inverseSurface":"#f5dce3","inverseOnSurface":"#3b2c31","outline":"#a38a92","outlineVariant":"#554148","shadow":"#000000","scrim":"#000000","surfaceTint":"#ffb0cd","primary":"#ffb0cd","onPrimary":"#640039","primaryContainer":"#8c0053","onPrimaryContainer":"#ffd9e4","inversePrimary":"#b7006e","secondary":"#f2b7c0","onSecondary":"#4b252c","secondaryContainer":"#653b42","onSecondaryContainer":"#ffd9de","tertiary":"#ffb3af","onTertiary":"#53201f","tertiaryContainer":"#6f3634","onTertiaryContainer":"#ffdad7","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"pink|expressive|light":{"background":"#fff8f7","onBackground":"#24181a","surface":"#fff8f7","surfaceDim":"#ebd5d6","surfaceBright":"#fff8f7","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#fff0f0","surfaceContainer":"#ffe9ea","surfaceContainerHigh":"#f9e3e4","surfaceContainerHighest":"#f4ddde","onSurface":"#24181a","surfaceVariant":"#fbdbdd","onSurfaceVariant":"#574143","inverseSurface":"#3a2d2e","inverseOnSurface":"#ffeced","outline":"#8b7173","outlineVariant":"#debfc1","shadow":"#000000","scrim":"#000000","surfaceTint":"#00658b","primary":"#00658b","onPrimary":"#ffffff","primaryContainer":"#c5e7ff","onPrimaryContainer":"#004c6a","inversePrimary":"#86cffa","secondary":"#815340","onSecondary":"#ffffff","secondaryContainer":"#ffdbcd","onSecondaryContainer":"#663c2b","tertiary":"#5d6226","onTertiary":"#ffffff","tertiaryContainer":"#e2e89d","onTertiaryContainer":"#454a0f","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"pink|expressive|dark":{"background":"#1b1012","onBackground":"#f4ddde","surface":"#1b1012","surfaceDim":"#1b1012","surfaceBright":"#443637","surfaceContainerLowest":"#160b0d","surfaceContainerLow":"#24181a","surfaceContainer":"#291c1e","surfaceContainerHigh":"#342728","surfaceContainerHighest":"#3f3133","onSurface":"#f4ddde","surfaceVariant":"#574143","onSurfaceVariant":"#debfc1","inverseSurface":"#f4ddde","inverseOnSurface":"#3a2d2e","outline":"#a68a8c","outlineVariant":"#574143","shadow":"#000000","scrim":"#000000","surfaceTint":"#86cffa","primary":"#86cffa","onPrimary":"#00344a","primaryContainer":"#004c6a","onPrimaryContainer":"#c5e7ff","inversePrimary":"#00658b","secondary":"#f5b9a1","onSecondary":"#4b2717","secondaryContainer":"#663c2b","onSecondaryContainer":"#ffdbcd","tertiary":"#c6cc83","onTertiary":"#2f3300","tertiaryContainer":"#454a0f","onTertiaryContainer":"#e2e89d","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"pink|tonalSpot|light":{"background":"#fff8f8","onBackground":"#21191c","surface":"#fff8f8","surfaceDim":"#e6d6da","surfaceBright":"#fff8f8","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#fff0f3","surfaceContainer":"#faeaed","surfaceContainerHigh":"#f4e4e8","surfaceContainerHighest":"#eedfe2","onSurface":"#21191c","surfaceVariant":"#f2dee3","onSurfaceVariant":"#514347","inverseSurface":"#372e31","inverseOnSurface":"#fdedf0","outline":"#837378","outlineVariant":"#d5c2c7","shadow":"#000000","scrim":"#000000","surfaceTint":"#8a4a65","primary":"#8a4a65","onPrimary":"#ffffff","primaryContainer":"#ffd9e4","onPrimaryContainer":"#6e334d","inversePrimary":"#ffb0cd","secondary":"#735760","onSecondary":"#ffffff","secondaryContainer":"#ffd9e4","onSecondaryContainer":"#5a3f49","tertiary":"#7e5537","onTertiary":"#ffffff","tertiaryContainer":"#ffdcc4","onTertiaryContainer":"#633e22","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"pink|tonalSpot|dark":{"background":"#191114","onBackground":"#eedfe2","surface":"#191114","surfaceDim":"#191114","surfaceBright":"#40373a","surfaceContainerLowest":"#130c0f","surfaceContainerLow":"#21191c","surfaceContainer":"#261d20","surfaceContainerHigh":"#30282a","surfaceContainerHighest":"#3c3235","onSurface":"#eedfe2","surfaceVariant":"#514347","onSurfaceVariant":"#d5c2c7","inverseSurface":"#eedfe2","inverseOnSurface":"#372e31","outline":"#9d8c91","outlineVariant":"#514347","shadow":"#000000","scrim":"#000000","surfaceTint":"#ffb0cd","primary":"#ffb0cd","onPrimary":"#531d36","primaryContainer":"#6e334d","onPrimaryContainer":"#ffd9e4","inversePrimary":"#8a4a65","secondary":"#e1bdc9","onSecondary":"#412932","secondaryContainer":"#5a3f49","onSecondaryContainer":"#ffd9e4","tertiary":"#f1bc96","onTertiary":"#49290e","tertiaryContainer":"#633e22","onTertiaryContainer":"#ffdcc4","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"pink|neutral|light":{"background":"#fff8f8","onBackground":"#1e1b1b","surface":"#fff8f8","surfaceDim":"#e0d8d9","surfaceBright":"#fff8f8","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#faf2f2","surfaceContainer":"#f4ecec","surfaceContainerHigh":"#eee6e7","surfaceContainerHighest":"#e8e1e1","onSurface":"#1e1b1b","surfaceVariant":"#e8e1e1","onSurfaceVariant":"#4a4646","inverseSurface":"#332f30","inverseOnSurface":"#f7efef","outline":"#7b7676","outlineVariant":"#ccc5c5","shadow":"#000000","scrim":"#000000","surfaceTint":"#6e5960","primary":"#6e5960","onPrimary":"#ffffff","primaryContainer":"#f8dbe3","onPrimaryContainer":"#554148","inversePrimary":"#dbbfc8","secondary":"#695b5f","onSecondary":"#ffffff","secondaryContainer":"#f2dee3","onSecondaryContainer":"#514347","tertiary":"#735760","onTertiary":"#ffffff","tertiaryContainer":"#ffd9e4","onTertiaryContainer":"#5a3f49","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"pink|neutral|dark":{"background":"#151313","onBackground":"#e8e1e1","surface":"#151313","surfaceDim":"#151313","surfaceBright":"#3c3839","surfaceContainerLowest":"#100e0e","surfaceContainerLow":"#1e1b1b","surfaceContainer":"#221f1f","surfaceContainerHigh":"#2c292a","surfaceContainerHighest":"#373434","onSurface":"#e8e1e1","surfaceVariant":"#4a4646","onSurfaceVariant":"#ccc5c5","inverseSurface":"#e8e1e1","inverseOnSurface":"#332f30","outline":"#958f90","outlineVariant":"#4a4646","shadow":"#000000","scrim":"#000000","surfaceTint":"#dbbfc8","primary":"#dbbfc8","onPrimary":"#3d2b32","primaryContainer":"#554148","onPrimaryContainer":"#f8dbe3","inversePrimary":"#6e5960","secondary":"#d5c2c7","onSecondary":"#392d31","secondaryContainer":"#514347","onSecondaryContainer":"#f2dee3","tertiary":"#e1bdc9","onTertiary":"#412932","tertiaryContainer":"#5a3f49","onTertiaryContainer":"#ffd9e4","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"faircoin|vibrant|light":{"background":"#f6fce9","onBackground":"#181d12","surface":"#f6fce9","surfaceDim":"#d6dcca","surfaceBright":"#f6fce9","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f0f6e3","surfaceContainer":"#eaf0de","surfaceContainerHigh":"#e4ebd8","surfaceContainerHighest":"#dfe5d3","onSurface":"#181d12","surfaceVariant":"#dde6cf","onSurfaceVariant":"#414939","inverseSurface":"#2c3226","inverseOnSurface":"#edf3e1","outline":"#727a67","outlineVariant":"#c1cab4","shadow":"#000000","scrim":"#000000","surfaceTint":"#376b00","primary":"#376b00","onPrimary":"#ffffff","primaryContainer":"#8afe00","onPrimaryContainer":"#285000","inversePrimary":"#78df00","secondary":"#486549","onSecondary":"#ffffff","secondaryContainer":"#c9ebc7","onSecondaryContainer":"#314d33","tertiary":"#2f694e","onTertiary":"#ffffff","tertiaryContainer":"#b2f0ce","onTertiaryContainer":"#125138","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"faircoin|vibrant|dark":{"background":"#10150a","onBackground":"#dfe5d3","surface":"#10150a","surfaceDim":"#10150a","surfaceBright":"#353b2e","surfaceContainerLowest":"#0a1006","surfaceContainerLow":"#181d12","surfaceContainer":"#1c2116","surfaceContainerHigh":"#262c20","surfaceContainerHighest":"#31372a","onSurface":"#dfe5d3","surfaceVariant":"#414939","onSurfaceVariant":"#c1cab4","inverseSurface":"#dfe5d3","inverseOnSurface":"#2c3226","outline":"#8b9480","outlineVariant":"#414939","shadow":"#000000","scrim":"#000000","surfaceTint":"#78df00","primary":"#78df00","onPrimary":"#1a3700","primaryContainer":"#285000","onPrimaryContainer":"#8afe00","inversePrimary":"#376b00","secondary":"#aecfac","onSecondary":"#1a361e","secondaryContainer":"#314d33","onSecondaryContainer":"#c9ebc7","tertiary":"#97d4b3","onTertiary":"#003824","tertiaryContainer":"#125138","onTertiaryContainer":"#b2f0ce","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"faircoin|expressive|light":{"background":"#f4fcf0","onBackground":"#171d16","surface":"#f4fcf0","surfaceDim":"#d5dcd1","surfaceBright":"#f4fcf0","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#eff6ea","surfaceContainer":"#e9f0e4","surfaceContainerHigh":"#e3eadf","surfaceContainerHighest":"#dee5d9","onSurface":"#171d16","surfaceVariant":"#d9e6d5","onSurfaceVariant":"#3e4a3d","inverseSurface":"#2b322b","inverseOnSurface":"#ecf3e7","outline":"#6e7a6c","outlineVariant":"#bdcaba","shadow":"#000000","scrim":"#000000","surfaceTint":"#94474d","primary":"#94474d","onPrimary":"#ffffff","primaryContainer":"#ffdada","onPrimaryContainer":"#763037","inversePrimary":"#ffb2b6","secondary":"#45664c","onSecondary":"#ffffff","secondaryContainer":"#c7eccb","onSecondaryContainer":"#2e4e36","tertiary":"#22695b","onTertiary":"#ffffff","tertiaryContainer":"#abf0de","onTertiaryContainer":"#005144","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"faircoin|expressive|dark":{"background":"#0f150e","onBackground":"#dee5d9","surface":"#0f150e","surfaceDim":"#0f150e","surfaceBright":"#343b33","surfaceContainerLowest":"#091009","surfaceContainerLow":"#171d16","surfaceContainer":"#1b211a","surfaceContainerHigh":"#252c24","surfaceContainerHighest":"#30372f","onSurface":"#dee5d9","surfaceVariant":"#3e4a3d","onSurfaceVariant":"#bdcaba","inverseSurface":"#dee5d9","inverseOnSurface":"#2b322b","outline":"#879485","outlineVariant":"#3e4a3d","shadow":"#000000","scrim":"#000000","surfaceTint":"#ffb2b6","primary":"#ffb2b6","onPrimary":"#591a22","primaryContainer":"#763037","onPrimaryContainer":"#ffdada","inversePrimary":"#94474d","secondary":"#abd0b0","onSecondary":"#173721","secondaryContainer":"#2e4e36","onSecondaryContainer":"#c7eccb","tertiary":"#8fd4c2","onTertiary":"#00382e","tertiaryContainer":"#005144","onTertiaryContainer":"#abf0de","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"faircoin|tonalSpot|light":{"background":"#f9faef","onBackground":"#1a1d16","surface":"#f9faef","surfaceDim":"#d9dbd0","surfaceBright":"#f9faef","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f3f5ea","surfaceContainer":"#edefe4","surfaceContainerHigh":"#e7e9de","surfaceContainerHighest":"#e2e3d9","onSurface":"#1a1d16","surfaceVariant":"#e0e4d6","onSurfaceVariant":"#44483e","inverseSurface":"#2e312a","inverseOnSurface":"#f0f2e7","outline":"#74796d","outlineVariant":"#c4c8ba","shadow":"#000000","scrim":"#000000","surfaceTint":"#48672e","primary":"#48672e","onPrimary":"#ffffff","primaryContainer":"#c9eea7","onPrimaryContainer":"#314e19","inversePrimary":"#aed18d","secondary":"#56624a","onSecondary":"#ffffff","secondaryContainer":"#dae7c9","onSecondaryContainer":"#3f4a34","tertiary":"#386664","onTertiary":"#ffffff","tertiaryContainer":"#bbece9","onTertiaryContainer":"#1e4e4d","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"faircoin|tonalSpot|dark":{"background":"#11140e","onBackground":"#e2e3d9","surface":"#11140e","surfaceDim":"#11140e","surfaceBright":"#373a33","surfaceContainerLowest":"#0c0f09","surfaceContainerLow":"#1a1d16","surfaceContainer":"#1e211a","surfaceContainerHigh":"#282b24","surfaceContainerHighest":"#33362e","onSurface":"#e2e3d9","surfaceVariant":"#44483e","onSurfaceVariant":"#c4c8ba","inverseSurface":"#e2e3d9","inverseOnSurface":"#2e312a","outline":"#8e9286","outlineVariant":"#44483e","shadow":"#000000","scrim":"#000000","surfaceTint":"#aed18d","primary":"#aed18d","onPrimary":"#1c3704","primaryContainer":"#314e19","onPrimaryContainer":"#c9eea7","inversePrimary":"#48672e","secondary":"#becbae","onSecondary":"#29341f","secondaryContainer":"#3f4a34","onSecondaryContainer":"#dae7c9","tertiary":"#a0cfcd","onTertiary":"#003736","tertiaryContainer":"#1e4e4d","onTertiaryContainer":"#bbece9","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"},"faircoin|neutral|light":{"background":"#fbf9f5","onBackground":"#1b1c1a","surface":"#fbf9f5","surfaceDim":"#dcdad6","surfaceBright":"#fbf9f5","surfaceContainerLowest":"#ffffff","surfaceContainerLow":"#f6f3ef","surfaceContainer":"#f0edea","surfaceContainerHigh":"#eae8e4","surfaceContainerHighest":"#e4e2de","onSurface":"#1b1c1a","surfaceVariant":"#e4e2de","onSurfaceVariant":"#474744","inverseSurface":"#30302e","inverseOnSurface":"#f3f0ed","outline":"#787774","outlineVariant":"#c8c6c3","shadow":"#000000","scrim":"#000000","surfaceTint":"#596150","primary":"#596150","onPrimary":"#ffffff","primaryContainer":"#dde6cf","onPrimaryContainer":"#414939","inversePrimary":"#c1cab4","secondary":"#5b6055","onSecondary":"#ffffff","secondaryContainer":"#e0e4d6","onSecondaryContainer":"#44483e","tertiary":"#56624a","onTertiary":"#ffffff","tertiaryContainer":"#dae7c9","onTertiaryContainer":"#3f4a34","error":"#ba1a1a","onError":"#ffffff","errorContainer":"#ffdad6","onErrorContainer":"#93000a"},"faircoin|neutral|dark":{"background":"#131412","onBackground":"#e4e2de","surface":"#131412","surfaceDim":"#131412","surfaceBright":"#393937","surfaceContainerLowest":"#0e0e0d","surfaceContainerLow":"#1b1c1a","surfaceContainer":"#1f201e","surfaceContainerHigh":"#2a2a28","surfaceContainerHighest":"#353533","onSurface":"#e4e2de","surfaceVariant":"#474744","onSurfaceVariant":"#c8c6c3","inverseSurface":"#e4e2de","inverseOnSurface":"#30302e","outline":"#92918d","outlineVariant":"#474744","shadow":"#000000","scrim":"#000000","surfaceTint":"#c1cab4","primary":"#c1cab4","onPrimary":"#2b3324","primaryContainer":"#414939","onPrimaryContainer":"#dde6cf","inversePrimary":"#596150","secondary":"#c4c8ba","onSecondary":"#2d3228","secondaryContainer":"#44483e","onSecondaryContainer":"#e0e4d6","tertiary":"#becbae","onTertiary":"#29341f","tertiaryContainer":"#3f4a34","onTertiaryContainer":"#dae7c9","error":"#ffb4ab","onError":"#690005","errorContainer":"#93000a","onErrorContainer":"#ffdad6"}}
|
|
@@ -2,13 +2,12 @@ import goldenResolvedTokens from './__fixtures__/golden-resolved-tokens.json';
|
|
|
2
2
|
import { APP_COLOR_NAMES } from '../color-presets';
|
|
3
3
|
import { getResolvedTokens } from '../token-registry';
|
|
4
4
|
|
|
5
|
-
// `golden-resolved-tokens.json` is the
|
|
6
|
-
// rgb for every preset×mode×token
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// the
|
|
10
|
-
//
|
|
11
|
-
// shift a single color.
|
|
5
|
+
// `golden-resolved-tokens.json` is the frozen palette oracle: the exact resolved
|
|
6
|
+
// rgb for every preset×mode×token. It was DELIBERATELY REBASED when the palette
|
|
7
|
+
// moved from hand-authored HSL triples to the colour engine (Phase 5) — the
|
|
8
|
+
// palette change is the deliverable. It is frozen going FORWARD: it now guards
|
|
9
|
+
// against accidental drift of the engine-backed output, so these tests still
|
|
10
|
+
// prove `getResolvedTokens` reproduces the committed palette byte-for-byte.
|
|
12
11
|
const fixture = goldenResolvedTokens as Record<string, Record<string, string>>;
|
|
13
12
|
|
|
14
13
|
describe('golden token parity (frozen oracle)', () => {
|
|
@@ -44,18 +44,18 @@ describe('web var(--primary) resolves to a real color (not a bare triple)', () =
|
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
it('
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
47
|
+
it('engine-backed alias invariants hold', () => {
|
|
48
|
+
// Phase 5 contract: `secondary` is a REAL contrast color (engine secondary
|
|
49
|
+
// role, no longer a mirror of primary), `card` is the lightest surface (engine
|
|
50
|
+
// `surfaceContainerLowest`, surfaced as `--card`). The legacy `primaryLight`
|
|
51
|
+
// (page surface tint) and `primaryDark` (page background) aliases are retained.
|
|
52
52
|
for (const preset of ['oxy', 'blue'] as const) {
|
|
53
53
|
for (const mode of ['light', 'dark'] as const) {
|
|
54
54
|
const { colors } = buildTheme(preset, mode);
|
|
55
55
|
const t = getResolvedTokens(preset, mode);
|
|
56
|
-
expect(colors.secondary).toBe(colors.primary);
|
|
57
|
-
expect(colors.secondary).toBe(t['--
|
|
58
|
-
expect(colors.card).toBe(t['--
|
|
56
|
+
expect(colors.secondary).not.toBe(colors.primary);
|
|
57
|
+
expect(colors.secondary).toBe(t['--secondary']);
|
|
58
|
+
expect(colors.card).toBe(t['--card']);
|
|
59
59
|
expect(colors.primaryLight).toBe(t['--surface']);
|
|
60
60
|
expect(colors.primaryDark).toBe(t['--background']);
|
|
61
61
|
}
|
|
@@ -5,18 +5,16 @@
|
|
|
5
5
|
import normalizeColor from '@react-native/normalize-colors';
|
|
6
6
|
|
|
7
7
|
import { buildTheme } from '../build-theme';
|
|
8
|
-
import
|
|
8
|
+
import { getPresetVars } from '../preset-vars';
|
|
9
|
+
import { APP_COLOR_NAMES, type AppColorName } from '../color-presets';
|
|
9
10
|
import type { ThemeColors } from '../types';
|
|
10
11
|
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// `git show 00a4cf3:src/theme/build-theme.ts`). We assert visual equality via
|
|
18
|
-
// ΔE on the parsed sRGB — `hsl(...)` and the matching `rgb(...)` parse to the
|
|
19
|
-
// same bytes under the RN/RNW/browser `normalizeColor`, so ΔE is 0.
|
|
12
|
+
// Phase 5 rebased the palette from hand-authored HSL triples to the colour
|
|
13
|
+
// engine. The pre-0.8.0 `theme.colors` parity oracles (which froze
|
|
14
|
+
// `secondary === primary` and `card === surface`) are intentionally OBSOLETE —
|
|
15
|
+
// those two aliases are the very bugs this phase fixes. This suite now guards the
|
|
16
|
+
// NEW engine-backed contract: every value parses, and the two fixes hold for
|
|
17
|
+
// every preset in both modes.
|
|
20
18
|
|
|
21
19
|
type Rgb = { r: number; g: number; b: number };
|
|
22
20
|
|
|
@@ -29,87 +27,45 @@ function parse(color: string): Rgb {
|
|
|
29
27
|
return { r: (n >>> 24) & 0xff, g: (n >>> 16) & 0xff, b: (n >>> 8) & 0xff };
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
return Math.sqrt((a.r - b.r) ** 2 + (a.g - b.g) ** 2 + (a.b - b.b) ** 2) / Math.sqrt(3);
|
|
34
|
-
}
|
|
30
|
+
const lightness = ({ r, g, b }: Rgb): number => r + g + b;
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
* shadow/overlay were never changed, so they are intentionally omitted.
|
|
44
|
-
*/
|
|
45
|
-
type Oracle = Partial<Record<keyof ThemeColors, string>>;
|
|
32
|
+
describe.each(APP_COLOR_NAMES)('engine-backed theme.colors (%s)', (preset: AppColorName) => {
|
|
33
|
+
it.each(['light', 'dark'] as const)('%s: every color value parses', (mode) => {
|
|
34
|
+
const { colors } = buildTheme(preset, mode);
|
|
35
|
+
for (const value of Object.values(colors)) {
|
|
36
|
+
expect(normalizeColor(value)).not.toBeNull();
|
|
37
|
+
}
|
|
38
|
+
});
|
|
46
39
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
primaryDark: 'hsl(205, 50%, 5%)', // == background
|
|
58
|
-
primarySubtle: 'hsl(205, 50%, 10%)',
|
|
59
|
-
primarySubtleForeground: 'hsl(205, 70%, 65%)',
|
|
60
|
-
negative: 'hsl(0, 84%, 45%)',
|
|
61
|
-
negativeForeground: '#FFFFFF',
|
|
62
|
-
negativeSubtle: 'hsl(0, 50%, 10%)',
|
|
63
|
-
negativeSubtleForeground: 'hsl(0, 70%, 65%)',
|
|
64
|
-
contrast50: 'hsl(205, 15%, 12%)',
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
// oxy: primary 277 66% 56%, surface dark 277 20% 18%, background dark 277 50% 5%, destructive hue 0.
|
|
69
|
-
preset: 'oxy',
|
|
70
|
-
mode: 'dark',
|
|
71
|
-
old: {
|
|
72
|
-
secondary: 'hsl(277, 66%, 56%)',
|
|
73
|
-
primary: 'hsl(277, 66%, 56%)',
|
|
74
|
-
card: 'hsl(277, 20%, 18%)',
|
|
75
|
-
primaryLight: 'hsl(277, 20%, 18%)',
|
|
76
|
-
primaryDark: 'hsl(277, 50%, 5%)',
|
|
77
|
-
primarySubtle: 'hsl(277, 50%, 10%)',
|
|
78
|
-
primarySubtleForeground: 'hsl(277, 70%, 65%)',
|
|
79
|
-
negative: 'hsl(0, 84%, 45%)',
|
|
80
|
-
negativeForeground: '#FFFFFF',
|
|
81
|
-
negativeSubtle: 'hsl(0, 50%, 10%)',
|
|
82
|
-
negativeSubtleForeground: 'hsl(0, 70%, 65%)',
|
|
83
|
-
contrast50: 'hsl(277, 15%, 12%)',
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
// blue light: surface 205 58% 94%, background 205 55% 96%.
|
|
88
|
-
preset: 'blue',
|
|
89
|
-
mode: 'light',
|
|
90
|
-
old: {
|
|
91
|
-
secondary: 'hsl(205, 87%, 53%)',
|
|
92
|
-
primary: 'hsl(205, 87%, 53%)',
|
|
93
|
-
card: 'hsl(205, 58%, 94%)',
|
|
94
|
-
primaryLight: 'hsl(205, 58%, 94%)',
|
|
95
|
-
primaryDark: 'hsl(205, 55%, 96%)',
|
|
96
|
-
primarySubtle: 'hsl(205, 70%, 93%)',
|
|
97
|
-
primarySubtleForeground: 'hsl(205, 90%, 25%)',
|
|
98
|
-
negative: 'hsl(0, 84%, 45%)',
|
|
99
|
-
negativeForeground: '#FFFFFF',
|
|
100
|
-
negativeSubtle: 'hsl(0, 90%, 95%)',
|
|
101
|
-
negativeSubtleForeground: 'hsl(0, 80%, 40%)',
|
|
102
|
-
contrast50: 'hsl(205, 10%, 93%)',
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
];
|
|
40
|
+
it('secondary is a real contrast color, not a mirror of primary', () => {
|
|
41
|
+
for (const mode of ['light', 'dark'] as const) {
|
|
42
|
+
const { colors } = buildTheme(preset, mode);
|
|
43
|
+
expect(colors.secondary).not.toBe(colors.primary);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('card is lighter than background in light, darker (or equal) in dark', () => {
|
|
48
|
+
const light = buildTheme(preset, 'light').colors;
|
|
49
|
+
expect(lightness(parse(light.card))).toBeGreaterThan(lightness(parse(light.background)));
|
|
106
50
|
|
|
107
|
-
|
|
108
|
-
|
|
51
|
+
const dark = buildTheme(preset, 'dark').colors;
|
|
52
|
+
expect(lightness(parse(dark.card))).toBeLessThanOrEqual(lightness(parse(dark.background)));
|
|
53
|
+
});
|
|
109
54
|
|
|
110
|
-
it
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
55
|
+
it('token-backed fields read straight from the resolved token map', () => {
|
|
56
|
+
for (const mode of ['light', 'dark'] as const) {
|
|
57
|
+
const { colors } = buildTheme(preset, mode);
|
|
58
|
+
const t = getPresetVars(preset, mode);
|
|
59
|
+
const field: Array<[keyof ThemeColors, string]> = [
|
|
60
|
+
['primary', '--primary'],
|
|
61
|
+
['secondary', '--secondary'],
|
|
62
|
+
['card', '--card'],
|
|
63
|
+
['background', '--background'],
|
|
64
|
+
['border', '--border'],
|
|
65
|
+
];
|
|
66
|
+
for (const [colorKey, tokenKey] of field) {
|
|
67
|
+
expect(colors[colorKey]).toBe(t[tokenKey]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
114
70
|
});
|
|
115
71
|
});
|
package/src/theme/build-theme.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Platform } from 'react-native';
|
|
2
2
|
import { APP_COLOR_PRESETS, type AppColorName } from './color-presets';
|
|
3
|
+
import { generateRoleColors, type RoleColors } from './color-engine';
|
|
3
4
|
import { getAdaptiveColors } from './adaptive-colors';
|
|
4
|
-
import { getResolvedTokens
|
|
5
|
+
import { getResolvedTokens } from './token-registry';
|
|
5
6
|
import { THEME_GRADIENTS } from './gradients';
|
|
6
7
|
import type { Theme, ThemeColors } from './types';
|
|
7
8
|
|
|
@@ -17,29 +18,16 @@ export const STATUS_COLORS = {
|
|
|
17
18
|
} as const;
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const hue = parseInt(first, 10);
|
|
27
|
-
return Number.isFinite(hue) ? hue : 0;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Build the JS `theme.colors` object from the SAME canonical rgb token source
|
|
32
|
-
* the web/native CSS-var writes use (`getResolvedTokens`). JS styles and the
|
|
33
|
-
* `var(--x)` document tokens therefore share one rgb pipeline — no second,
|
|
34
|
-
* drift-prone HSL conversion lives here.
|
|
21
|
+
* Build the JS `theme.colors` object from the SAME engine-derived colours the
|
|
22
|
+
* web/native CSS-var writes use. Token-backed fields read from the resolved rgb
|
|
23
|
+
* token map (`getResolvedTokens`, which sources from the engine via
|
|
24
|
+
* `getPresetVars`); the brand-tint family (primarySubtle/negative/…) reads the
|
|
25
|
+
* engine's container/error roles directly. JS styles and the `var(--x)` document
|
|
26
|
+
* tokens therefore share one engine-backed pipeline — no second HSL conversion.
|
|
35
27
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* the historical `hsl(h, s%, l%)` math — but are emitted as `rgb(...)` by
|
|
40
|
-
* routing the triple through the registry's `hslToSrgb`, so the single-format
|
|
41
|
-
* pipeline is preserved. (`hsl(h,s%,l%)` and the `rgb(...)` of the same color
|
|
42
|
-
* are byte-identical under the RN/RNW/browser parser.)
|
|
28
|
+
* The two intentional fixes land here too: `card` is now the lightest surface
|
|
29
|
+
* (`--card` → engine `surfaceContainerLowest`) and `secondary` is a real
|
|
30
|
+
* contrast colour (engine `secondary` role), not a mirror of `primary`.
|
|
43
31
|
*/
|
|
44
32
|
function buildColorsFromPreset(
|
|
45
33
|
preset: AppColorName,
|
|
@@ -51,24 +39,23 @@ function buildColorsFromPreset(
|
|
|
51
39
|
// Read a resolved `rgb(...)` token by its bare name (no leading `--`).
|
|
52
40
|
const g = (k: string): string => t[`--${k}`] ?? 'rgb(0 0 0)';
|
|
53
41
|
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const dHue = extractHue(presetTokens['--destructive'] ?? '0 0% 0%');
|
|
42
|
+
// The full engine role set — for fields that map to roles Bloom's canonical
|
|
43
|
+
// token set does not surface (containers, error family).
|
|
44
|
+
const config = APP_COLOR_PRESETS[preset];
|
|
45
|
+
const r: RoleColors = generateRoleColors({
|
|
46
|
+
seed: config.hex,
|
|
47
|
+
variant: config.variant,
|
|
48
|
+
isDark,
|
|
49
|
+
});
|
|
63
50
|
|
|
64
51
|
return {
|
|
65
52
|
background: g('background'),
|
|
66
53
|
backgroundSecondary: g('surface'),
|
|
67
|
-
backgroundTertiary: g('
|
|
54
|
+
backgroundTertiary: g('popover'),
|
|
68
55
|
|
|
69
56
|
text: g('foreground'),
|
|
70
57
|
textSecondary: g('muted-foreground'),
|
|
71
|
-
textTertiary:
|
|
58
|
+
textTertiary: r.outline,
|
|
72
59
|
|
|
73
60
|
border: g('border'),
|
|
74
61
|
borderLight: g('input'),
|
|
@@ -80,8 +67,8 @@ function buildColorsFromPreset(
|
|
|
80
67
|
primaryLight: g('surface'),
|
|
81
68
|
primaryDark: g('background'),
|
|
82
69
|
|
|
83
|
-
// `secondary`
|
|
84
|
-
secondary: g('
|
|
70
|
+
// The FIX: `secondary` is now a real contrast colour (engine `secondary`).
|
|
71
|
+
secondary: g('secondary'),
|
|
85
72
|
|
|
86
73
|
tint: g('primary'),
|
|
87
74
|
icon: g('muted-foreground'),
|
|
@@ -89,15 +76,16 @@ function buildColorsFromPreset(
|
|
|
89
76
|
|
|
90
77
|
...STATUS_COLORS,
|
|
91
78
|
|
|
92
|
-
primarySubtle:
|
|
93
|
-
primarySubtleForeground:
|
|
94
|
-
negative:
|
|
95
|
-
negativeForeground:
|
|
96
|
-
negativeSubtle:
|
|
97
|
-
negativeSubtleForeground:
|
|
98
|
-
contrast50:
|
|
79
|
+
primarySubtle: r.primaryContainer,
|
|
80
|
+
primarySubtleForeground: r.onPrimaryContainer,
|
|
81
|
+
negative: r.error,
|
|
82
|
+
negativeForeground: r.onError,
|
|
83
|
+
negativeSubtle: r.errorContainer,
|
|
84
|
+
negativeSubtleForeground: r.onErrorContainer,
|
|
85
|
+
contrast50: g('muted'),
|
|
99
86
|
|
|
100
|
-
|
|
87
|
+
// The FIX: `card` is the lightest surface (engine `surfaceContainerLowest`).
|
|
88
|
+
card: g('card'),
|
|
101
89
|
shadow: isDark ? 'rgba(0, 0, 0, 0.3)' : 'rgba(0, 0, 0, 0.1)',
|
|
102
90
|
overlay: 'rgba(0, 0, 0, 0.5)',
|
|
103
91
|
};
|