From a1489414f0a62a6b808f9346aa0f564d8e0645a9 Mon Sep 17 00:00:00 2001 From: Tom Vines Date: Sun, 3 Aug 2025 19:25:19 +1000 Subject: [PATCH] feat: toggleable, two-tone light/dark mode --- assets/css/screen.css | 197 +++++++++++++---------------------- assets/js/global.js | 5 +- partials/header.hbs | 4 + partials/icons/site/moon.hbs | 1 + partials/icons/site/sun.hbs | 1 + partials/navigation.hbs | 4 + 6 files changed, 88 insertions(+), 124 deletions(-) create mode 100644 partials/icons/site/moon.hbs create mode 100644 partials/icons/site/sun.hbs diff --git a/assets/css/screen.css b/assets/css/screen.css index 80ad4ec..983bf93 100644 --- a/assets/css/screen.css +++ b/assets/css/screen.css @@ -132,7 +132,7 @@ --color-white: #fff; /* Body */ - --color-body: #fff; + --color-body: #f7f7f5; --color-body-partial: #fff; /* Border */ @@ -149,31 +149,9 @@ --opacity-one: .8; --opacity-two: 1; } - -/* Partial version - –––––––––––––––––––––––––––––––––––––––––––––––––––– */ -.partial-dark-mode, -.auto-partial-dark-mode { - --color-font-two: #f7f7f5; - --color-one: #e8e8e6; - --color-two: #d9d9d8; - --color-six: #f7f7f5; - --color-eight: #e8e8e6; - --color-eleven: #e8e8e6; - --color-thirteen: #e2e2df; - --color-fourteen: #e8e8e6; - --color-white: #f7f7f5; - --color-body: #f7f7f5; - --color-border-one: #d9d9d8; - --color-border-two: #d9d9d8; - --opacity-one: .7; - --opacity-two: 1; -} - /* Dark version –––––––––––––––––––––––––––––––––––––––––––––––––––– */ -.dark-mode, -.is-partial-dark { +.dark-mode { --color-font-one: #f7f7f5; --color-font-two: #1a1b1e; --color-font-three: #f7f7f5; @@ -196,7 +174,7 @@ --color-fourteen: #2b2d31; --color-white: #f7f7f5; --color-body: #1a1b1e; - --color-body-partial: #1a1b1e; + --color-body-partial: #151619; --color-border-one: #4b4f52; --color-border-two: #4b4f52; --color-border-three: #5e6265; @@ -204,103 +182,6 @@ --opacity-two: .9; } -/* Automatic dark version [duplicate dark version] - –––––––––––––––––––––––––––––––––––––––––––––––––––– */ -@media (prefers-color-scheme:dark) { - .auto-dark-mode, - .auto-partial-dark-mode { - --color-font-one: #f7f7f5; - --color-font-two: #1a1b1e; - --color-font-three: #f7f7f5; - --color-font-four: #1a1b1e; - --color-font-five: #f7f7f5; - --color-font-six: #1a1b1e; - --color-one: #2b2d31; - --color-two: #34363a; - --color-three: #f7f7f5; - --color-four: #f7f7f5; - --color-five: #f7f7f5; - --color-six: #1a1b1e; - --color-seven: #f7f7f5; - --color-eight: #2b2d31; - --color-nine: #212225; - --color-ten: #212225; - --color-eleven: #292a2d; - --color-twelve: #2b2d31; - --color-thirteen: #34363a; - --color-fourteen: #2b2d31; - --color-white: #f7f7f5; - --color-body: #1a1b1e; - --color-body-partial: #1a1b1e; - --color-border-one: #4b4f52; - --color-border-two: #4b4f52; - --color-border-three: #5e6265; - --opacity-one: .5; - --opacity-two: .9; - } - -} - -body .is-partial-color:not(.is-partial-dark) { - --color-font-one: #151618; - --color-font-two: #fff; - --color-font-four: #151618; - --color-font-five: #fff; - --color-one: rgba(0, 0, 0, .07); - --color-two: rgba(0, 0, 0, .12); - --color-three: #151618; - --color-four: #fff; - --color-five: #151618; - --color-six: #151618; - --color-nine: #fff; - --color-eleven: rgba(0, 0, 0, .07); - --color-twelve: #fff; - --color-body: #fff; - --color-body-partial: var(--ghost-bg-color); - --color-border-one: rgba(0, 0, 0, .3); - --opacity-one: .8; - --opacity-two: 1; -} - -.dark-mode .is-partial-color:not(.is-partial-dark) { - --color-font-three: #f7f7f5; - --color-font-four: #f7f7f5; - --color-font-five: #151618; - --color-four: #151618; - --color-six: #f7f7f5; - --color-nine: rgba(0, 0, 0, .07); - --color-twelve: rgba(0, 0, 0, .07); - --color-body: #151618; -} - -@media (prefers-color-scheme:dark) { - .auto-dark-mode .is-partial-color:not(.is-partial-dark) { - --color-font-three: #f7f7f5; - --color-font-four: #f7f7f5; - --color-font-five: #151618; - --color-four: #151618; - --color-six: #f7f7f5; - --color-nine: rgba(0, 0, 0, .07); - --color-twelve: rgba(0, 0, 0, .07); - --color-body: #151618; - } - -} - -/* Logo for dark version - –––––––––––––––––––––––––––––––––––––––––––––––––––– */ -@media (prefers-color-scheme:dark) { - .auto-dark-mode a.is-dark + a { - display: none; - } -} - -@media (prefers-color-scheme:light) { - .auto-dark-mode a.is-dark { - display: none; - } -} - /* Hiding 'Portal' notifications –––––––––––––––––––––––––––––––––––––––––––––––––––– */ iframe[title="portal-notification"] { @@ -3272,7 +3153,7 @@ textarea::placeholder { } .kg-card.kg-product-card :is(.kg-product-card-container > div , .kg-product-card-container > div a) { - color: var(--color-font-black); + color: var(--color-font-one); } /* NFT @@ -5765,3 +5646,73 @@ textarea::placeholder { } } + +.header-nav .theme-toggle { + cursor: pointer; + width: 24px; + height: 24px; + display: inline-block; +} +.header-nav .theme-toggle.is-desktop { + margin-left: 0.8vw; +} +.header-nav .theme-toggle svg { + color: var(--color-font-one); + fill: none; +} +.header-nav .theme-toggle.is-mobile, +html:not(.light-dark-mode) .header-nav .theme-toggle, +html.dark-mode .header-nav .theme-toggle .if-is-light, +html:not(.dark-mode) .header-nav .theme-toggle .if-is-dark { + display: none; +} +@media (min-width: 1025px) { + .header-nav .theme-toggle:hover svg { + fill: var(--color-font-one); + } +} +@media (max-width: 1024px) { + .light-dark-mode .header-logo { + flex-basis: 60%; + } + .light-dark-mode .header-nav { + flex-basis: 40%; + } + .header-nav .theme-toggle.is-mobile { + display: block; + position: absolute; + top: 9px; + right: 84px; + } + .header-nav .theme-toggle.is-desktop { + display: none; + } +} + +.post-header-container { + border-bottom: var(--border) var(--color-border-one); + padding-bottom: 4vh; + margin-bottom: 8vh; +} +.post-header-container .post-header-content, +.post-header-container .post-header-image { + margin: auto; +} + +.kg-callout-card-white, +.kg-product-card-container, +.kg-file-card-container { + background-color: var(--color-body-partial) !important; + border-color: var(--color-border-one) !important; + color: var(--color-font-one) !important; +} +.kg-file-card-container, +.kg-file-card-icon { + min-height: auto !important; +} +.kg-file-card-icon svg { + color: var(--color-font-one); +} +.kg-file-card-icon::before { + display: none; +} diff --git a/assets/js/global.js b/assets/js/global.js index dcc240f..716a290 100644 --- a/assets/js/global.js +++ b/assets/js/global.js @@ -16,4 +16,7 @@ var e,t;e=this,t=function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:3,t=new Map,n=Math.pow(10,e);return{get:function(e){var r=e.match(w).length;if(t.has(r))return t.get(r);var i=1/Math.sqrt(r),o=parseFloat(Math.round(i*n)/n);return t.set(r,o),o},clear:function(){t.clear()}}}var _=function(){function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=n.getFn,i=void 0===r?x.getFn:r;t(this,e),this.norm=L(3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return r(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,u(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();u(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?x.getFn:r,o=new _({getFn:i});return o.setKeys(e.map(b)),o.setSources(t),o.create(),o}function O(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,a=t.expectedLocation,c=void 0===a?0:a,s=t.distance,h=void 0===s?x.distance:s,u=t.ignoreLocation,l=void 0===u?x.ignoreLocation:u,d=r/e.length;if(l)return d;var f=Math.abs(c-o);return h?d+f/h:f?1:d}function A(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:x.minMatchCharLength,n=[],r=-1,i=-1,o=0,a=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}function j(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,a=void 0===o?x.location:o,c=i.threshold,s=void 0===c?x.threshold:c,h=i.distance,u=void 0===h?x.distance:h,l=i.includeMatches,d=void 0===l?x.includeMatches:l,f=i.findAllMatches,v=void 0===f?x.findAllMatches:f,y=i.minMatchCharLength,g=void 0===y?x.minMatchCharLength:y,p=i.isCaseSensitive,m=void 0===p?x.isCaseSensitive:p,b=i.ignoreLocation,k=void 0===b?x.ignoreLocation:b;if(t(this,e),this.options={location:a,threshold:s,distance:u,includeMatches:d,findAllMatches:v,minMatchCharLength:g,isCaseSensitive:m,ignoreLocation:k},this.pattern=m?n:n.toLowerCase(),this.chunks=[],this.pattern.length){var M=function(e,t){r.chunks.push({pattern:e,alphabet:j(e),startIndex:t})},w=this.pattern.length;if(w>32){for(var L=0,_=w%32,S=w-_;L3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?x.location:i,a=r.distance,c=void 0===a?x.distance:a,s=r.threshold,h=void 0===s?x.threshold:s,u=r.findAllMatches,l=void 0===u?x.findAllMatches:u,d=r.minMatchCharLength,f=void 0===d?x.minMatchCharLength:d,v=r.includeMatches,y=void 0===v?x.includeMatches:v,p=r.ignoreLocation,m=void 0===p?x.ignoreLocation:p;if(t.length>32)throw new Error(g(32));for(var b,k=t.length,M=e.length,w=Math.max(0,Math.min(o,M)),L=h,_=w,S=f>1||y,j=S?Array(M):[];(b=e.indexOf(t,_))>-1;){var E=O(t,{currentLocation:b,expectedLocation:w,distance:c,ignoreLocation:m});if(L=Math.min(E,L),_=b+k,S)for(var I=0;I=J;U-=1){var q=U-1,B=n[e.charAt(q)];if(S&&(j[q]=+!!B),T[U]=(T[U+1]<<1|1)&B,$&&(T[U]|=(C[U+1]|C[U])<<1|1|C[U+1]),T[U]&N&&(F=O(t,{errors:$,currentLocation:q,expectedLocation:w,distance:c,ignoreLocation:m}))<=L){if(L=F,(_=q)<=w)break;J=Math.max(1,2*w-_)}}var V=O(t,{errors:$+1,currentLocation:w,expectedLocation:w,distance:c,ignoreLocation:m});if(V>L)break;C=T}var G={isMatch:_>=0,score:Math.max(.001,F)};if(S){var H=A(j,f);H.length?y&&(G.indices=H):G.isMatch=!1}return G}(e,n,i,{location:a+o,distance:s,threshold:h,findAllMatches:u,minMatchCharLength:l,includeMatches:r,ignoreLocation:d}),m=p.isMatch,b=p.score,k=p.indices;m&&(y=!0),v+=b,m&&k&&(f=[].concat(c(f),c(k)))}));var p={isMatch:y,score:y?v/this.chunks.length:1};return y&&r&&(p.indices=f),p}}]),e}(),I=[];function C(e,t){for(var n=0,r=I.length;n-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function N(e,t){t.score=e.score}function $(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?x.includeMatches:r,o=n.includeScore,a=void 0===o?x.includeScore:o,c=[];return i&&c.push(P),a&&c.push(N),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return c.length&&c.forEach((function(t){t(e,r)})),r}))}var D=function(){function e(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2?arguments[2]:void 0;if(t(this,e),this.options=a({},x,{},r),this.options.useExtendedSearch)throw new Error("Extended search is not available");this._keyStore=new m(this.options.keys),this.setCollection(n,i)}return r(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof _))throw new Error("Incorrect 'index' type");this._myIndex=t||S(this.options.keys,this._docs,{getFn:this.options.getFn})}},{key:"add",value:function(e){f(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{},n=t.limit,r=void 0===n?-1:n,i=this.options,o=i.includeMatches,a=i.includeScore,c=i.shouldSort,s=i.sortFn,h=i.ignoreFieldNorm,d=u(e)?u(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return F(d,{ignoreFieldNorm:h}),c&&d.sort(s),l(r)&&r>-1&&(d=d.slice(0,r)),$(d,this._docs,{includeMatches:o,includeScore:a})}},{key:"_searchStringList",value:function(e){var t=C(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(f(n)){var a=t.searchIn(n),c=a.isMatch,s=a.score,h=a.indices;c&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:h}]})}})),r}},{key:"_searchLogical",value:function(e){throw new Error("Logical search is not available")}},{key:"_searchObjectList",value:function(e){var t=this,n=C(e,this.options),r=this._myIndex,i=r.keys,o=r.records,a=[];return o.forEach((function(e){var r=e.$,o=e.i;if(f(r)){var s=[];i.forEach((function(e,i){s.push.apply(s,c(t._findMatches({key:e,value:r[i],searcher:n})))})),s.length&&a.push({idx:o,item:r,matches:s})}})),a}},{key:"_findMatches",value:function(e){var t=e.key,n=e.value,r=e.searcher;if(!f(n))return[];var i=[];if(h(n))n.forEach((function(e){var n=e.v,o=e.i,a=e.n;if(f(n)){var c=r.searchIn(n),s=c.isMatch,h=c.score,u=c.indices;s&&i.push({score:h,key:t,value:n,idx:o,norm:a,indices:u})}}));else{var o=n.v,a=n.n,c=r.searchIn(o),s=c.isMatch,u=c.score,l=c.indices;s&&i.push({score:u,key:t,value:o,norm:a,indices:l})}return i}}]),e}();return D.version="6.4.6",D.createIndex=S,D.parseIndex=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?x.getFn:n,i=e.keys,o=e.records,a=new _({getFn:r});return a.setKeys(i),a.setIndexRecords(o),a},D.config=x,D},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Fuse=t(); /* Search function */ -document.addEventListener("DOMContentLoaded",function(){!function(e){"use strict";const t=document.body,n=document.querySelector(".search-section"),s=document.querySelectorAll(".search-open"),i=document.querySelector(".search-close"),c=document.querySelector(".search-input"),a=document.querySelector(".search-info"),o=document.querySelector(".search-counter"),r=document.querySelector(".search-results"),d=document.querySelector(".search-counter-results"),l=document.querySelector(".search-overlay");if(n){function u(){t.classList.remove("search-is-active"),t.classList.add("search-no-active"),c.value="",r.innerHTML="",o.classList.add("is-hide"),a.classList.remove("is-hide"),window.scrollTo(0,0)}t.addEventListener("keyup",function(e){27==e.keyCode&&u()}),i.addEventListener("click",u),l.addEventListener("click",u),s.forEach(function(s){s.addEventListener("click",function(){t.classList.add("search-is-active"),t.classList.remove("search-no-active"),n.style.display="block",c.focus()}),s.addEventListener("click",function(){if(!1===m){var t=options.api,n=new XMLHttpRequest;n.open("GET",t,!0),n.onload=function(){var e,t;n.status>=200&&n.status<400&&(n.response,e=JSON.parse(n.responseText),t=new Fuse(e.posts,options),c.onkeyup=function(e){if(d.innerHTML="",r.innerHTML="",this.value.length>2&&(a.classList.add("is-hide"),o.classList.remove("is-hide")),this.value.length<3&&(a.classList.remove("is-hide"),o.classList.add("is-hide")),!(this.value.length<=2)){const n=t.search(e.target.value,{limit:options.limit});d.innerHTML=n.length,n.map(function(e){var t=new Date(e.item.published_at).toLocaleDateString(document.documentElement.lang,{year:"numeric",month:"long",day:"numeric"}),n=document.createElement("time"),s=document.createElement("h5"),i=document.createElement("span"),c=document.createElement("a");if(!0===options.images){var a=document.createElement("img");null!==e.item.feature_image&&(a.setAttribute("src",e.item.feature_image),c.appendChild(a))}n.textContent=n.innerHTML+=t,i.textContent=e.item.title,c.setAttribute("href",e.item.url),s.appendChild(i),r.appendChild(c),c.appendChild(s),c.appendChild(n)})}})},n.send(),s.removeEventListener("click",e)}m=!0})});var m=!1}}(window)}); \ No newline at end of file +document.addEventListener("DOMContentLoaded",function(){!function(e){"use strict";const t=document.body,n=document.querySelector(".search-section"),s=document.querySelectorAll(".search-open"),i=document.querySelector(".search-close"),c=document.querySelector(".search-input"),a=document.querySelector(".search-info"),o=document.querySelector(".search-counter"),r=document.querySelector(".search-results"),d=document.querySelector(".search-counter-results"),l=document.querySelector(".search-overlay");if(n){function u(){t.classList.remove("search-is-active"),t.classList.add("search-no-active"),c.value="",r.innerHTML="",o.classList.add("is-hide"),a.classList.remove("is-hide"),window.scrollTo(0,0)}t.addEventListener("keyup",function(e){27==e.keyCode&&u()}),i.addEventListener("click",u),l.addEventListener("click",u),s.forEach(function(s){s.addEventListener("click",function(){t.classList.add("search-is-active"),t.classList.remove("search-no-active"),n.style.display="block",c.focus()}),s.addEventListener("click",function(){if(!1===m){var t=options.api,n=new XMLHttpRequest;n.open("GET",t,!0),n.onload=function(){var e,t;n.status>=200&&n.status<400&&(n.response,e=JSON.parse(n.responseText),t=new Fuse(e.posts,options),c.onkeyup=function(e){if(d.innerHTML="",r.innerHTML="",this.value.length>2&&(a.classList.add("is-hide"),o.classList.remove("is-hide")),this.value.length<3&&(a.classList.remove("is-hide"),o.classList.add("is-hide")),!(this.value.length<=2)){const n=t.search(e.target.value,{limit:options.limit});d.innerHTML=n.length,n.map(function(e){var t=new Date(e.item.published_at).toLocaleDateString(document.documentElement.lang,{year:"numeric",month:"long",day:"numeric"}),n=document.createElement("time"),s=document.createElement("h5"),i=document.createElement("span"),c=document.createElement("a");if(!0===options.images){var a=document.createElement("img");null!==e.item.feature_image&&(a.setAttribute("src",e.item.feature_image),c.appendChild(a))}n.textContent=n.innerHTML+=t,i.textContent=e.item.title,c.setAttribute("href",e.item.url),s.appendChild(i),r.appendChild(c),c.appendChild(s),c.appendChild(n)})}})},n.send(),s.removeEventListener("click",e)}m=!0})});var m=!1}}(window)}); + +/* Light/dark mode toggle */ +document.addEventListener("DOMContentLoaded",(()=>{const{classList:e}=document.documentElement;if(!e.contains("light-dark-mode"))return;const t="(prefers-color-scheme: dark)",d=()=>{const e=localStorage.getItem("theme"),d=window.matchMedia&&window.matchMedia(t).matches;return"dark"===e||"light"!==e&&d},a=()=>e[d()?"add":"remove"]("dark-mode");window.matchMedia(t)?.addEventListener("change",a),document.querySelectorAll("header .theme-toggle").forEach((e=>e.addEventListener("click",(()=>{localStorage.setItem("theme",d()?"light":"dark"),a()})))),a()})); \ No newline at end of file diff --git a/partials/header.hbs b/partials/header.hbs index b7d54fe..45c8fe8 100644 --- a/partials/header.hbs +++ b/partials/header.hbs @@ -2,6 +2,10 @@
+ + {{>icons/site/sun}} + {{>icons/site/moon}} + {{>search is_mobile=true}}