diff --git a/outputs/hozen/default.nix b/outputs/hozen/default.nix index 6360d82..f7db3fd 100644 --- a/outputs/hozen/default.nix +++ b/outputs/hozen/default.nix @@ -2,6 +2,7 @@ inherit (ook.lib.color.utils) mkLightColorScheme mkDarkColorScheme; darkScheme = mkDarkColorScheme { + slug = "gruvbox-material-dark-medium"; neutrals = { "50" = "dfd2b3"; "100" = "d9c7a5"; @@ -17,12 +18,12 @@ "600" = "585350"; "650" = "4d4947"; "700" = "3f3b3b"; - "750" = "343232"; + "750" = "32302f"; "800" = "282828"; "850" = "212121"; "900" = "1a1a1a"; }; - primary = "ea6962"; + primary = "a9b665"; red = "ea6962"; orange = "e78a4e"; yellow = "d8a657"; @@ -37,6 +38,7 @@ }; lightScheme = mkLightColorScheme { + slug = "gruvbox-material-light-soft"; neutrals = { "50" = "f7efda"; "100" = "f4eac8"; diff --git a/outputs/lib/color/utils.nix b/outputs/lib/color/utils.nix index 7014169..a6abb35 100644 --- a/outputs/lib/color/utils.nix +++ b/outputs/lib/color/utils.nix @@ -8,8 +8,14 @@ hslSet = translate.hex.toHSL.set hexStr; newHSL = types.hsl.set { inherit (hslSet) h; - l = math.clamp 0.0 1.0 (hslSet.l + (modifications.l or 0.0)); - s = math.clamp 0.0 1.0 (hslSet.s + (modifications.s or 0.0)); + l = + if modifications ? absoluteL + then modifications.l + else math.clamp 0.0 1.0 (hslSet.l + (modifications.l or 0.0)); + s = + if modifications ? absoluteS + then modifications.l + else math.clamp 0.0 1.0 (hslSet.s + (modifications.s or 0.0)); }; rgbSet = translate.hsl.toRGB.set newHSL; in @@ -27,35 +33,47 @@ desaturate = amount: hexStr: modifyHSL hexStr {s = (amount * -1) / 100.0;}; - # opinionated scale generators for light/dark themes - # lighter/darker shades always desaturate + absoluteLum = amount: hexStr: + modifyHSL hexStr { + absoluteL = true; + l = amount / 100.0; + }; + mkDarkColorScale = base: { - up4 = desaturate 24 (lighten 12 base); - up3 = desaturate 18 (lighten 9 base); - up2 = desaturate 12 (lighten 6 base); - up1 = desaturate 6 (lighten 3 base); + hard4 = lighten 12 base; + hard3 = lighten 9 base; + hard2 = lighten 6 base; + hard1 = lighten 3 base; inherit base; - down1 = desaturate 6 (darken 3 base); - down2 = desaturate 12 (darken 6 base); - down3 = desaturate 18 (darken 9 base); - down4 = desaturate 24 (darken 12 base); + soft1 = darken 3 base; + soft2 = darken 6 base; + soft3 = darken 9 base; + soft4 = darken 12 base; }; mkLightColorScale = base: { - down4 = desaturate 24 (lighten 12 base); - down3 = desaturate 18 (lighten 9 base); - down2 = desaturate 12 (lighten 6 base); - down1 = desaturate 6 (lighten 3 base); + soft4 = lighten 12 base; + soft3 = lighten 9 base; + soft2 = lighten 6 base; + soft1 = lighten 3 base; inherit base; - up1 = desaturate 6 (darken 3 base); - up2 = desaturate 12 (darken 6 base); - up3 = desaturate 18 (darken 9 base); - up4 = desaturate 24 (darken 12 base); + hard1 = darken 3 base; + hard2 = darken 6 base; + hard3 = darken 9 base; + hard4 = darken 12 base; + }; + + mkAlert = color: { + fg = absoluteLum 19 color; + bg = absoluteLum 79 color; + border = color; + base = color; }; # core color scheme generator mkColorScheme = { type ? "dark", + slug, neutrals ? {}, primary, red, @@ -71,52 +89,59 @@ brown, } @ args: let # Select scale function based on theme type - colorScale = + mkColorScale = if type == "dark" then mkDarkColorScale else mkLightColorScale; # Generate color scales - colorScales = { - red = colorScale args.red; - orange = colorScale args.orange; - yellow = colorScale args.yellow; - olive = colorScale args.olive; - green = colorScale args.green; - teal = colorScale args.teal; - blue = colorScale args.blue; - violet = colorScale args.violet; - purple = colorScale args.purple; - pink = colorScale args.pink; - brown = colorScale args.brown; + colors = { + red = mkColorScale args.red; + orange = mkColorScale args.orange; + yellow = mkColorScale args.yellow; + olive = mkColorScale args.olive; + green = mkColorScale args.green; + teal = mkColorScale args.teal; + blue = mkColorScale args.blue; + violet = mkColorScale args.violet; + purple = mkColorScale args.purple; + pink = mkColorScale args.pink; + brown = mkColorScale args.brown; }; # Theme-specific configurations - themeConfig = + theme = if type == "dark" then { semantic = { - body = args.neutrals."700"; - header = args.neutrals."800"; - footer = args.neutrals."800"; - menu = args.neutrals."800"; - border = args.neutrals."150"; - border-active = args.neutrals."150"; - border-inactive = args.neutrals."600"; - text = args.neutrals."150"; - text-bright = args.neutrals."100"; - subtext = args.neutrals."300"; + layout = { + body = args.neutrals."750"; + header = args.neutrals."800"; + footer = args.neutrals."800"; + menu = args.neutrals."800"; + }; + border = { + base = args.neutrals."150"; + active = args.neutrals."150"; + inactive = args.neutrals."600"; + }; + typography = { + text = args.neutrals."150"; + text-bright = args.neutrals."100"; + subtext = args.neutrals."300"; + contrast-text = args.neutrals."800"; + }; }; secondary = { - up-4 = args.neutrals."400"; - up-3 = args.neutrals."450"; - up-2 = args.neutrals."500"; - up-1 = args.neutrals."550"; - base = args.neutrals."700"; - down-1 = args.neutrals."750"; - down-2 = args.neutrals."800"; - down-3 = args.neutrals."850"; - down-4 = args.neutrals."900"; + hard4 = args.neutrals."300"; + hard3 = args.neutrals."350"; + hard2 = args.neutrals."400"; + hard1 = args.neutrals."450"; + base = args.neutrals."500"; + soft1 = args.neutrals."550"; + soft2 = args.neutrals."600"; + soft3 = args.neutrals."650"; + soft4 = args.neutrals."700"; }; base00 = args.neutrals."800"; base01 = args.neutrals."700"; @@ -131,27 +156,34 @@ } else { semantic = { - body = args.neutrals."50"; - header = args.neutrals."150"; - footer = args.neutrals."150"; - menu = args.neutrals."150"; - border = args.neutrals."800"; - border-active = args.neutrals."800"; - border-inactive = args.neutrals."300"; - text = args.neutrals."800"; - text-bright = args.neutrals."850"; - subtext = args.neutrals."600"; + layout = { + body = args.neutrals."50"; + header = args.neutrals."150"; + footer = args.neutrals."150"; + menu = args.neutrals."150"; + }; + border = { + base = args.neutrals."800"; + active = args.neutrals."800"; + inactive = args.neutrals."300"; + }; + typography = { + text = args.neutrals."800"; + text-bright = args.neutrals."850"; + subtext = args.neutrals."600"; + text-contrast = args.neutrals."50"; + }; }; secondary = { - up-4 = args.neutrals."400"; - up-3 = args.neutrals."350"; - up-2 = args.neutrals."300"; - up-1 = args.neutrals."250"; + hard4 = args.neutrals."400"; + hard3 = args.neutrals."350"; + hard2 = args.neutrals."300"; + hard1 = args.neutrals."250"; base = args.neutrals."200"; - down-1 = args.neutrals."150"; - down-2 = args.neutrals."100"; - down-3 = args.neutrals."50"; - down-4 = args.neutrals."50"; + soft1 = args.neutrals."150"; + soft2 = args.neutrals."100"; + soft3 = args.neutrals."50"; + soft4 = args.neutrals."50"; }; base00 = args.neutrals."150"; base01 = args.neutrals."250"; @@ -165,6 +197,7 @@ base11 = args.neutrals."50"; }; in { + inherit slug; # Common structure for both themes neutrals = { inherit @@ -190,8 +223,14 @@ ; }; + error = mkAlert args.red; + warning = mkAlert args.yellow; + success = mkAlert args.green; + note = mkAlert args.blue; + tip = mkAlert args.teal; + inherit - (colorScales) + (colors) red orange yellow @@ -205,52 +244,11 @@ brown ; - primary = colorScale args.primary; + primary = mkColorScale args.primary; - inherit (themeConfig) semantic secondary; + inherit (theme) secondary; + inherit (theme.semantic) layout border typography; - # Status colors (same structure for both themes) - error = { - bg = "${colorScales.red.base}"; - bg-active = "${colorScales.red.down1}"; - bg-hover = "${colorScales.red.down2}"; - text = "${themeConfig.semantic.text-bright}"; - border = "${colorScales.red.up2}"; - }; - - success = { - bg = "${colorScales.green.base}"; - bg-active = "${colorScales.green.down1}"; - bg-hover = "${colorScales.green.down2}"; - text = "${themeConfig.semantic.text-bright}"; - border = "${colorScales.green.up2}"; - }; - - warning = { - bg = "${colorScales.yellow.base}"; - bg-active = "${colorScales.yellow.down1}"; - bg-hover = "${colorScales.yellow.down2}"; - text = "${themeConfig.semantic.text-bright}"; - border = "${colorScales.yellow.up2}"; - }; - - info = { - bg = "${colorScales.blue.base}"; - bg-active = "${colorScales.blue.down1}"; - bg-hover = "${colorScales.blue.down2}"; - text = "${themeConfig.semantic.text-bright}"; - border = "${colorScales.blue.up2}"; - }; - - tip = { - bg = "${colorScales.teal.base}"; - bg-active = "${colorScales.teal.down1}"; - bg-hover = "${colorScales.teal.down2}"; - text = "${themeConfig.semantic.text-bright}"; - border = "${colorScales.teal.up2}"; - }; - - # Syntax highlighting (same for both themes) syntax = { string = args.green; number = args.purple; @@ -273,14 +271,13 @@ preCondit = args.purple; special = args.yellow; specialChar = args.yellow; - comment = "${themeConfig.semantic.subtext}"; + comment = "${theme.semantic.typography.subtext}"; todo = args.purple; tag = args.teal; }; - # Base16/24 colors inherit - (themeConfig) + (theme) base00 base01 base02 @@ -292,8 +289,6 @@ base10 base11 ; - - # Generated base colors base08 = args.red; base09 = args.orange; base0A = args.yellow; @@ -302,12 +297,12 @@ base0D = args.blue; base0E = args.purple; base0F = args.brown; - base12 = "${colorScales.red.up2}"; - base13 = "${colorScales.yellow.up2}"; - base14 = "${colorScales.green.up2}"; - base15 = "${colorScales.teal.up2}"; - base16 = "${colorScales.blue.up2}"; - base17 = "${colorScales.purple.up2}"; + base12 = "${colors.red.hard2}"; + base13 = "${colors.yellow.hard2}"; + base14 = "${colors.green.hard2}"; + base15 = "${colors.teal.hard2}"; + base16 = "${colors.blue.hard2}"; + base17 = "${colors.purple.hard2}"; }; # wrappers