diff --git a/assets/sass/abstracts/_functions.scss b/assets/sass/abstracts/_functions.scss index 09e251ef..abf8ae74 100644 --- a/assets/sass/abstracts/_functions.scss +++ b/assets/sass/abstracts/_functions.scss @@ -1,15 +1,14 @@ -@use "sass:math"; +@use "sass:color"; @use "settings"; -// Gradient hack to get our custom underline to wrap: -// https://www.dannyguo.com/blog/animated-multiline-link-underlines-with-css/ -@function underline-hack($color) { - // Less compatible but better for light/dark mode switching. We fall back to non-alpha hex colors with - // postcss-color-rgba-fallback to mitigate this. - // stylelint-disable-next-line color-function-notation - $color-opaque-alpha: rgba($color, math.div(settings.$link-underline-opacity, 100%)); +// Figure out the color of the "transparent" link underlines: +@function underline-hack($color, $background: #ffffff) { + // Calculate underline color by mix()'ing it with a given background to give the impression of opacity but with much + // better efficiency and compatibility. + $color-transparentized: color.mix($color, $background, settings.$link-underline-opacity); - // Return non-gradient linear-gradient(): - @return linear-gradient($color-opaque-alpha, $color-opaque-alpha); + // Return a "gradient" as a hack to get the fancy underline to wrap: + // https://www.dannyguo.com/blog/animated-multiline-link-underlines-with-css/ + @return linear-gradient($color-transparentized, $color-transparentized); } diff --git a/assets/sass/abstracts/_settings.scss b/assets/sass/abstracts/_settings.scss index bd94e1c3..e9e248ae 100644 --- a/assets/sass/abstracts/_settings.scss +++ b/assets/sass/abstracts/_settings.scss @@ -27,7 +27,6 @@ $font-stack-mono-variable: list.join($webfont-mono-variable, $system-fonts-monos // Fancy link underline settings: $link-underline-opacity: 40%; $link-underline-size: 2px; -$link-opacity-color: #ffffff; // Default fading style when switching between light/dark themes: $theme-transition-duration: 0.15s; diff --git a/assets/sass/abstracts/_themes.scss b/assets/sass/abstracts/_themes.scss index 445328eb..a8952e5e 100644 --- a/assets/sass/abstracts/_themes.scss +++ b/assets/sass/abstracts/_themes.scss @@ -1,45 +1,42 @@ @use "sass:list"; @use "sass:map"; -@use "sass:meta"; @use "settings"; // Takes a map of CSS properties and theme keys (see below) and set both body.light and body.dark selectors. -// ex. @include themes.themed($color: "text", $background-color: "background-inner"); -@mixin themed($colors...) { - $selectors: "#{&}"; - - // keep track of each property we're theming - $properties: (); - @each $property, $color in meta.keywords($colors) { - $properties: list.append($properties, $property); +// ex. @include themes.themed((color: "text", background-color: "background-inner")); +// Also accepts additional transitions (in shorthand) to tack on. +@mixin themed($properties, $addTransitions: ()) { + // generate CSS transition shorthand for each themed property w/ default duration and function + $defaults: (); + @each $property, $color in $properties { + $shorthand: $property settings.$theme-transition-duration settings.$theme-transition-function; + $defaults: list.append($defaults, $shorthand); } - // list themed properties under CSS transitions for fancy fading - transition-property: list.join($properties, (), $separator: comma); - transition-duration: #{settings.$theme-transition-duration}; - transition-timing-function: #{settings.$theme-transition-function}; + // list all transitions separated by commas (with additional shorthand(s) passed in) + transition: list.join($addTransitions, $defaults, $separator: comma); + + // keep track of the original selector(s) calling this mixin for below + $selectors: "#{&}"; // add corresponding body.light and body.dark root selectors @each $theme, $map in $themes { @at-root body.#{$theme} { - // support root body element + // support theming root body element @if $selectors == "body" { - @each $property, $color in meta.keywords($colors) { + @each $property, $color in $properties { #{$property}: map.get($map, $color); } } @else { #{$selectors} { - @each $property, $color in meta.keywords($colors) { + @each $property, $color in $properties { #{$property}: map.get($map, $color); } } } } } - - // allow anything above to be overridden manually by passing in a content block - @content; } // ---------------- diff --git a/assets/sass/components/_animation.scss b/assets/sass/components/_animation.scss index 4502ebd7..dfb8a36a 100644 --- a/assets/sass/components/_animation.scss +++ b/assets/sass/components/_animation.scss @@ -36,7 +36,11 @@ } // stylelint-enable rule-empty-line-before - @include themes.themed($background-color: "medium-light"); + @include themes.themed( + ( + background-color: "medium-light", + ) + ); } } diff --git a/assets/sass/components/_content.scss b/assets/sass/components/_content.scss index 381bd635..63070834 100644 --- a/assets/sass/components/_content.scss +++ b/assets/sass/components/_content.scss @@ -16,7 +16,12 @@ div#content { padding-left: 1.5em; border-left: 3px solid; - @include themes.themed($color: "medium-dark", $border-color: "links"); + @include themes.themed( + ( + color: "medium-dark", + border-color: "links", + ) + ); } h2, @@ -41,10 +46,18 @@ div#content { content: "\0023"; // pound sign } - @include themes.themed($color: "medium-light"); + @include themes.themed( + ( + color: "medium-light", + ) + ); &:hover { - @include themes.themed($color: "links"); + @include themes.themed( + ( + color: "links", + ) + ); } } @@ -58,7 +71,11 @@ div#content { padding-bottom: 0.25em; border-bottom: 1px solid; - @include themes.themed($border-color: "kinda-light"); + @include themes.themed( + ( + border-color: "kinda-light", + ) + ); } p.center { @@ -80,7 +97,11 @@ div#content { line-height: 1.5; margin-top: 0.5em; - @include themes.themed($color: "medium"); + @include themes.themed( + ( + color: "medium", + ) + ); } } @@ -99,7 +120,11 @@ div#content { height: 2px; border: 0; - @include themes.themed($background-color: "light"); + @include themes.themed( + ( + background-color: "light", + ) + ); } } diff --git a/assets/sass/components/_footer.scss b/assets/sass/components/_footer.scss index 2243dcd1..a485baea 100644 --- a/assets/sass/components/_footer.scss +++ b/assets/sass/components/_footer.scss @@ -8,10 +8,19 @@ footer { padding: 1.25em 1.5em; border-top: 1px solid; - @include themes.themed($color: "medium-dark", $border-color: "kinda-light"); + @include themes.themed( + ( + color: "medium-dark", + border-color: "kinda-light", + ) + ); a { - @include themes.themed($color: "medium-dark"); + @include themes.themed( + ( + color: "medium-dark", + ) + ); } div.footer-row { @@ -29,7 +38,12 @@ footer { padding-bottom: 2px; border-bottom: 1px solid; - @include themes.themed($color: "medium-dark", $border-color: "light"); + @include themes.themed( + ( + color: "medium-dark", + border-color: "light", + ) + ); } } diff --git a/assets/sass/components/_global.scss b/assets/sass/components/_global.scss index b701aa6a..a34c491b 100644 --- a/assets/sass/components/_global.scss +++ b/assets/sass/components/_global.scss @@ -19,7 +19,11 @@ body { font-size: 0.975em; line-height: 1.5; - @include themes.themed($background-color: "background-outer"); + @include themes.themed( + ( + background-color: "background-outer", + ) + ); // set themed lightbulb icons manually &.light button.dark-mode-toggle { @@ -69,7 +73,12 @@ main { width: 100%; padding: 0 1.5em; - @include themes.themed($color: "text", $background-color: "background-inner"); + @include themes.themed( + ( + color: "text", + background-color: "background-inner", + ) + ); a { background-position: 0% 100%; @@ -77,18 +86,19 @@ main { background-size: 0% settings.$link-underline-size; padding-bottom: settings.$link-underline-size; - @include themes.themed($color: "links") { - // TODO: overriding transition-property from themed() -- very hacky - transition-property: color, background-size; - transition-duration: #{settings.$theme-transition-duration}, 0.25s; - transition-timing-function: #{settings.$theme-transition-function}, ease-in-out; - } + @include themes.themed( + $properties: ( + color: "links", + ), + $addTransitions: ( + background-size 0.25s ease-in-out, + ) + ); - // cool link underlines (via messy SCSS hacking): - // https://www.dannyguo.com/blog/animated-multiline-link-underlines-with-css/ + // cool link underlines via messy SCSS hacking (see ../abstracts/_functions) @each $theme, $map in themes.$themes { @at-root body.#{$theme} #{&} { - background-image: functions.underline-hack(map.get($map, "links")); + background-image: functions.underline-hack(map.get($map, "links"), map.get($map, "background-inner")); } } diff --git a/assets/sass/components/_header.scss b/assets/sass/components/_header.scss index 3edd6c55..eceae7c4 100644 --- a/assets/sass/components/_header.scss +++ b/assets/sass/components/_header.scss @@ -7,7 +7,11 @@ header { padding: 0.7em 1.5em; border-bottom: 1px solid; - @include themes.themed($border-color: "kinda-light"); + @include themes.themed( + ( + border-color: "kinda-light", + ) + ); nav { width: 100%; @@ -21,7 +25,11 @@ header { display: flex; align-items: center; - @include themes.themed($color: "medium-dark"); + @include themes.themed( + ( + color: "medium-dark", + ) + ); img#header-selfie { width: 50px; @@ -30,7 +38,11 @@ header { border-radius: 50%; user-select: none; - @include themes.themed($border-color: "light"); + @include themes.themed( + ( + border-color: "light", + ) + ); } span#header-name { @@ -41,7 +53,11 @@ header { } &:hover { - @include themes.themed($color: "links"); + @include themes.themed( + ( + color: "links", + ) + ); img#header-selfie { opacity: 90%; @@ -66,22 +82,26 @@ header { // hovers are super choppy without this in some browsers will-change: transform; - @include themes.themed($color: "medium-dark") { - // TODO: overriding transition-property from themed() -- very hacky - transition-property: color, transform; - transition-duration: #{settings.$theme-transition-duration}; - transition-timing-function: #{settings.$theme-transition-function}, ease-in-out; - } + @include themes.themed( + $properties: ( + color: "medium-dark", + ), + $addTransitions: ( + transform 0.2s ease-in-out, + ) + ); &:hover { transform: scale(1.1); - @include themes.themed($color: "links") { - // TODO: overriding transition-property from themed() -- very hacky - transition-property: color, transform; - transition-duration: #{settings.$theme-transition-duration}; - transition-timing-function: #{settings.$theme-transition-function}, ease-in-out; - } + @include themes.themed( + $properties: ( + color: "links", + ), + $addTransitions: ( + transform 0.2s ease-in-out, + ) + ); } span { diff --git a/assets/sass/components/_syntax.scss b/assets/sass/components/_syntax.scss index 833ef5c7..bf417e81 100644 --- a/assets/sass/components/_syntax.scss +++ b/assets/sass/components/_syntax.scss @@ -64,7 +64,11 @@ div.highlight-clipboard-enabled { line-height: 1; &:hover { - @include themes.themed($color: "links"); + @include themes.themed( + ( + color: "links", + ) + ); } } } diff --git a/assets/sass/pages/_contact.scss b/assets/sass/pages/_contact.scss index 45636e77..bf8bdb28 100644 --- a/assets/sass/pages/_contact.scss +++ b/assets/sass/pages/_contact.scss @@ -34,7 +34,13 @@ div.layout-contact { border-radius: 0.3em; font-size: 0.9em; - @include themes.themed($color: "text", $background-color: "super-duper-light", $border-color: "light"); + @include themes.themed( + ( + color: "text", + background-color: "super-duper-light", + border-color: "light", + ) + ); } textarea { @@ -58,11 +64,21 @@ div.layout-contact { line-height: 1.5; user-select: none; - @include themes.themed($color: "text", $background-color: "kinda-light"); + @include themes.themed( + ( + color: "text", + background-color: "kinda-light", + ) + ); &:hover, &:focus { - @include themes.themed($color: "super-duper-light", $background-color: "links"); + @include themes.themed( + ( + color: "super-duper-light", + background-color: "links", + ) + ); } img.emoji { @@ -76,11 +92,19 @@ div.layout-contact { font-weight: 600; &#contact-form-result-success { - @include themes.themed($color: "success"); + @include themes.themed( + ( + color: "success", + ) + ); } &#contact-form-result-error { - @include themes.themed($color: "error"); + @include themes.themed( + ( + color: "error", + ) + ); } } } diff --git a/assets/sass/pages/_home.scss b/assets/sass/pages/_home.scss index 5dd21b55..a647cd70 100644 --- a/assets/sass/pages/_home.scss +++ b/assets/sass/pages/_home.scss @@ -1,3 +1,5 @@ +@use "sass:map"; + @use "../abstracts/themes"; @use "../abstracts/functions"; @@ -184,7 +186,11 @@ div.layout-home { } &#shh { - @include themes.themed($color: "medium-light"); + @include themes.themed( + ( + color: "medium-light", + ) + ); } &.wave { @@ -198,7 +204,7 @@ div.layout-home { @each $theme, $color in $colors { @at-root body.#{$theme} div.layout-home a##{$id} { color: $color; - background-image: functions.underline-hack($color); + background-image: functions.underline-hack($color, map.get(map.get(themes.$themes, $theme), "background-inner")); } } } diff --git a/assets/sass/pages/_list.scss b/assets/sass/pages/_list.scss index d0d7adf7..8c033588 100644 --- a/assets/sass/pages/_list.scss +++ b/assets/sass/pages/_list.scss @@ -32,7 +32,11 @@ div.layout-list { width: 5.25em; flex-shrink: 0; - @include themes.themed($color: "medium"); + @include themes.themed( + ( + color: "medium", + ) + ); } &:last-child { diff --git a/assets/sass/pages/_projects.scss b/assets/sass/pages/_projects.scss index f84f41fe..9e1de77d 100644 --- a/assets/sass/pages/_projects.scss +++ b/assets/sass/pages/_projects.scss @@ -42,7 +42,12 @@ div.layout-projects { border-radius: 0.5em; font-size: 0.9em; - @include themes.themed($color: "medium-dark", $border-color: "kinda-light"); + @include themes.themed( + ( + color: "medium-dark", + border-color: "kinda-light", + ) + ); a.repo-name { font-size: 1.2em; @@ -63,7 +68,11 @@ div.layout-projects { margin-right: 1.5em; font-size: 0.925em; - @include themes.themed($color: "medium"); + @include themes.themed( + ( + color: "medium", + ) + ); svg { display: inline-block; diff --git a/assets/sass/pages/_single.scss b/assets/sass/pages/_single.scss index fa9830d8..9a5efc13 100644 --- a/assets/sass/pages/_single.scss +++ b/assets/sass/pages/_single.scss @@ -13,7 +13,11 @@ div.layout-single { line-height: 2.3; letter-spacing: 0.04em; - @include themes.themed($color: "medium"); + @include themes.themed( + ( + color: "medium", + ) + ); a { color: inherit; @@ -65,7 +69,11 @@ div.layout-single { content: "#"; // cosmetically hashtagify tags padding-right: 0.125em; - @include themes.themed($color: "light"); + @include themes.themed( + ( + color: "light", + ) + ); } &:last-of-type { diff --git a/assets/sass/pages/_videos.scss b/assets/sass/pages/_videos.scss index 4fb2b690..4a218b51 100644 --- a/assets/sass/pages/_videos.scss +++ b/assets/sass/pages/_videos.scss @@ -11,7 +11,11 @@ div.layout-video { line-height: 1.5; margin: 1.25em 1em 0.5em 1em; - @include themes.themed($color: "medium-light"); + @include themes.themed( + ( + color: "medium-light", + ) + ); a { font-weight: bold; diff --git a/package.json b/package.json index 55842575..a6303f8a 100644 --- a/package.json +++ b/package.json @@ -80,13 +80,12 @@ "gulp-execa": "^3.0.2", "gulp-html-minifier-terser": "^6.0.1", "gulp-imagemin": "^8.0.0", - "hugo-extended": "github:jakejarvis/hugo-extended#reinstall-on-error", + "hugo-extended": "github:jakejarvis/hugo-extended#main", "lint-staged": "^11.2.6", "markdownlint-cli": "~0.29.0", "mini-css-extract-plugin": "^2.4.3", "npm-run-all": "^4.1.5", "postcss": "^8.3.11", - "postcss-color-rgba-fallback": "^4.0.0", "postcss-focus": "^5.0.1", "postcss-loader": "^6.2.0", "postcss-normalize-charset": "^5.0.1", diff --git a/webpack.config.js b/webpack.config.js index 27e9fc30..0b8d7be1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -11,7 +11,6 @@ import TerserPlugin from "terser-webpack-plugin"; import autoprefixer from "autoprefixer"; import postcssSvgo from "postcss-svgo"; import postcssFocus from "postcss-focus"; -import postcssColorRgbaFallback from "postcss-color-rgba-fallback"; import postcssNormalizeCharset from "postcss-normalize-charset"; // https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#what-do-i-use-instead-of-__dirname-and-__filename @@ -134,9 +133,6 @@ export default { postcssSvgo({ encode: true, }), - postcssColorRgbaFallback({ - properties: ["background-image"], - }), postcssFocus(), postcssNormalizeCharset(), ], diff --git a/yarn.lock b/yarn.lock index 0b6f54c4..0d7f1c19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5072,9 +5072,9 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -"hugo-extended@github:jakejarvis/hugo-extended#reinstall-on-error": +"hugo-extended@github:jakejarvis/hugo-extended#main": version "0.88.1-patch1" - resolved "https://codeload.github.com/jakejarvis/hugo-extended/tar.gz/0ecddf5b1e78fe1fa2190cea5e9db1bc9e622be3" + resolved "https://codeload.github.com/jakejarvis/hugo-extended/tar.gz/8251c012de3d7d7916c1cbf21ac8013f90a1a93c" dependencies: careful-downloader "^2.0.1" log-symbols "^5.0.0" @@ -7414,11 +7414,6 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -7530,15 +7525,6 @@ postcss-calc@^8.0.0: postcss-selector-parser "^6.0.2" postcss-value-parser "^4.0.2" -postcss-color-rgba-fallback@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-rgba-fallback/-/postcss-color-rgba-fallback-4.0.0.tgz#b836c4a34c747cf9b16f1ebcd7d6016c299e0cf2" - integrity sha512-XxjOy2dA/IYY/O9p492lklb0sw2lyshjXCoJQz7Y0YLxT1ymnep5d8LmQPkB+kCTVCzmniJNotiZhWM1RSfANA== - dependencies: - postcss "^7.0.17" - postcss-value-parser "^4.0.2" - rgb-hex "^3.0.0" - postcss-colormin@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.0.tgz#2b620b88c0ff19683f3349f4cf9e24ebdafb2c88" @@ -7819,14 +7805,6 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss@^7.0.17: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - postcss@^8.2.15, postcss@^8.2.4, postcss@^8.3.11, postcss@^8.3.5, postcss@^8.3.6: version "8.3.11" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858" @@ -8430,11 +8408,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rgb-hex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rgb-hex/-/rgb-hex-3.0.0.tgz#eab0168cc1279563b18a14605315389142e2e487" - integrity sha512-8h7ZcwxCBDKvchSWbWngJuSCqJGQ6nDuLLg+QcRyQDbX9jMWt+PpPeXAhSla0GOooEomk3lCprUpGkMdsLjKyg== - rimraf@^2.4.0, rimraf@^2.5.4: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"