$colors: ( light: ( background: #fff, primary-400: #acacac, primary-500: #505050, primary-600: #3c3c3c, accent-500: #007bff, accent-600: #0056b3, color-primary: hsl(0, 0%, 10%), color-text: hsl(0, 0%, 20%), color-subtext: hsl(0, 0%, 30%), color-border: hsl(0, 0%, 85%), color-box-background: mix($color-primary, white, 4%) ), dark: ( background: rgb(17, 35, 57), primary-400: #acacac, primary-500: #505050, primary-600: #3c3c3c, accent-500: #007bff, accent-600: #0056b3, color-primary: hsl(0, 0%, 96%), color-text: hsl(0, 0%, 74%), color-subtext: hsl(0, 0%, 49%), color-border: hsl(0, 0%, 23%), color-box-background: mix($color-primary, black, 4%) ), ); $color-placeholder: 'here'; @function compose-color-variable($color-key) { @return '--color-#{$color-key}'; } :root { @each $key, $value in map-get($colors, 'light') { #{compose-color-variable($key)}: #{$value}; } } @media (prefers-color-scheme: dark) { :root { @each $key, $value in map-get($colors, 'dark') { #{compose-color-variable($key)}: #{$value}; } } } @function str-replace($string, $search, $replace: '') { $index: str-index($string, $search); @if not $index { @return $string; } @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); } @function color-get($palette, $color-key) { @return map-get(map-get($colors, $palette), $color-key); } @mixin color-assign($property, $color-key, $template: '') { $fallback: #{color-get("light", $color-key)}; $var: var(#{compose-color-variable($color-key)}); #{$property}: if(str-length($template) == 0, $fallback, #{str-replace($template, $color-placeholder, $fallback)}); #{$property}: if(str-length($template) == 0, $var, #{str-replace($template, $color-placeholder, $var)}); }