finished settings for theme, contrast, and scale didn't commit for a day again because im a bozo
sophuwu sophie@skisiel.com
Wed, 19 Feb 2025 09:43:29 +0100
3 files changed,
258 insertions(+),
253 deletions(-)
M
dark_theme.css
→
dark_theme.css
@@ -1,38 +1,23 @@
- - - +:root{ + --dark: #262833; + --light: #ffffff; + --warm: #FFFF99; - @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap'); - -:root{ - /* - --theme: <integer 0-5>; - * sets the theme color, 4 is the default. 0 white, 1-3 add yellow filter. 4 is dark, 5 changes header+link colors. - --contrast: <bool 0/1>; - * sets high contrast, 0 is the default. - --font: string; - * sets the font, 'JetBrains Mono' will be used from google fonts if not set. - --font-size: <float><unit>; - * sets the font size, 18px is the default. - */ + --cont: calc(20% * var(--contrast,1)); - --col: var(--theme, 4); - --cont: calc(70% + (30% * var(--contrast,0))); - --dark-bg: #262833; + --bg-color: var(--theme, var(--dark)); - --sepia: color-mix(in srgb, white, yellow calc( 10% * (var(--col) + 2) * (min(1,var(--col))))); - --bg-color: color-mix(in srgb, var(--sepia), var(--dark-bg) calc(0% + (100% * (max(0,calc(var(--col) - 3)))))); --st-color: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) calc(255 - b)); - --fg-color: color-mix(in srgb, var(--bg-color), var(--st-color) var(--cont)); - --it-color: color-mix(in srgb, var(--bg-color), var(--fg-color) var(--cont)); + --fg-color: color-mix(in srgb, var(--st-color), var(--bg-color) var(--cont)); + --it-color: color-mix(in srgb, var(--fg-color), var(--bg-color) var(--cont)); - --hl-color: color-mix(in srgb, #8d53a6, #ff4500 calc(0% + (100% * (max(0,calc(var(--col) - 4)))))); - --rf-color: color-mix(in srgb, #ff7597, #4c86ce calc(0% + (100% * (max(0,calc(var(--col) - 4)))))); - --rf-hover: color-mix(in srgb, var(--rf-color), var(--st-color) 40%); + --hl-color: #ff7597; + --rf-color: #5da5ff; + --rf-hover: #40d8ff; - --dimmer: rgba(0,0,0,69); - --lessdimmer: rgba(0,0,0,20%); + --dimmer: color-mix(in srgb, var(--fg-color), var(--bg-color) 70%); + --dim: color-mix(in srgb, var(--fg-color), var(--bg-color) 80%); font-variant-ligatures: none!important; --font-family: var(--font, 'JetBrains Mono');@@ -59,15 +44,13 @@ }
@media (max-width: 400px) { --x-font-size: 10px; } - font-size: var(--font-size, var(--x-font-size)); + font-size: calc( var(--scale,1) * var(--x-font-size) ); } *{ color: var(--fg-color); font-family: var(--font-family), monospace; line-height: 1em; - padding: 0; - transition: all 150ms ease-in-out; } body, html { margin: 0;@@ -76,77 +59,6 @@ height: 100%;
width: 100%; background-color: var(--bg-color); } -article.hidden { - display: none!important; - height: 0!important; -} -togii { - background-color: color-mix(in srgb, var(--hl-color), var(--bg-color) 50%); -} -.settings { - display: contents; - input { - &[type=range] { - margin: 0; - &[id="theme"] { - width: 100%; - --grad0: 0; - --grad1: 1; - --grad2: 2; - --grad3: 3; - --grad4: 4; - --grad5: 5; - --graddy: 18%; - background-image: linear-gradient(90deg, color-mix(in srgb, color-mix(in srgb, white, yellow calc( 10% * (var(--grad0) + 2) * (min(1,var(--grad0))))), var(--dark-bg) calc(0% + (100% * (max(0,calc(var(--grad0) - 3)))))) calc(var(--grad0) * var(--graddy)), - color-mix(in srgb, color-mix(in srgb, white, yellow calc( 10% * (var(--grad1) + 2) * (min(1,var(--grad1))))), var(--dark-bg) calc(0% + (100% * (max(0,calc(var(--grad1) - 3)))))) calc(var(--grad1) * var(--graddy)), - color-mix(in srgb, color-mix(in srgb, white, yellow calc( 10% * (var(--grad2) + 2) * (min(1,var(--grad2))))), var(--dark-bg) calc(0% + (100% * (max(0,calc(var(--grad2) - 3)))))) calc(var(--grad2) * var(--graddy)), - color-mix(in srgb, color-mix(in srgb, white, yellow calc( 10% * (var(--grad3) + 2) * (min(1,var(--grad3))))), var(--dark-bg) calc(0% + (100% * (max(0,calc(var(--grad3) - 3)))))) calc(var(--grad3) * var(--graddy)), - color-mix(in srgb, color-mix(in srgb, white, yellow calc( 10% * (var(--grad4) + 2) * (min(1,var(--grad4))))), var(--dark-bg) calc(0% + (100% * (max(0,calc(var(--grad4) - 3)))))) calc(var(--grad4) * var(--graddy)), - color-mix(in srgb, color-mix(in srgb, white, yellow calc( 10% * (var(--grad5) + 2) * (min(1,var(--grad5))))), var(--dark-bg) calc(0% + (100% * (max(0,calc(var(--grad5) - 3)))))) calc(var(--grad5) * var(--graddy)))!important; - } - &[id="contrast"] { - width: 2rem; - background: var(--lessdimmer); - } - - } - height:1rem; - &[type="text"]{ - font-size: 0.7rem; - padding: 0.2em 1ch; - margin: -0.2em -1ch; - } - border: 1px solid var(--fg-color); - border-radius: 0.5rem; - border-color: var(--fg-color); - background: var(--lessdimmer); - } - - .slider::-webkit-slider-thumb, .slider::-moz-range-thumb { - width: calc(100% / 12); - min-width: 1rem; - background: var(--hl-color); - height: calc(1rem - 0.1em); - } - height: 100%!important; - tr > th { - width: 100%; - margin: 0; - } - td { - padding: 0.5ch; - margin: auto; - } - label { - display: contents; - } - input#font { - width: 100%; - } - table { - margin: 0 auto 0 auto; - } -} table.head, table.foot { width: inherit; }@@ -171,7 +83,7 @@ }
code.Nm, .Fl, .Cm, .Ic, code.In, .Fd, .Fn, .Cd { font-weight: bold; } -i, em, hr { +i, em { color: var(--it-color); } dt, b, strong {@@ -179,6 +91,7 @@ color: var(--st-color);
} hr { margin: 5px 0; + color: var(--fg-color); } form{ padding:0;@@ -213,63 +126,75 @@ align-content: space-between;
align-items: center; } header { - width: calc( 100% - 1em ); + width: calc(100% - 1em); padding: 0.5lh 0; margin: 0; background-color: var(--bg-color); border-bottom: var(--fg-color) 1px solid; display: flex; flex-direction: row; - align-content: center; - justify-content: center; + justify-content: space-between; +} +header > form { + display: contents; +} +header > div { + display: inherit; +} +header h3 { + margin: auto 0 auto 0; + font-size: 1.15rem; +} +header.settings :not(:first-child) h3 { + font-size: 0.9rem; + margin-right: 1ch; + color: var(--st-color); +} +.rounded > * { + background-color: inherit; + border: 1px var(--fg-color); + font-size: 1rem; + margin: 0 !important; + padding: 0.1em 1ch; + border-style: solid none solid solid; +} +.rounded > :first-child { + border-radius: 1ch 0 0 1ch; + border-style: solid none solid solid; + margin-left: auto !important; +} - form, div{ - display: contents; - * { - background-color: inherit; - border: 1px var(--fg-color); - font-size: 1rem; - margin: 0!important; - padding: 0.1em 1ch; - border-style: solid none solid solid ; - } - :first-child { - border-radius: 1ch 0 0 1ch; - border-style: solid none solid solid; - margin-left: auto!important;; - } - :last-child { - border-radius: 0 1ch 1ch 0; - border-style: solid; - margin-right: auto!important;; - } - input:not([type="submit"]){ - font-size: 0.9em; - width: 100%; - max-width: 50ch; - } - h3, input[type="submit"], button { - min-width: fit-content; - } - input[type="submit"], button { - font-weight: bold; - cursor: pointer; - } - :is(input[type="submit"], button):hover { - background: var(--dimmer); - } - /*h3{*/ - /* border: none 0;*/ - /* font-size: 1.2rem;*/ - /* padding: 0.1em 1ch;*/ - /*}*/ - } - * { - height: inherit; - } +.rounded > :last-child { + border-radius: 0 1ch 1ch 0; + border-style: solid; + margin-right: auto !important; +} + +header > * > * { + min-width: fit-content; +} + +.txt { + font-size: 0.9em; + width: 100%; + max-width: 50ch; +} + +.submit, button { + font-weight: bold; + cursor: pointer; } +button:hover, .submit:hover { + background: var(--dim); +} +buttton:focus, .submit:focus, .txt:focus { + background: var(--dimmer); +} +header * { + height: inherit; +} main{ width: calc( 100% - 1em ); height: 100%;@@ -277,6 +202,18 @@ margin: 0 auto 0 auto;
overflow: auto; padding: 0; } +.hidden { + display: none!important; + height: 0!important; +} +.settings h4 { - +} +.settings div.rounded { + display: contents; +} +.butt-set { + background-color: var(--it-color); + color: var(--bg-color); +}
M
index.html
→
index.html
@@ -1,6 +1,9 @@
<!DOCTYPE html> <html lang="en"> <head> + <link rel="preconnect" href="https://fonts.googleapis.com"> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap" rel="stylesheet"> <meta charset="utf-8"> <title>{{ title }}@{{ hostname }}</title> <style id="styleCss">@@ -11,45 +14,55 @@ {{ jsContent }}
</script> </head> <body> - - <header> + <header class="menu" id="search"> <div> - <h3>ManWeb</h3> - <h3>@{{ hostname }}</h3> + <h3>ManWeb @{{ hostname }}</h3> </div> - <form method="post"> - <h3>Find:</h3> - <input type="text" name="q" autocomplete="off" value="{{ query }}"> - <input type="submit" value="Search"> + <form class="rounded" method="post"> + <input type="text" class="txt" name="q" autocomplete="off" value="{{ query }}"> + <input type="submit" class="submit" value="Search"> </form> + <div class="rounded"> + <button id="helpButt">Help</button> + <button onclick="Menu(H(this).l)">Settings</button> + </div> + </header> + <header class="settings menu hidden" id="settings"> <div> - <button id="helpButt">Help</button> - <button id="SetButt">Settings</button> + <h3>Settings</h3> + </div> + <div> + <h3>Theme</h3> + <div class="rounded"> + <button>Dark</button> + <button>Light</button> + <button>Warm</button> + </div> + </div> + <div> + <h3>Contrast</h3> + <div class="rounded"> + <button>Low</button> + <button>Medium</button> + <button>High</button> + </div> + </div> + <div> + <h3>Scale</h3> + <div class="rounded"> + <button>-</button> + <label id="scaleVal">100%</label> + <button>+</button> + </div> + </div> + <div> + <div class="rounded"> + <button onclick="ResetStyle()">Reset</button> + <button onclick="Menu()">Close</button> + </div> </div> </header> - - <main> - <article class="settings hidden"> - <table> - <tr> - <td>Theme</td> - <td><input type="range" min="0" max="5" value="4" id="theme" class="slider"></td> - </tr> - <tr class="yeet"> - <td> - <label>High Contrast</label> - <input readonly type="range" min="0" max="1" value="0" id="contrast" class="slider"></td> - <td> - <label>Font Size</label> - <input type="text" id="fontsize" placeholder="e.g. 18px"></td> - </tr> - <tr> - <td>Custom Font</td> - <td><input type="text" id="font" placeholder="e.g. Helvetica"></td> - </tr> - </table> - <hr> - </article> + <main id="main-content"> {{ content }} </main> </body>
M
scripts.js
→
scripts.js
@@ -1,86 +1,141 @@
- /* - --theme: <integer 0-5>; - * sets the theme color, 4 is the default. 0 white, 1-3 add yellow filter. 4 is dark, 5 changes header+link colors. - --contrast: <bool 0/1>; - * sets high contrast, 0 is the default. - --font: string; - * sets the font, 'JetBrains Mono' will be used from google fonts if not set. - --font-size: <float><unit>; - * sets the font size, 18px is the default. - */ +const style = document.getElementById("styleCss"); +const styleCss = style.innerHTML; + +const ValidKeys = ["theme", "contrast", "scale"]; +const Valid_theme = ["dark", "warm", "light"]; +const Valid_contrast = ["low", "medium", "high"]; +const Valid_scale = ["-", "0", "+"]; + -const CSSRx = /^(((\d+(\.\d+)?)(%|p[xtc]|r?em|ex|ch|v(min|max|w|h)|([cm]m)|in))|(((?<x>x{1,3}-)?(small|larg)e?((?<=\k<x>)r)?)|medium|normal))$/; +function SetStyle() { + let tmp = ":root {\n"; + ValidKeys.forEach(key => { + let value = localStorage.getItem(key); + if (value) tmp += "--" + key + ": " + value + ";\n"; + }); + tmp += "}\n\n"; + style.innerHTML = tmp + styleCss; + ValidKeys.forEach(key => function (key) { + if (butts[key]["arr"].length < 3) return; + let value = localStorage.getItem(key); + if (!value) { + if (key == "theme") value = "dark"; + else if (key == "contrast") value = 1; + else return; + } + if (value >= 0 && value <= 2) value = Valid_contrast[value]; + else if (value.startsWith("var(--")) value = value.substring("var(--".length, value.length - 1); + butts[key]["arr"].forEach(b => b.classList.remove("butt-set")); + butts[key]["map"][value].classList.add("butt-set"); + }(key)); +} +function SaveValue(key, value) { + if (!ValidKeys.includes(key)) return; + localStorage.setItem(key, value); + SetStyle(); +} -let funcmap = { - "--theme": function (value) { - let v = parseInt(value); - return (v < 0 || v > 5) - }, - "--contrast": function (value) { - let v = parseInt(value); - return (v < 0 || v > 1) - }, - "--font": function (value) { - return (value.length < 1) - }, - "--font-size": function (value) { - return !CSSRx.test(value) +function SetTheme(theme=null) { + if (theme==null) { + let value = localStorage.getItem("theme"); + if (!value) value = "var(--dark)"; + value = value.replace("var(--", "").replace(")", ""); + HlButt("theme", value); } -}; + if (!Valid_theme.includes(theme)) return; + theme = "var(--" + theme + ")"; + SaveValue("theme", theme); +} +function SetContrast(contrast=null) { + if (contrast==null) { -function SaveValue(key, value) { - let fn = funcmap[key] - if (typeof(fn) != "function"||fn(value)) { - return false; + if (!value) value = "1"; + value = Valid_contrast[value]; + HlButt("contrast", value); } - localStorage.setItem(key, value); - return true; + if (!Valid_contrast.includes(contrast)) return; + SaveValue("contrast", Valid_contrast.indexOf(contrast)); +} + +function SetScale(scale) { + if (!Valid_scale.includes(scale)) return; + let value = localStorage.getItem("scale"); + if (!value) value = 1; + let diff = (0.1 * (Valid_scale.indexOf(scale) - 1)); + if (diff != 0) { + value = parseFloat(value) + diff; + if (value < 0.1) value = 0.1; + if (value > 2) value = 2; + value = value.toFixed(1); + SaveValue("scale", value); + } + document.getElementById("scaleVal").innerHTML = (value*100).toFixed(0) + "%" } -function DeleteValue(key) { - localStorage.removeItem(key); +function ResetStyle() { + ValidKeys.forEach(key => { + localStorage.removeItem(key); + }); + SetStyle(); + SetScale("0"); +} +function H(elem) { + return {l: elem.innerHTML.toLowerCase(), n: elem.innerHTML}; } -// var style = document.createElement('style'); -// style.innerText += document.styleSheets[0].cssRules[0].cssText; -// const styleCss = style.innerText; -// style.id = "styleCss"; -// document.head.appendChild(style); +function Menu(wants="search"){ + let mainClick = [`document.getElementById("main-content").`,`EventListener("click", function () {Menu()})`]; -const style = document.getElementById("styleCss"); -const styleCss = style.innerText; + let n = document.getElementById(wants); + if (!n || !n.classList.contains("menu")) return; -function setStyle() { - let tmp = ":root{\n"; - let ar = ["--theme", "--contrast", "--font", "--font-size"]; - for (let key of ar) { - let value = localStorage.getItem(key); - if (value) tmp += `${key}:${value};` + "\n"; - } - tmp += "}"; - style.innerText = tmp + styleCss; + eval(mainClick.join(function (b){ + if (b) return "remove"; + return "add"; + }(wants == "search"))); + + let l = function (elem) {return { + e: function (e){e==elem}, + h: elem.classList.contains("hidden"), + t: function () {elem.classList.toggle("hidden")}, + };}; + document.querySelectorAll(".menu").forEach(ee => function (e){ + if (e.e(n) || e.h) return; + e.t(); + }(l(ee))); + n = l(n); + if (n.h) n.t(); } -document.addEventListener("DOMContentLoaded", setStyle); +function Butt() { + let butts = new Object(); + ValidKeys.forEach(key => function (key) { + butts[key]=new Object(); + eval("Valid_"+key).forEach(v => function (v) { + butts[key][v]=null; + }(v)); + }(key)); + return butts; +}; + +var butts = Object(); + document.addEventListener("DOMContentLoaded", function () { - document.getElementById("SetButt").addEventListener("click", function () { - let ar = ["--theme", "--contrast", "--font", "--font-size"]; - for (let key of ar) { - let value = localStorage.getItem(key); - if (value) document.getElementById(key.replaceAll("-", "")).value = value; - } - document.querySelector("article.settings").classList.toggle("hidden"); - }); - document.getElementById("contrast").addEventListener("mousedown", function () { - let elem = document.getElementById("contrast"); - if (elem.value == 1) elem.value = 0; - else elem.value = 1; - elem.classList.toggle("togii"); - if (SaveValue("--contrast", elem.value))setStyle(); - }); - document.getElementById("theme").addEventListener("input", function () { - if (SaveValue("--theme", document.getElementById("theme").value))setStyle(); - }); + document.querySelectorAll("#settings > div > h3").forEach(elemH => function (elemH,n) { + if (!ValidKeys.includes(n.l)) return; + butts[n.l]= new Object({}); + butts[n.l]["h"] = elemH; + butts[n.l]["div"] = elemH.parentElement; + butts[n.l]["arr"] = []; + butts[n.l]["map"] = new Object({}); + elemH.parentElement.querySelectorAll("button").forEach(butt => function (butt, fun, v) { + let i = butts[n.l]["arr"].push(butt); + butts[n.l]["map"][v] = butts[n.l]["arr"][i-1]; + butt.addEventListener("click", function () {fun(v)}); + }(butt,eval("Set" + n.n), H(butt).l)); + }(elemH,H(elemH))); + SetStyle(); + SetScale("0"); });