From 1f7b31f9bafa57da46f3236eef028b1d17a6f910 Mon Sep 17 00:00:00 2001
From: Alexander Bilz <mail@alexbilz.com>
Date: Thu, 21 May 2020 14:41:07 +0000
Subject: [PATCH] 🌑 Added dark mode

---
 images/screenshot_dark.png   |    0 
 layouts/partials/navbar.html |    7 ++
 assets/js/anatole.js         |   48 ++++++++++++++++
 assets/css/style.css         |  102 +++++++++++++++++++++------------
 layouts/partials/head.html   |    1 
 README.md                    |    1 
 layouts/partials/footer.html |    4 +
 7 files changed, 124 insertions(+), 39 deletions(-)

diff --git a/README.md b/README.md
index be6673d..7b55e26 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@
 ### Features include:
 
 - Profile picture and slogan
+- Dark mode
 - Navigation items
 - Pagination
 - Google Analytics (optional)
diff --git a/assets/css/style.css b/assets/css/style.css
index 4f788ff..8cd46d0 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -1,16 +1,38 @@
 @charset "UTF-8";
+:root{
+  --bg-color:#fff;
+  --secondary-bg-color:#eeeeee;
+  --heading-color: #5f5f5f;
+  --body-color: rgba(0, 0, 0, 0.5);
+  --post-color: rgba(0, 0, 0, 0.44);
+  --border-color: rgba(0, 0, 0, 0.15);
+  --pre-bg-color: #f9f9fd;
+  --nav-text-color:#5a5a5a;
+  --tag-color: #424242;
+}
 html {
-  background-color: #fff;
+  background-color: var(--bg-color);
   -webkit-font-smoothing: antialiased;
 }
-
+html[data-theme='dark'] {
+  --bg-color:rgb(28, 28, 33);
+  --secondary-bg-color:rgb(119, 119, 122);
+  --heading-color:rgba(191, 191, 191, 0.5);
+  --body-color: rgba(191, 191, 191, 0.5);
+  --post-color: rgba(0, 0, 0, 0.44);
+  --border-color: rgb(38, 38, 38);
+  --pre-bg-color: #21212d;
+  --nav-text-color:rgb(191, 191, 191);
+  --tag-color: rgb(191, 191, 191) !important;
+  
+}
 body {
-  color: rgba(0, 0, 0, 0.5);
+  color: var(--body-color);
   font-family: 'Verdana', sans-serif;
   font-size: 15px;
   width: 100%;
   margin: 0 auto 30px auto;
-  background-color: #fff;
+  background-color: var(--bg-color);
 }
 
 p {
@@ -26,9 +48,9 @@
 .category {
   padding: 4px 6px;
   border-radius: 3px;
-  color: #fff;
-  background-color: #f9f9fd;
-  border: 1px solid #f2f2f2;
+  color: #000 !important;
+  background-color: var(--secondary-bg-color);
+  border: 1px solid var(--border-color);
 }
 
 .tag::before {
@@ -44,7 +66,7 @@
 }
 
 pre {
-  background-color: #f9f9fd;
+  background-color: var(--pre-bg-color);
   padding: 5px;
   display: block;
   overflow-x: auto;
@@ -62,7 +84,7 @@
   -o-transition: all .15s linear;
   -ms-transition: all .15s linear;
   transition: all .15s linear;
-  color: #424242;
+  color: var(--tag-color);
 }
 
 a:hover, a:active {
@@ -152,9 +174,9 @@
   position: fixed;
   right: 0;
   z-index: 3;
-  background-color: #fff;
+  background-color: var(--bg-color);
   height: 60px;
-  border-bottom: 1px solid #f2f2f2;
+  border-bottom: 1px solid var(--border-color);
 }
 .page-top .nav {
   list-style: none;
@@ -168,15 +190,21 @@
   padding-right: 20px;
 }
 .page-top .nav a {
-  color: #5A5A5A;
+  color: var(--nav-text-color);
 }
 .page-top .nav a:hover {
   color: #4786D6;
 }
 .page-top .nav a.current {
-  color: #5A5A5A;
+  color: var(--nav-text-color);
   padding-bottom: 22px;
-  border-bottom: 1px solid #5A5A5A;
+  border-bottom: 1px solid var(--nav-text-color);
+}
+.page-top .themeswitcher {
+  list-style: none;
+  padding: 15px 30px;
+  float: right;
+  font-size: 1.6em;
 }
 .page-top .information {
   float: right;
@@ -205,14 +233,14 @@
   width: 40%;
   -webkit-background-size: cover;
   background-size: cover;
-  background-color: #fff;
+  background-color: var(--bg-color);
   height: 100%;
   transition: 0.8s;
   top: 0;
   left: 0;
   position: fixed;
   z-index: 4;
-  border-right: 1px solid #f2f2f2;
+  border-right: 1px solid var(--border-color);
 }
 .sidebar .logo-title {
   text-align: center;
@@ -220,7 +248,6 @@
 }
 .sidebar .logo-title .description {
   font-size: 14px;
-  color: #565654;
 }
 .sidebar .logo-title .logo {
   margin: 0 auto;
@@ -239,7 +266,7 @@
 }
 .sidebar .logo-title .title a {
   text-decoration: none;
-  color: #464646;
+  color: var(--heading-color);
   font-size: 2rem;
   font-weight: bold;
 }
@@ -258,14 +285,14 @@
   line-height: 0;
 }
 .sidebar .social-links a {
-  color: #565654;
+  color: var(--heading-color);
 }
 .sidebar .social-links a:hover {
   color: #4786D6;
 }
 
 .post {
-  background-color: #FFF;
+  background-color: var(--bg-color);
   margin: 30px;
 }
 .post .post-title h1 {
@@ -280,21 +307,22 @@
   font-size: 28px;
   line-height: 1;
   font-weight: 600;
-  color: #5f5f5f;
+  color: var(--heading-color);
 }
 .post .post-title h3 {
   text-transform: uppercase;
   letter-spacing: 1px;
   line-height: 1;
   font-weight: 600;
-  color: #464646;
+  /* color: #464646; */
+  color: var(--heading-color);
   font-size: 22px;
   margin: 0;
 }
 .post .post-title a {
   text-decoration: none;
   letter-spacing: 1px;
-  color: #5f5f5f;
+  color: var(--heading-color);
 }
 .post .post-title a:hover {
   text-decoration: underline;
@@ -308,20 +336,20 @@
   color: #2F69B3;
 }
 .post .post-content h3 {
-  color: #5F5F5F;
+  /*  */
   font-size: 22px;
   font-weight: 600;
 }
 .post .post-content h4 {
-  color: #5F5F5F;
+  /* color: var(--heading-color); */
   font-size: 16px;
 }
 .post .post-content img {
   max-width: 100%;
 }
 .post .post-footer {
-  padding: 0 0 30px 0;
-  border-bottom: 1px solid #f2f2f2;
+  padding: 0 0 10px 0;
+  border-bottom: 1px solid var(--border-color);
 }
 .post .post-footer .meta {
   max-width: 100%;
@@ -332,6 +360,7 @@
   float: left;
   font-size: 12px;
   margin-bottom: 1em;
+  color: var(--body-color);
 }
 .post .post-footer .info .separator a {
   margin-right: 0.2em;
@@ -344,7 +373,7 @@
 }
 .post .post-footer .meta a {
   text-decoration: none;
-  color: #bbbbbb;
+  color: var(--body-color);
   padding-right: 10px;
 }
 .post .post-footer .meta a:hover {
@@ -371,7 +400,7 @@
 }
 .post .post-footer .tags a {
   text-decoration: none;
-  color: rgba(0, 0, 0, 0.44);
+  color: var(--post-color);
   font-weight: 400;
 }
 .post .post-footer .tags a:hover {
@@ -396,7 +425,7 @@
 }
 .pagination ul li a {
   text-decoration: none;
-  color: rgba(0, 0, 0, 0.5);
+  color: var(--body-color);
 }
 .pagination .pre {
   float: left;
@@ -427,7 +456,7 @@
 
 #disqus_thread {
   margin: 30px;
-  border-bottom: 1px solid #f2f2f2;
+  border-bottom: 1px solid var(--border-color);
 }
 
 .footer {
@@ -439,7 +468,6 @@
   position: absolute;
   width: 100%;
   padding-bottom: 20px;
-  background: #fff;
 }
 .footer a {
   color: #A6A6A6;
@@ -592,13 +620,13 @@
   display: inline-block;
   position: relative;
   outline: 0;
-  color: rgba(0, 0, 0, 0.44);
+  color: var(--post-color);
   background: transparent;
   font-size: 14px;
   text-align: center;
   text-decoration: none;
   cursor: pointer;
-  border: 1px solid rgba(0, 0, 0, 0.15);
+  border: 1px solid var(--border-color);
   white-space: nowrap;
   font-weight: 400;
   font-style: normal;
@@ -658,13 +686,13 @@
   position: relative;
   padding: 0.5em 1.25em;
   outline: 0;
-  color: rgba(0, 0, 0, 0.44);
+  color: var(--post-color);
   background: transparent;
   font-size: 14px;
   text-align: center;
   text-decoration: none;
   cursor: pointer;
-  border: 1px solid rgba(0, 0, 0, 0.15);
+  border: 1px solid var(--border-color);
   white-space: nowrap;
   font-weight: 400;
   font-style: normal;
@@ -741,4 +769,4 @@
   .share {
     display: grid;
   }
-}
\ No newline at end of file
+}
diff --git a/assets/js/anatole.js b/assets/js/anatole.js
new file mode 100644
index 0000000..e7859fd
--- /dev/null
+++ b/assets/js/anatole.js
@@ -0,0 +1,48 @@
+const themeSwitcher = document.querySelector('.theme-switch');
+
+function getTheme(){
+    return localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+}
+
+function setTheme(style){
+    document.documentElement.setAttribute('data-theme', style);
+    localStorage.setItem('theme', style);  
+}
+
+// switch themes
+function switchTheme(e) {
+    var theme = getTheme();
+    if (theme == 'light') {
+        setTheme('dark');
+    }
+    else {
+        setTheme('light');
+    }
+}
+
+// initialize default value
+var theme = getTheme();
+
+// check if a prefered color theme is set for users that have never been to our site
+const userPrefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
+
+if (theme === null) {
+    if(userPrefersDark){
+        setTheme('dark');
+    }
+    else{
+        setTheme('light');
+    }
+}
+else {
+    // load a stored theme
+    if (theme == 'light') {
+        document.documentElement.setAttribute('data-theme', 'light');
+    }
+    else {
+        document.documentElement.setAttribute('data-theme', 'dark');
+    }    
+}
+
+
+themeSwitcher.addEventListener('click', switchTheme, false);
\ No newline at end of file
diff --git a/images/screenshot_dark.png b/images/screenshot_dark.png
new file mode 100644
index 0000000..c8439d2
--- /dev/null
+++ b/images/screenshot_dark.png
Binary files differ
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html
index 7a49578..36b2a41 100644
--- a/layouts/partials/footer.html
+++ b/layouts/partials/footer.html
@@ -6,10 +6,12 @@
 <script type="text/javascript" src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}"></script>
 {{ $migrate := resources.Get "js/jquery-migrate.js" }}
 {{ $appear := resources.Get "js/jquery-appear.js" }}
-{{ $js := slice $migrate $appear | resources.Concat "js/bundle.js" }}
+{{ $anatole := resources.Get "js/anatole.js" }}
+{{ $js := slice $migrate $appear $anatole | resources.Concat "js/bundle.js" }}
 {{ $secureJS := $js |  resources.Minify | resources.Fingerprint }}
 <script type="text/javascript" src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}"></script>
 {{- partial "medium-zoom.html" . -}}
 {{- partial "math.html" . -}}
 {{- template "_internal/google_analytics_async.html" . -}}
+
 </html>
\ No newline at end of file
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index de15d56..e04cd6e 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -1,3 +1,4 @@
+<html lang="en" data-theme="light">
 <head>
     <title> {{.Site.Params.author}}{{ with .Title }} | {{ . }}{{ end }} </title>
     <meta charset="utf-8">
diff --git a/layouts/partials/navbar.html b/layouts/partials/navbar.html
index 90dd290..c9e8552 100644
--- a/layouts/partials/navbar.html
+++ b/layouts/partials/navbar.html
@@ -6,4 +6,9 @@
 
         {{ end }}
     </div>
-</div>
\ No newline at end of file
+    <div class="themeswitcher">
+        <a class="theme-switch" title="Switch Theme">
+            <i class="fa fa-adjust fa-fw" aria-hidden="true"></i>
+        </a>
+    </div>
+</div>

--
Gitblit v1.10.0