commit 6473c4dc26d0a4c82b21295231c1347182029aa0
parent 8495cfcd08f81e1a9719e1dc8af559eb38882997
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Wed, 20 Nov 2024 17:12:29 -0300
add dark scheme toggle button; use css variables to define colors
Diffstat:
7 files changed, 227 insertions(+), 128 deletions(-)
diff --git a/common/head.shtml b/common/head.shtml
@@ -9,5 +9,9 @@
type="text/css"
crossorigin="anonymous"/>
+<link
+ rel="stylesheet"
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0&icon_names=contrast"/>
+
<link rel='stylesheet' type='text/css' href="/css/style.css?ver=0.4">
<link rel="icon" type="image/x-icon" href="favicon.webp">
diff --git a/common/header.shtml b/common/header.shtml
@@ -10,6 +10,11 @@
<li class="header_button" style="padding-right: 14px"><a href="/files" style="text-decoration: none;">files</a></li>
<li class="header_button" style="padding-right: 0px"><a href="/about" style="text-decoration: none;">about</a></li>
</ul>
+ <a title="Toggle color scheme" id="color-scheme-button" onClick="toggleColorScheme()">
+<svg id="color-scheme-button-dark" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M480-360q50 0 85-35t35-85q0-50-35-85t-85-35q-50 0-85 35t-35 85q0 50 35 85t85 35Zm0 80q-83 0-141.5-58.5T280-480q0-83 58.5-141.5T480-680q83 0 141.5 58.5T680-480q0 83-58.5 141.5T480-280ZM200-440H40v-80h160v80Zm720 0H760v-80h160v80ZM440-760v-160h80v160h-80Zm0 720v-160h80v160h-80ZM256-650l-101-97 57-59 96 100-52 56Zm492 496-97-101 53-55 101 97-57 59Zm-98-550 97-101 59 57-100 96-56-52ZM154-212l101-97 55 53-97 101-59-57Zm326-268Z"/></svg><svg id="color-scheme-button-light" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M480-120q-150 0-255-105T120-480q0-150 105-255t255-105q14 0 27.5 1t26.5 3q-41 29-65.5 75.5T444-660q0 90 63 153t153 63q55 0 101-24.5t75-65.5q2 13 3 26.5t1 27.5q0 150-105 255T480-120Zm0-80q88 0 158-48.5T740-375q-20 5-40 8t-40 3q-123 0-209.5-86.5T364-660q0-20 3-40t8-40q-78 32-126.5 102T200-480q0 116 82 198t198 82Zm-10-270Z"/></svg>
+ </a>
</div>
+ <script type="text/javascript" src="/scripts/js/color-scheme-toggle.js"></script>
</header>
+
<hr class="header_bottom_bar">
diff --git a/css/article.css b/css/article.css
@@ -9,7 +9,7 @@
font-size: 1em;
padding-bottom: 2.75em;
/* color: #588B8B; */
- color: #9D96B8;
+ color: var(--article-date);
font-style: italic;
font-family: "inconsolata", monospace;
}
@@ -213,86 +213,3 @@ ul {
}
h2 { padding-bottom: .5em; }
}
-
-@media (prefers-color-scheme: light) {
- .article-date {
- color: #7E5A9B;
- }
- .article_bottom_bar{
- border-top: 1px dashed white;
- }
-
- /* Monokai light theme */
- /* Background */ .bg { color: #272822; background-color: #fafafa; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4 }
- /* PreWrapper */ .chroma { color: #272822; background-color: #fafafa; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; }
- /* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
- /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
- /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
- /* LineHighlight */ .chroma .hl { background-color: #e1e1e1 }
- /* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
- /* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
- /* Line */ .chroma .line { display: flex; }
- /* Keyword */ .chroma .k { color: #00a8c8 }
- /* KeywordConstant */ .chroma .kc { color: #00a8c8 }
- /* KeywordDeclaration */ .chroma .kd { color: #00a8c8 }
- /* KeywordNamespace */ .chroma .kn { color: #f92672 }
- /* KeywordPseudo */ .chroma .kp { color: #00a8c8 }
- /* KeywordReserved */ .chroma .kr { color: #00a8c8 }
- /* KeywordType */ .chroma .kt { color: #00a8c8 }
- /* Name */ .chroma .n { color: #111111 }
- /* NameAttribute */ .chroma .na { color: #75af00 }
- /* NameBuiltin */ .chroma .nb { color: #111111 }
- /* NameBuiltinPseudo */ .chroma .bp { color: #111111 }
- /* NameClass */ .chroma .nc { color: #75af00 }
- /* NameConstant */ .chroma .no { color: #00a8c8 }
- /* NameDecorator */ .chroma .nd { color: #75af00 }
- /* NameEntity */ .chroma .ni { color: #111111 }
- /* NameException */ .chroma .ne { color: #75af00 }
- /* NameFunction */ .chroma .nf { color: #75af00 }
- /* NameFunctionMagic */ .chroma .fm { color: #111111 }
- /* NameLabel */ .chroma .nl { color: #111111 }
- /* NameNamespace */ .chroma .nn { color: #111111 }
- /* NameOther */ .chroma .nx { color: #75af00 }
- /* NameProperty */ .chroma .py { color: #111111 }
- /* NameTag */ .chroma .nt { color: #f92672 }
- /* NameVariable */ .chroma .nv { color: #111111 }
- /* NameVariableClass */ .chroma .vc { color: #111111 }
- /* NameVariableGlobal */ .chroma .vg { color: #111111 }
- /* NameVariableInstance */ .chroma .vi { color: #111111 }
- /* NameVariableMagic */ .chroma .vm { color: #111111 }
- /* Literal */ .chroma .l { color: #ae81ff }
- /* LiteralDate */ .chroma .ld { color: #d88200 }
- /* LiteralString */ .chroma .s { color: #d88200 }
- /* LiteralStringAffix */ .chroma .sa { color: #d88200 }
- /* LiteralStringBacktick */ .chroma .sb { color: #d88200 }
- /* LiteralStringChar */ .chroma .sc { color: #d88200 }
- /* LiteralStringDelimiter */ .chroma .dl { color: #d88200 }
- /* LiteralStringDoc */ .chroma .sd { color: #d88200 }
- /* LiteralStringDouble */ .chroma .s2 { color: #d88200 }
- /* LiteralStringEscape */ .chroma .se { color: #8045ff }
- /* LiteralStringHeredoc */ .chroma .sh { color: #d88200 }
- /* LiteralStringInterpol */ .chroma .si { color: #d88200 }
- /* LiteralStringOther */ .chroma .sx { color: #d88200 }
- /* LiteralStringRegex */ .chroma .sr { color: #d88200 }
- /* LiteralStringSingle */ .chroma .s1 { color: #d88200 }
- /* LiteralStringSymbol */ .chroma .ss { color: #d88200 }
- /* LiteralNumber */ .chroma .m { color: #ae81ff }
- /* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
- /* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
- /* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
- /* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
- /* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
- /* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
- /* Operator */ .chroma .o { color: #f92672 }
- /* OperatorWord */ .chroma .ow { color: #f92672 }
- /* Punctuation */ .chroma .p { color: #111111 }
- /* Comment */ .chroma .c { color: #75715e }
- /* CommentHashbang */ .chroma .ch { color: #75715e }
- /* CommentMultiline */ .chroma .cm { color: #75715e }
- /* CommentSingle */ .chroma .c1 { color: #75715e }
- /* CommentSpecial */ .chroma .cs { color: #75715e }
- /* CommentPreproc */ .chroma .cp { color: #75715e }
- /* CommentPreprocFile */ .chroma .cpf { color: #75715e }
- /* GenericEmph */ .chroma .ge { font-style: italic }
- /* GenericStrong */ .chroma .gs { font-weight: bold }
-}
diff --git a/css/blog.css b/css/blog.css
@@ -1,17 +1,14 @@
-#blog-index-tbody #date a {
- color: antiquewhite;
- text-decoration: none;
- padding-right: 5px;
-}
+@import "/css/colors.css";
-#blog-index-tbody #date {
+#blog-index-table #date {
text-wrap: nowrap;
vertical-align: top;
+ a {
+ color: var(--fg-color);
+ text-decoration: none;
+ padding-right: 5px;
+ font-family: "inconsolata", monospace;
+ }
}
-
-@media (prefers-color-scheme: light) {
- #blog-index-tbody #date a {
- color: #000000;
- }
}
diff --git a/css/colors.css b/css/colors.css
@@ -0,0 +1,107 @@
+:root, [data-theme="dark"] {
+ --bg-color: #191919;
+ --fg-color: antiquewhite;
+ --accent-color: crimson;
+ --secondary-accent-color: peru;
+ --hover-color: peru;
+ --code-bg: #303030;
+ --link-color: peru;
+ --link-hover-color: crimson;
+ --title-color: #DAA520;
+ --pre-bg-color: #292929;
+ --pre-border-color: #6A6A6A;
+ --article-date: #9D96B8;
+ --grey1: #3C3C3C;
+}
+
+[data-theme="light"] {
+ --fg-color: #000000;
+ --bg-color: white;
+ --accent-color: #CC2936;
+ --secondary-accent-color: #141414;
+ --hover-color: #a04a00;
+ --link-hover-color: #CC2936;
+ --link-color: #A04A00;
+ --title-color: #000000;
+ --pre-color: rgba(190,198,219,0.2);
+ --pre-border-color: #aaa;
+ /* --code-bg: #656c76; */
+ --code-bg: rgba(190,198,219,0.2);
+ --article-date: #7E5A9B;
+ --grey1: #D0D0D0;
+
+ /* Monokai light theme */
+ /* Background */ .bg { color: #272822; background-color: #fafafa; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4 }
+ /* PreWrapper */ .chroma { color: #272822; background-color: #fafafa; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; }
+ /* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
+ /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
+ /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
+ /* LineHighlight */ .chroma .hl { background-color: #e1e1e1 }
+ /* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+ /* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+ /* Line */ .chroma .line { display: flex; }
+ /* Keyword */ .chroma .k { color: #00a8c8 }
+ /* KeywordConstant */ .chroma .kc { color: #00a8c8 }
+ /* KeywordDeclaration */ .chroma .kd { color: #00a8c8 }
+ /* KeywordNamespace */ .chroma .kn { color: #f92672 }
+ /* KeywordPseudo */ .chroma .kp { color: #00a8c8 }
+ /* KeywordReserved */ .chroma .kr { color: #00a8c8 }
+ /* KeywordType */ .chroma .kt { color: #00a8c8 }
+ /* Name */ .chroma .n { color: #111111 }
+ /* NameAttribute */ .chroma .na { color: #75af00 }
+ /* NameBuiltin */ .chroma .nb { color: #111111 }
+ /* NameBuiltinPseudo */ .chroma .bp { color: #111111 }
+ /* NameClass */ .chroma .nc { color: #75af00 }
+ /* NameConstant */ .chroma .no { color: #00a8c8 }
+ /* NameDecorator */ .chroma .nd { color: #75af00 }
+ /* NameEntity */ .chroma .ni { color: #111111 }
+ /* NameException */ .chroma .ne { color: #75af00 }
+ /* NameFunction */ .chroma .nf { color: #75af00 }
+ /* NameFunctionMagic */ .chroma .fm { color: #111111 }
+ /* NameLabel */ .chroma .nl { color: #111111 }
+ /* NameNamespace */ .chroma .nn { color: #111111 }
+ /* NameOther */ .chroma .nx { color: #75af00 }
+ /* NameProperty */ .chroma .py { color: #111111 }
+ /* NameTag */ .chroma .nt { color: #f92672 }
+ /* NameVariable */ .chroma .nv { color: #111111 }
+ /* NameVariableClass */ .chroma .vc { color: #111111 }
+ /* NameVariableGlobal */ .chroma .vg { color: #111111 }
+ /* NameVariableInstance */ .chroma .vi { color: #111111 }
+ /* NameVariableMagic */ .chroma .vm { color: #111111 }
+ /* Literal */ .chroma .l { color: #ae81ff }
+ /* LiteralDate */ .chroma .ld { color: #d88200 }
+ /* LiteralString */ .chroma .s { color: #d88200 }
+ /* LiteralStringAffix */ .chroma .sa { color: #d88200 }
+ /* LiteralStringBacktick */ .chroma .sb { color: #d88200 }
+ /* LiteralStringChar */ .chroma .sc { color: #d88200 }
+ /* LiteralStringDelimiter */ .chroma .dl { color: #d88200 }
+ /* LiteralStringDoc */ .chroma .sd { color: #d88200 }
+ /* LiteralStringDouble */ .chroma .s2 { color: #d88200 }
+ /* LiteralStringEscape */ .chroma .se { color: #8045ff }
+ /* LiteralStringHeredoc */ .chroma .sh { color: #d88200 }
+ /* LiteralStringInterpol */ .chroma .si { color: #d88200 }
+ /* LiteralStringOther */ .chroma .sx { color: #d88200 }
+ /* LiteralStringRegex */ .chroma .sr { color: #d88200 }
+ /* LiteralStringSingle */ .chroma .s1 { color: #d88200 }
+ /* LiteralStringSymbol */ .chroma .ss { color: #d88200 }
+ /* LiteralNumber */ .chroma .m { color: #ae81ff }
+ /* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
+ /* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
+ /* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
+ /* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
+ /* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
+ /* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
+ /* Operator */ .chroma .o { color: #f92672 }
+ /* OperatorWord */ .chroma .ow { color: #f92672 }
+ /* Punctuation */ .chroma .p { color: #111111 }
+ /* Comment */ .chroma .c { color: #75715e }
+ /* CommentHashbang */ .chroma .ch { color: #75715e }
+ /* CommentMultiline */ .chroma .cm { color: #75715e }
+ /* CommentSingle */ .chroma .c1 { color: #75715e }
+ /* CommentSpecial */ .chroma .cs { color: #75715e }
+ /* CommentPreproc */ .chroma .cp { color: #75715e }
+ /* CommentPreprocFile */ .chroma .cpf { color: #75715e }
+ /* GenericEmph */ .chroma .ge { font-style: italic }
+ /* GenericStrong */ .chroma .gs { font-weight: bold }
+}
+
diff --git a/css/style.css b/css/style.css
@@ -1,3 +1,5 @@
+@import "/css/colors.css";
+
* {
margin: 0;
padding: 0;
@@ -14,8 +16,8 @@ html {
}
body {
- color: antiquewhite;
- background: #141414;
+ color: var(--fg-color);
+ background: var(--bg-color);
margin-bottom: 15em;
margin-left: .5em;
margin-right: .5em;
@@ -24,7 +26,7 @@ body {
}
header {
- color: crimson;
+ color: var(--accent-color);
max-width: 39em;
@@ -41,6 +43,10 @@ header {
border-top: 1em;
}
+#color-scheme-button-light {
+ display: none;
+}
+
.header_flex_div {
display: flex;
justify-content: center;
@@ -52,7 +58,7 @@ header {
border: 0;
clear:both;
- display:block;
+ display: block;
width: 80%;
max-width: 35em;
@@ -63,7 +69,7 @@ header {
margin-bottom: .5em;
padding-top: 0;
padding-bottom: 0;
- border-top: 1px dashed peru;
+ border-top: 1px dashed var(--secondary-accent-color);
}
#header_link, #header_link_short {
@@ -75,8 +81,18 @@ header {
font-family: "Nimbus Sans", "Nimbus Sans L", "Inter", "Helvetica", "inconsolata", monospace, "DejaVu Sans", sans, "Verdana", sans-serif, "Georgia", serif;
}
+#color-scheme-button {
+ position: absolute;
+ top: 30px;
+ right: 0;
+ display: inline-block;
+ cursor: pointer;
+ fill: var(--fg-color);
+ opacity: 75%;
+}
+
#header_link:hover {
- color: peru;
+ color: var(--hover-color);
}
#header_title {
@@ -86,7 +102,7 @@ header {
}
article {
- color: antiquewhite;
+ color: var(--fg-color);
max-width: 39em;
@@ -125,7 +141,7 @@ article {
padding-top: 0;
padding-bottom: 0;
/*! border-bottom: dashed; */
- border-top: 1px dashed peru;
+ border-top: 1px dashed var(--secondary-accent-color);
}
footer {
@@ -159,7 +175,7 @@ footer {
#index-title, #blog-title {
text-align: center;
- color: #DAA520;
+ color: var(--title-color);
padding-top: 0em;
padding-bottom: .5em;
/* animation: zoom-in-zoom-out 5s ease-in-out infinite; */
@@ -181,12 +197,12 @@ img {
}
a:visited, a:active, a:link {
- color: peru;
+ color: var(--link-color);
text-decoration: none;
}
a:hover {
- color: crimson;
+ color: var(--link-hover-color);
text-decoration: underline;
}
@@ -242,8 +258,9 @@ p { padding-bottom: 1em; }
code {
font-size: 85%;
font-family: "Ubuntu Mono", monospace;
- background-color: rgba(110,118,129,0.4);
padding: 0 .1em;
+ /* background-color: #656c7633; */
+ background-color: var(--code-bg);
margin: 0;
border-radius: 6px;
white-space: wrap;
@@ -258,7 +275,7 @@ pre {
padding-left: 1em;
padding-right: 1em;
border-radius: 0em;
- background-color: #111111;
+ background-color: var(--pre-bg-color);
width: auto;
display: block;
margin-left: auto;
@@ -266,10 +283,12 @@ pre {
margin-top: .25em;
margin-bottom: 1.25em;
border-width: thin;
- border-color: antiquewhite;
+ border-color: var(--pre-border-color);
border-style: solid;
/* box-shadow: 5px 5px 7px black; */
overflow: auto;
+ scrollbar-color: var(--pre-border-color);
+ scrollbar-width: thin;
}
pre code {
@@ -282,7 +301,7 @@ pre code {
white-space: inherit;
}
-#command { color: #33ff11; }
+/* #command { color: #33ff11; } */
#command_sym { color: #ff1694; }
#command_red { color: gold; }
@@ -311,11 +330,11 @@ hr {
#go_top {
text-decoration: none;
- color: peru;
+ color: var(--link-color);
}
#go_top:hover {
- color: crimson;
+ color: var(--accent-color);
}
/* list-style-type: none; /1* Remove bullets *1/ */
@@ -349,7 +368,7 @@ hr {
}
#urgent-announcement {
- color: antiquewhite;
+ color: var(--fg-color);
font-weight: bold;
padding: 0.5em 0em 1em 0em;
}
@@ -462,24 +481,14 @@ b-time {
}
@media (prefers-color-scheme: light) {
- body {
- background: white;
- color: #000000;
- }
- article {
- color: #000000;
- }
- #header_link {
- color: #CC2936;
- }
#header_link:hover {
color: #a04a00;
}
.header_bottom_bar {
- border-top: 1px dashed #141414;
+ border-top: 1px dashed;
}
.article_bottom_bar {
- border-top: 1px dashed #141414;
+ border-top: 1px dashed;
}
a:visited {
color: #a04a00;
@@ -490,9 +499,6 @@ b-time {
a:hover {
color: #CC2936;
}
- #index-title {
- color: inherit;
- }
pre {
background-color: #eee;
border: 3px solid #aaa;
diff --git a/scripts/js/color-scheme-toggle.js b/scripts/js/color-scheme-toggle.js
@@ -0,0 +1,63 @@
+
+function toggleColorScheme() {
+ const dataTheme = document.documentElement.getAttribute("data-theme");
+ const systemDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
+
+ if(typeof dataTheme == "undefined" || dataTheme === null) {
+ newTheme = systemDarkMode ? "light" : "dark";
+ } else {
+ newTheme = (dataTheme === "dark") ? "light" : "dark";
+ }
+
+ document.documentElement.setAttribute("data-theme", newTheme);
+ localStorage.setItem("data-theme", newTheme);
+ updateColorSchemeButton()
+
+ if(((newTheme === "dark") && systemDarkMode) || ((newTheme === "light") && !systemDarkMode)) {
+ console.log("Removing item");
+ localStorage.removeItem("data-theme");
+ }
+}
+
+function updateColorSchemeButton() {
+ const dataTheme = localStorage.getItem("data-theme");
+ const systemDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
+ const colorSchemeButtonLight = document.getElementById("color-scheme-button-light");
+ const colorSchemeButtonDark = document.getElementById("color-scheme-button-dark");
+
+ function buttonDarkMode() {
+ colorSchemeButtonLight.style.display = "none";
+ colorSchemeButtonDark.style.display = "inline-block";
+ document.documentElement.setAttribute("data-theme", "dark");
+ }
+
+ function buttonLightMode() {
+ colorSchemeButtonLight.style.display = "inline-block";
+ colorSchemeButtonDark.style.display = "none";
+ document.documentElement.setAttribute("data-theme", "light");
+ }
+
+ if(typeof dataTheme == "undefined" || dataTheme === null) {
+ if(systemDarkMode) {
+ buttonDarkMode();
+ } else {
+ buttonLightMode();
+ }
+ } else {
+ if(dataTheme === "dark") {
+ buttonDarkMode();
+ } else {
+ buttonLightMode();
+ }
+ }
+}
+
+function removeLocalStorage() {
+ console.log("Removing item");
+ localStorage.removeItem("data-theme");
+ updateColorSchemeButton();
+}
+
+window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", removeLocalStorage);
+window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", removeLocalStorage);
+updateColorSchemeButton()