From 0e46e65034740ac9acb167f6bee2131fadc5ea29 Mon Sep 17 00:00:00 2001 From: Lee Cattarin Date: Wed, 9 Sep 2026 13:37:35 -0700 Subject: [PATCH] color picker yay --- _includes/footer.njk | 21 ++++++++ _includes/head-content.njk | 2 + css/main.css | 9 +++- css/nav.css | 105 +++++++++++++++++++++++++++++++++++++ eleventy.config.js | 1 + js/theme.js | 35 +++++++++++++ 6 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 js/theme.js diff --git a/_includes/footer.njk b/_includes/footer.njk index ec29e23d..8f59dfa2 100644 --- a/_includes/footer.njk +++ b/_includes/footer.njk @@ -21,4 +21,25 @@ + +
+ color scheme + + + + + + + + + +
diff --git a/_includes/head-content.njk b/_includes/head-content.njk index 36307a02..d6f377fb 100644 --- a/_includes/head-content.njk +++ b/_includes/head-content.njk @@ -38,4 +38,6 @@ +{# Scripts #} + diff --git a/css/main.css b/css/main.css index f1669ead..7e7dd561 100644 --- a/css/main.css +++ b/css/main.css @@ -51,6 +51,13 @@ --color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light)); } +:root:has(#theme-light:checked) { + color-scheme: light; +} +:root:has(#theme-dark:checked) { + color-scheme: dark; +} + /* Base */ * { @@ -194,7 +201,7 @@ ul, ol, dl, li { } li { - line-height: 1.2 5; + line-height: 1.2; margin-top: .65rem; margin-bottom: .65rem; } diff --git a/css/nav.css b/css/nav.css index 899a8b5c..5405392c 100644 --- a/css/nav.css +++ b/css/nav.css @@ -241,6 +241,111 @@ footer a:focus-visible { outline-color: var(--color-pink); } +/* color picker */ +#theme { + display: flex; + justify-content: center; + margin: .5rem auto 0; + padding: 0 .75rem .5rem; + width: fit-content; + border: .125rem solid var(--color-teal); + border-radius: 2rem; +} + +#theme legend { + margin: 0 auto; + color: var(--color-teal); +} + +footer label { + cursor: pointer; + border: .125rem solid var(--color-pink); + padding: 0 .25rem; + color: var(--color-pink); + background-color: var(--color-bg); /* this stops the box shadows from showing through */ + box-shadow: .15em .15em var(--color-shadow); + /* Click animation handling */ + position: relative; + top: 0; + left: 0; + transition: top .05s ease-in, left .05s ease-in; +} + +footer input:checked + label { + color: var(--color-blue); + border-color: var(--color-blue); +} + +footer label i { + color: var(--color-teal); +} + +footer input:checked + label i { + color: var(--color-pink); +} + +@media (any-hover: hover) { + footer label:hover, + footer input:checked + label:hover, + footer label:hover i, + footer input:checked + label:hover i { + color: var(--color-bg); + } + + footer label:hover { + background-color: var(--color-pink); + } + + footer input:checked + label:hover { + background-color: var(--color-teal); + } +} + +footer input:focus-visible + label, +footer input:focus-visible + label i { + color: var(--color-bg); + background-color: var(--color-pink); + border-color: var(--color-pink); +} + +footer input:checked:focus-visible + label, +footer input:checked:focus-visible + label i { + color: var(--color-bg); + background-color: var(--color-teal); + border-color: var(--color-teal); +} + +footer label:active { + top: .09em; + left: .09em; + box-shadow: .05em .05em var(--color-shadow); +} + +label.theme-light { + border-top-left-radius: 1rem; + border-bottom-left-radius: 1rem; + border-right: none; + padding-left: .35rem; +} + +label.theme-auto { +} + +label.theme-dark { + border-top-right-radius: 1rem; + border-bottom-right-radius: 1rem; + border-left: none; + padding-right: .35rem; +} + +footer input { + /* To allow screen reader to still access these. */ + /* From https://lyra.horse/blog/2025/08/you-dont-need-js/ */ + opacity: 0; + position: absolute; + pointer-events: none; +} + /* Pagination */ .pagination, .pagination li { diff --git a/eleventy.config.js b/eleventy.config.js index 7e575612..d44d67a7 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -135,6 +135,7 @@ export default async function(eleventyConfig) { /* Watch when serving */ eleventyConfig.addWatchTarget("css"); + eleventyConfig.addWatchTarget("js"); }; export const config = { diff --git a/js/theme.js b/js/theme.js new file mode 100644 index 00000000..f5339ef0 --- /dev/null +++ b/js/theme.js @@ -0,0 +1,35 @@ +const THEME = "theme"; + +const saveTheme = (themeValue) => { + localStorage.setItem(THEME, themeValue); +}; + +const themeLight = document.getElementById("theme-light"); +themeLight.addEventListener("input", (e) => { + saveTheme(themeLight.value); +}); + +const themeAuto = document.getElementById("theme-auto"); +themeAuto.addEventListener("input", (e) => { + saveTheme(themeAuto.auto); +}); + +const themeDark = document.getElementById("theme-dark"); +themeDark.addEventListener("input", (e) => { + saveTheme(themeDark.value); +}); + +var currentThemeValue = localStorage.getItem(THEME); +switch (currentThemeValue) { + case "light": + themeLight.checked = true; + break; + case "auto": + themeAuto.checked = true; + break; + case "dark": + themeDark.checked = true; + break; + default: + themeAuto.checked = true; +}