From a466503265458fcfa442a963aa59e0a38fbc0a2b Mon Sep 17 00:00:00 2001 From: illubyte Studios <47870619+Illubyte@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:08:31 -0400 Subject: [PATCH] Reworked Sass to automatically generate color variations from palette (#8890) * Reworked Sass to automatically generate color variations from palette * Fixed naming scheme for mixing colors * Updated light theme to use pre-defined steps * Updated dark theme to use pre-defined steps, added steps at 90 & 110 * Hardcoded -alt color variations, extracted color variation generator to reusable mixin. Co-authored-by: rijkvanzanten --- app/src/styles/_colors.scss | 48 ++++++ app/src/styles/main.scss | 1 + app/src/styles/themes/_dark.scss | 140 +++--------------- app/src/styles/themes/_light.scss | 128 ++-------------- .../styles/themes/mixins/generate-colors.scss | 22 +++ 5 files changed, 102 insertions(+), 237 deletions(-) create mode 100644 app/src/styles/_colors.scss create mode 100644 app/src/styles/themes/mixins/generate-colors.scss diff --git a/app/src/styles/_colors.scss b/app/src/styles/_colors.scss new file mode 100644 index 0000000000..65f6fabde4 --- /dev/null +++ b/app/src/styles/_colors.scss @@ -0,0 +1,48 @@ +@import 'themes/mixins/generate-colors'; + +// Main palette +$purple: #9e8de4; +$blue: #68b0f4; +$green: #00c897; +$yellow: #ffb300; +$orange: #ee9746; +$red: #e35169; + +// Mixing colors +$light-theme-tint: #fff; +$light-theme-shade: #2e3c43; +$dark-theme-tint: #fff; +$dark-theme-shade: #2e3c43; + +// Color variant names -> Color to map to said name +$color-mapping: ( + 'purple': $purple, + 'blue': $blue, + 'green': $green, + 'yellow': $yellow, + 'orange': $orange, + 'red': $red, + 'primary': $green, + 'secondary': $blue, + 'success': $green, + 'warning': $yellow, + 'danger': $red, +); + +// Suffix -> Percentage mapping (Percentage of main color) +// Negative numbers will use secondary color for mixture. +// The percentage will be equal to the absolute value of the number. +$step-mapping: ( + '10': 10, + '25': 25, + '50': 50, + '75': 75, + '90': 90, + // Special case, 'none' will result in no suffix + 'none': 100, + '110': -90, + '125': -75, + '150': -50, + '175': -25, + '190': -10, +); diff --git a/app/src/styles/main.scss b/app/src/styles/main.scss index 39f8bec460..3c28d00a8c 100644 --- a/app/src/styles/main.scss +++ b/app/src/styles/main.scss @@ -1,4 +1,5 @@ @import 'base'; +@import 'colors'; @import 'fonts'; @import 'themes/dark'; @import 'themes/light'; diff --git a/app/src/styles/themes/_dark.scss b/app/src/styles/themes/_dark.scss index f57d870c32..f3a7dafa9a 100644 --- a/app/src/styles/themes/_dark.scss +++ b/app/src/styles/themes/_dark.scss @@ -4,140 +4,42 @@ @mixin dark { --border-normal: #455a64; --border-normal-alt: #78909c; - --border-subdued: #2E3F47; + --border-subdued: #2e3f47; - --foreground-normal: #B3C4CC; // Less contrast for improved hierarchy + --foreground-normal: #b3c4cc; // Less contrast for improved hierarchy --foreground-normal-alt: #cfd8dc; // More contrast for titles and labels - --foreground-subdued: #697A83; - --foreground-inverted:#263238; + --foreground-subdued: #697a83; + --foreground-inverted: #263238; - --background-normal: #2E3C43; // #37474f - --background-normal-alt: #3A4B53; // #455a64 - --background-subdued: #2D3A41; - --background-highlight: #2D3A41; + --background-normal: #2e3c43; // #37474f + --background-normal-alt: #3a4b53; // #455a64 + --background-subdued: #2d3a41; + --background-highlight: #2d3a41; --background-page: #263238; --background-input: #263238; --background-page-rgb: 38, 50, 56; - --background-inverted: #FFF; + --background-inverted: #fff; // --card-shadow-color: 207,216,220; - --card-face-color: #36454D; - --card-shadow-color: 0,0,0; - --card-shadow: 0px 0px 6px 0px rgba(var(--card-shadow-color),0.2); + --card-face-color: #36454d; + --card-shadow-color: 0, 0, 0; + --card-shadow: 0px 0px 6px 0px rgba(var(--card-shadow-color), 0.2); --overlay-color: rgba(19, 24, 26, 0.9); - --purple-190: #F6F4FD; - --purple-175: #E7E2F8; - --purple-150: #CEC5F1; - --purple-125: #B7AAEB; - --purple: #9E8DE4; - --purple-75: #8279BC; - --purple-50: #666493; - --purple-25: #4A506B; - --purple-10: #394453; - --purple-alt: #394453; + // Generate color variations + @include generate-colors($color-mapping, $dark-theme-shade, $dark-theme-tint); - --blue-190: #F0F8FE; - --blue-175: #D9EBFC; - --blue-150: #B3D7F9; - --blue-125: #8EC4F7; - --blue: #68B0F4; - --blue-75: #5993C8; - --blue-50: #4B769B; - --blue-25: #3C596F; - --blue-10: #344855; - --blue-alt: #344855; - - --green-190: #E6FAF5; - --green-175: #BFF1E5; - --green-150: #7FE3CA; - --green-125: #40D6B1; - --green: #00C897; - --green-110: #05BA8F; // Text readability - --green-75: #0BA582; - --green-50: #17826D; - --green-25: #225F58; - --green-10: #294A4B; - --green-alt: #294A4B; - - --yellow-190: #FFF9ED; - --yellow-175: #FEF0D3; - --yellow-150: #FDE2A7; - --yellow-125: #FCD37B; - --yellow: #FBC54F; - --yellow-75: #C8A34C; - --yellow-50: #948049; - --yellow-25: #615E46; - --yellow-10: #42453F; - --yellow-alt: #42453F; - - --orange-190: #FDF5EC; - --orange-175: #FBE5D1; - --orange-150: #F7CBA3; - --orange-125: #F2B174; - --orange: #EE9746; - --orange-75: #BE8045; - --orange-50: #8E6A44; - --orange-25: #5E5344; - --orange-10: #414543; - --orange-alt: #414543; - - --red-190: #FDEEF0; - --red-175: #F8D3D9; - --red-150: #F0A7B3; - --red-125: #EA7D8F; - --red: #E35169; - --red-75: #B64C5F; - --red-50: #884756; - --red-25: #5B414C; - --red-10: #403E47; - --red-alt: #403E47; - - - --primary-190: var(--green-190); - --primary-175: var(--green-175); - --primary-150: var(--green-150); - --primary-125: var(--green-125); - --primary: var(--green); + --purple-alt: var(--purple-10); + --blue-alt: var(--blue-10); + --green-alt: var(--green-10); + --yellow-alt: var(--yellow-10); + --orange-alt: var(--orange-10); + --red-alt: var(--red-10); --primary-alt: var(--green-10); - --primary-110: var(--green-110); - --primary-75: var(--green-75); - --primary-50: var(--green-50); - --primary-25: var(--green-25); - --primary-10: var(--green-10); - - --success-190: var(--green-190); - --success-175: var(--green-175); - --success-150: var(--green-150); - --success-125: var(--green-125); - --success: var(--green); + --secondary-alt: var(--blue-10); --success-alt: var(--green-10); - --success-75: var(--green-75); - --success-50: var(--green-50); - --success-25: var(--green-25); - --success-10: var(--green-10); - - --warning-190: var(--yellow-190); - --warning-175: var(--yellow-175); - --warning-150: var(--yellow-150); - --warning-125: var(--yellow-125); - --warning: var(--yellow); --warning-alt: var(--yellow-10); - --warning-75: var(--yellow-75); - --warning-50: var(--yellow-50); - --warning-25: var(--yellow-25); - --warning-10: var(--yellow-10); - - --danger-190: var(--red-190); - --danger-175: var(--red-175); - --danger-150: var(--red-150); - --danger-125: var(--red-125); - --danger: var(--red); --danger-alt: var(--red-10); - --danger-75: var(--red-75); - --danger-50: var(--red-50); - --danger-25: var(--red-25); - --danger-10: var(--red-10); .alt-colors { --background-subdued: var(--background-page); diff --git a/app/src/styles/themes/_light.scss b/app/src/styles/themes/_light.scss index 1295a7b6e8..a767938eee 100644 --- a/app/src/styles/themes/_light.scss +++ b/app/src/styles/themes/_light.scss @@ -25,128 +25,20 @@ --card-shadow: 0px 0px 6px 0px rgba(var(--card-shadow-color), 0.2); --overlay-color: rgba(38, 50, 56, 0.9); - --purple-alt: #f6f4fd; - --purple-10: #f6f4fd; - --purple-25: #e7e2f8; - --purple-50: #cec5f1; - --purple-75: #b7aaeb; - --purple: #9e8de4; - --purple-125: #8279bc; - --purple-150: #666493; - --purple-175: #4a506b; - --purple-190: #394453; + // Generate color variations + @include generate-colors($color-mapping, $light-theme-tint, $light-theme-shade); - --blue-alt: #f0f8fe; - --blue-10: #f0f8fe; - --blue-25: #d9ebfc; - --blue-50: #b3d7f9; - --blue-75: #8ec4f7; - --blue: #68b0f4; - --blue-125: #5993c8; - --blue-150: #4b769b; - --blue-175: #3c596f; - --blue-190: #344855; - - --green-alt: #e6faf5; - --green-10: #e6faf5; - --green-25: #bff1e5; - --green-50: #7fe3ca; - --green-75: #40d6b1; - --green: #00c897; - --green-110: #05ba8f; // Text readability - --green-125: #0ba582; - --green-150: #17826d; - --green-175: #225f58; - --green-190: #294a4b; - - --yellow-alt: #fff9ed; - --yellow-10: #fff9ed; - --yellow-25: #fef0d3; - --yellow-50: #fde2a7; - --yellow-75: #fcd37b; - --yellow: #ffb300; - --yellow-125: #c8a34c; - --yellow-150: #948049; - --yellow-175: #615e46; - --yellow-190: #424a44; - - --orange-alt: #fdf5ec; - --orange-10: #fdf5ec; - --orange-25: #fbe5d1; - --orange-50: #f7cba3; - --orange-75: #f2b174; - --orange: #ee9746; - --orange-125: #be8045; - --orange-150: #8e6a44; - --orange-175: #5e5344; - --orange-190: #414543; - - --red-alt: #fdeef0; - --red-10: #fdeef0; - --red-25: #f8d3d9; - --red-50: #f0a7b3; - --red-75: #ea7d8f; - --red: #e35169; - --red-125: #b64c5f; - --red-150: #884756; - --red-175: #5b414c; - --red-190: #403e47; - - --primary-10: var(--green-10); - --primary-25: var(--green-25); - --primary-50: var(--green-50); - --primary-75: var(--green-75); - --primary: var(--green); + --purple-alt: var(--purple-10); + --blue-alt: var(--blue-10); + --green-alt: var(--green-10); + --yellow-alt: var(--yellow-10); + --orange-alt: var(--orange-10); + --red-alt: var(--red-10); --primary-alt: var(--green-10); - --primary-110: var(--green-110); - --primary-125: var(--green-125); - --primary-150: var(--green-150); - --primary-175: var(--green-175); - --primary-190: var(--green-190); - - --secondary-alt: var(--blue-alt); - --secondary-10: var(--blue-10); - --secondary-25: var(--blue-25); - --secondary-50: var(--blue-50); - --secondary-75: var(--blue-75); - --secondary: var(--blue); - --secondary-125: var(--blue-125); - --secondary-150: var(--blue-150); - --secondary-175: var(--blue-175); - --secondary-190: var(--blue-190); - - --success-10: var(--green-10); - --success-25: var(--green-25); - --success-50: var(--green-50); - --success-75: var(--green-75); - --success: var(--green); + --secondary-alt: var(--blue-10); --success-alt: var(--green-10); - --success-125: var(--green-125); - --success-150: var(--green-150); - --success-175: var(--green-175); - --success-190: var(--green-190); - - --warning-10: var(--orange-10); - --warning-25: var(--orange-25); - --warning-50: var(--orange-50); - --warning-75: var(--orange-75); - --warning: var(--orange); - --warning-alt: var(--orange-10); - --warning-125: var(--orange-125); - --warning-150: var(--orange-150); - --warning-175: var(--orange-175); - --warning-190: var(--orange-190); - - --danger-10: var(--red-10); - --danger-25: var(--red-25); - --danger-50: var(--red-50); - --danger-75: var(--red-75); - --danger: var(--red); + --warning-alt: var(--yellow-10); --danger-alt: var(--red-10); - --danger-125: var(--red-125); - --danger-150: var(--red-150); - --danger-175: var(--red-175); - --danger-190: var(--red-190); .alt-colors { --background-subdued: var(--background-page); diff --git a/app/src/styles/themes/mixins/generate-colors.scss b/app/src/styles/themes/mixins/generate-colors.scss new file mode 100644 index 0000000000..c61a83254e --- /dev/null +++ b/app/src/styles/themes/mixins/generate-colors.scss @@ -0,0 +1,22 @@ +@mixin generate-colors($color-map, $mix-color-low, $mix-color-high) { + // Loop through palette in $color-map list + @each $identifier, $color in $color-map { + // Loop through pre-defined steps in $step-mapping list + @each $suffix, $step in $step-mapping { + // Default suffix to nothing + $resolved-suffix: ''; + // Default mixing color + $mixing-color: $mix-color-low; + // Set suffix if not equal to none + @if $suffix != 'none' { + $resolved-suffix: '-#{$suffix}'; + } + // If our step is negative, change to dark mixing color + @if $step < 0 { + $mixing-color: $mix-color-high; + } + // This is the CSS variable that will be output + --#{$identifier}#{$resolved-suffix}: #{mix($mixing-color, $color, 100 - abs($step))}; + } + } +}