summaryrefslogtreecommitdiff
path: root/htdocs
diff options
context:
space:
mode:
authorEvgeny Zinoviev <me@ch1p.io>2022-07-10 01:30:05 +0300
committerEvgeny Zinoviev <me@ch1p.io>2022-07-10 23:53:02 +0300
commit1c524efbf7da91cb99bb4516feb514071e938495 (patch)
treee1fced0104749014db154f5d3b29881e705bfafc /htdocs
parent8979719a1af4bc0712407db7f95704f645f261a3 (diff)
dark theme support
Diffstat (limited to 'htdocs')
-rw-r--r--htdocs/img/enter.svg1
-rw-r--r--htdocs/js/common.js293
-rw-r--r--htdocs/sass.php9
-rw-r--r--htdocs/scss/app/blog.scss (renamed from htdocs/scss/blog.scss)20
-rw-r--r--htdocs/scss/app/common.scss (renamed from htdocs/scss/common.scss)172
-rw-r--r--htdocs/scss/app/form.scss (renamed from htdocs/scss/form.scss)4
-rw-r--r--htdocs/scss/app/head.scss157
-rw-r--r--htdocs/scss/app/hljs.scss1
-rw-r--r--htdocs/scss/app/mobile.scss (renamed from htdocs/scss/mobile.scss)2
-rw-r--r--htdocs/scss/app/pages.scss (renamed from htdocs/scss/pages.scss)0
-rw-r--r--htdocs/scss/bundle_admin.scss3
-rw-r--r--htdocs/scss/bundle_common.scss10
-rw-r--r--htdocs/scss/colors/dark.scss46
-rw-r--r--htdocs/scss/colors/light.scss46
-rw-r--r--htdocs/scss/common-bundle.scss9
-rw-r--r--htdocs/scss/entries/admin/dark.scss2
-rw-r--r--htdocs/scss/entries/admin/light.scss2
-rw-r--r--htdocs/scss/entries/common/dark.scss2
-rw-r--r--htdocs/scss/entries/common/light.scss2
-rw-r--r--htdocs/scss/hljs.scss1
-rw-r--r--htdocs/scss/hljs/github.scss36
-rw-r--r--htdocs/scss/vars.scss39
22 files changed, 624 insertions, 233 deletions
diff --git a/htdocs/img/enter.svg b/htdocs/img/enter.svg
deleted file mode 100644
index 6fe49ed..0000000
--- a/htdocs/img/enter.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="15" height="9.474"><path d="M0 4.737l4.737 4.737 1.105-1.106L3 5.526h12V.79h-1.579v3.158H3l2.842-2.842L4.737 0z"/></svg>
diff --git a/htdocs/js/common.js b/htdocs/js/common.js
index 4e4199c..959b672 100644
--- a/htdocs/js/common.js
+++ b/htdocs/js/common.js
@@ -14,6 +14,39 @@ if (!String.prototype.endsWith) {
};
}
+if (!Object.assign) {
+ Object.defineProperty(Object, 'assign', {
+ enumerable: false,
+ configurable: true,
+ writable: true,
+ value: function(target, firstSource) {
+ 'use strict';
+ if (target === undefined || target === null) {
+ throw new TypeError('Cannot convert first argument to object');
+ }
+
+ var to = Object(target);
+ for (var i = 1; i < arguments.length; i++) {
+ var nextSource = arguments[i];
+ if (nextSource === undefined || nextSource === null) {
+ continue;
+ }
+
+ var keysArray = Object.keys(Object(nextSource));
+ for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
+ var nextKey = keysArray[nextIndex];
+ var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
+ if (desc !== undefined && desc.enumerable) {
+ to[nextKey] = nextSource[nextKey];
+ }
+ }
+ }
+ return to;
+ }
+ });
+}
+
+
//
// AJAX
//
@@ -87,7 +120,7 @@ if (!String.prototype.endsWith) {
break;
}
- opts = extend({}, defaultOpts, opts);
+ opts = Object.assign({}, defaultOpts, opts);
var xhr = createXMLHttpRequest();
xhr.open(method, url);
@@ -244,11 +277,11 @@ function setCookie(name, value, days) {
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
- document.cookie = name + "=" + (value || "") + expires + "; path=/";
+ document.cookie = name + "=" + (value || "") + expires + "; domain=" + window.appConfig.cookieHost + "; path=/";
}
function unsetCookie(name) {
- document.cookie = name+'=; Max-Age=-99999999;';
+ document.cookie = name + '=; Max-Age=-99999999; domain=' + window.appConfig.cookieHost + "; path=/";
}
function getCookie(name) {
@@ -312,6 +345,34 @@ function escape(str) {
return pre.innerHTML;
}
+function parseUrl(uri) {
+ var parser = document.createElement('a');
+ parser.href = uri;
+
+ return {
+ protocol: parser.protocol, // => "http:"
+ host: parser.host, // => "example.com:3000"
+ hostname: parser.hostname, // => "example.com"
+ port: parser.port, // => "3000"
+ pathname: parser.pathname, // => "/pathname/"
+ hash: parser.hash, // => "#hash"
+ search: parser.search, // => "?search=test"
+ origin: parser.origin, // => "http://example.com:3000"
+ path: (parser.pathname || '') + (parser.search || '')
+ }
+}
+
+function once(fn, context) {
+ var result;
+ return function() {
+ if (fn) {
+ result = fn.apply(context || this, arguments);
+ fn = null;
+ }
+ return result;
+ };
+}
+
//
//
@@ -390,3 +451,229 @@ window.__lang = {};
unsetCookie('is_retina');
}
})();
+
+var StaticManager = {
+ loadedStyles: [],
+ versions: {},
+
+ setStyles: function(list, versions) {
+ this.loadedStyles = list;
+ this.versions = versions;
+ },
+
+ loadStyle: function(name, theme, callback) {
+ var url;
+ if (!window.appConfig.devMode) {
+ var filename = name + (theme === 'dark' ? '_dark' : '') + '.css';
+ url = '/css/'+filename+'?'+this.versions[filename];
+ } else {
+ url = '/sass.php?name='+name+'&theme='+theme;
+ }
+
+ var el = document.createElement('link');
+ el.onerror = callback
+ el.onload = callback
+ el.setAttribute('rel', 'stylesheet');
+ el.setAttribute('type', 'text/css');
+ el.setAttribute('id', 'style_'+name+'_dark');
+ el.setAttribute('href', url);
+
+ document.getElementsByTagName('head')[0].appendChild(el);
+ }
+};
+
+var ThemeSwitcher = (function() {
+ /**
+ * @type {string[]}
+ */
+ var modes = ['auto', 'dark', 'light'];
+
+ /**
+ * @type {number}
+ */
+ var currentModeIndex = -1;
+
+ /**
+ * @type {boolean|null}
+ */
+ var systemState = null;
+
+ /**
+ * @returns {boolean}
+ */
+ function isSystemModeSupported() {
+ try {
+ // crashes on:
+ // Mozilla/5.0 (Windows NT 6.2; ARM; Trident/7.0; Touch; rv:11.0; WPDesktop; Lumia 630 Dual SIM) like Gecko
+ // Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1
+ // Mozilla/5.0 (iPad; CPU OS 12_5_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1
+ //
+ // error examples:
+ // - window.matchMedia("(prefers-color-scheme: dark)").addEventListener is not a function. (In 'window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",this.onSystemSettingChange.bind(this))', 'window.matchMedia("(prefers-color-scheme: dark)").addEventListener' is undefined)
+ // - Object [object MediaQueryList] has no method 'addEventListener'
+ return !!window['matchMedia']
+ && typeof window.matchMedia("(prefers-color-scheme: dark)").addEventListener === 'function';
+ } catch (e) {
+ return false
+ }
+ }
+
+ /**
+ * @returns {boolean}
+ */
+ function isDarkModeApplied() {
+ var st = StaticManager.loadedStyles;
+ for (var i = 0; i < st.length; i++) {
+ var name = st[i];
+ if (ge('style_'+name+'_dark'))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @returns {string}
+ */
+ function getSavedMode() {
+ var val = getCookie('theme');
+ if (!val)
+ return modes[0];
+ if (modes.indexOf(val) === -1) {
+ console.error('[ThemeSwitcher getSavedMode] invalid cookie value')
+ unsetCookie('theme')
+ return modes[0]
+ }
+ return val
+ }
+
+ /**
+ * @param {boolean} dark
+ */
+ function changeTheme(dark) {
+ addClass(document.body, 'theme-changing');
+
+ var onDone = function() {
+ window.requestAnimationFrame(function() {
+ removeClass(document.body, 'theme-changing');
+ })
+ };
+
+ window.requestAnimationFrame(function() {
+ if (dark)
+ enableDark(onDone);
+ else
+ disableDark(onDone);
+ })
+ }
+
+ /**
+ * @param {function} callback
+ */
+ function enableDark(callback) {
+ var names = [];
+ StaticManager.loadedStyles.forEach(function(name) {
+ var el = ge('style_'+name+'_dark');
+ if (el)
+ return;
+ names.push(name);
+ });
+
+ var left = names.length;
+ names.forEach(function(name) {
+ StaticManager.loadStyle(name, 'dark', once(function(e) {
+ left--;
+ if (left === 0)
+ callback();
+ }));
+ })
+ }
+
+ /**
+ * @param {function} callback
+ */
+ function disableDark(callback) {
+ StaticManager.loadedStyles.forEach(function(name) {
+ var el = ge('style_'+name+'_dark');
+ if (el)
+ el.remove();
+ })
+ callback();
+ }
+
+ /**
+ * @param {string} mode
+ */
+ function setLabel(mode) {
+ var labelEl = ge('theme-switcher-label');
+ labelEl.innerHTML = escape(lang('theme_'+mode));
+ }
+
+ return {
+ init: function() {
+ var cur = getSavedMode();
+ currentModeIndex = modes.indexOf(cur);
+
+ var systemSupported = isSystemModeSupported();
+ if (!systemSupported) {
+ if (currentModeIndex === 0) {
+ modes.shift(); // remove 'auto' from the list
+ currentModeIndex = 1; // set to 'light'
+ if (isDarkModeApplied())
+ disableDark();
+ }
+ } else {
+ /**
+ * @param {boolean} dark
+ */
+ var onSystemChange = function(dark) {
+ var prevSystemState = systemState;
+ systemState = dark;
+
+ if (modes[currentModeIndex] !== 'auto')
+ return;
+
+ if (systemState !== prevSystemState)
+ changeTheme(systemState);
+ };
+
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
+ onSystemChange(e.matches === true)
+ });
+
+ onSystemChange(window.matchMedia('(prefers-color-scheme: dark)').matches === true);
+ }
+
+ setLabel(modes[currentModeIndex]);
+ },
+
+ next: function(e) {
+ if (hasClass(document.body, 'theme-changing')) {
+ console.log('next: theme changing is in progress, ignoring...')
+ return;
+ }
+
+ currentModeIndex = (currentModeIndex + 1) % modes.length;
+ switch (modes[currentModeIndex]) {
+ case 'auto':
+ if (systemState !== null)
+ changeTheme(systemState);
+ break;
+
+ case 'light':
+ if (isDarkModeApplied())
+ changeTheme(false);
+ break;
+
+ case 'dark':
+ if (!isDarkModeApplied())
+ changeTheme(true);
+ break;
+ }
+
+ setLabel(modes[currentModeIndex]);
+ setCookie('theme', modes[currentModeIndex]);
+
+ return cancelEvent(e);
+ }
+ };
+})(); \ No newline at end of file
diff --git a/htdocs/sass.php b/htdocs/sass.php
index eb24962..186b706 100644
--- a/htdocs/sass.php
+++ b/htdocs/sass.php
@@ -4,7 +4,14 @@ require __DIR__.'/../init.php';
global $config;
$name = $_REQUEST['name'] ?? '';
-if (!$config['is_dev'] || !$name || !file_exists($path = ROOT.'/htdocs/scss/'.$name.'.scss')) {
+$theme = $_REQUEST['theme'] ?? '';
+
+if ($theme != 'light' && $theme != 'dark') {
+ http_response_code(403);
+ exit;
+}
+
+if (!$config['is_dev'] || !$name || !file_exists($path = ROOT.'/htdocs/scss/entries/'.$name.'/'.$theme.'.scss')) {
// logError(__FILE__.': access denied');
http_response_code(403);
exit;
diff --git a/htdocs/scss/blog.scss b/htdocs/scss/app/blog.scss
index 7641683..53ec7e4 100644
--- a/htdocs/scss/blog.scss
+++ b/htdocs/scss/app/blog.scss
@@ -1,4 +1,4 @@
-@import 'vars';
+@import '../vars';
.blog-write-link-wrap {
margin-bottom: $base-padding;
@@ -81,7 +81,7 @@
margin-bottom: 2px;
}
.blog-upload-item-info {
- color: #888;
+ color: $grey;
font-size: $fs - 2px;
}
.blog-upload-item-note {
@@ -102,7 +102,7 @@
}
.blog-post-date {
- color: #888;
+ color: $grey;
margin-top: 5px;
font-size: $fs - 1px;
> a {
@@ -168,7 +168,7 @@
background-color: $code-block-bg;
span.term-prompt {
- color: #999;
+ color: $light-grey;
@include user-select(none);
}
}
@@ -177,7 +177,7 @@
border-left: 3px #e0e0e0 solid;
margin-left: 0;
padding: 5px 0 5px 12px;
- color: #888;
+ color: $grey;
}
table.table-100 {
@@ -266,7 +266,7 @@
.blog-post-comments {
margin-top: $base-padding;
padding: 12px 15px;
- border: 1px #e0e0e0 solid;
+ border: 1px $border-color solid;
@include radius(3px);
}
.blog-post-comments img {
@@ -317,7 +317,7 @@ td.blog-item-date-cell {
padding-right: 10px;
}
.blog-item-date {
- color: #777;
+ color: $grey;
//text-transform: lowercase;
}
td.blog-item-title-cell {
@@ -344,6 +344,8 @@ td.blog-item-title-cell {
padding-top: 0;
}
}
+
+/*
a.blog-item-view-all-link {
display: inline-block;
padding: 4px 17px;
@@ -356,7 +358,7 @@ a.blog-item-view-all-link:hover {
text-decoration: none;
background-color: #ededed;
}
-
+*/
.blog-tags {
float: right;
@@ -374,7 +376,7 @@ a.blog-item-view-all-link:hover {
font-size: $fs - 1px;
}
.blog-tag-item > a {
- color: #222;
+ color: $fg;
}
.blog-tag-item-count {
color: #aaa;
diff --git a/htdocs/scss/common.scss b/htdocs/scss/app/common.scss
index 644a080..b9c5959 100644
--- a/htdocs/scss/common.scss
+++ b/htdocs/scss/app/common.scss
@@ -1,4 +1,4 @@
-@import "vars";
+@import "../vars";
.clearfix:after {
content: ".";
@@ -13,7 +13,7 @@ html, body {
padding: 0;
margin: 0;
border: 0;
- //background-color: $bg;
+ background-color: $bg;
color: $fg;
height: 100%;
min-height: 100%;
@@ -35,13 +35,15 @@ body.full-width .base-width {
margin-right: auto;
}
-input[type="text"], textarea {
+input[type="text"],
+input[type="password"],
+textarea {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
box-sizing: border-box;
border: 1px $input-border solid;
- border-radius: 0px;
+ border-radius: 0;
background-color: $input-bg;
color: $fg;
font-family: $ff;
@@ -49,14 +51,16 @@ input[type="text"], textarea {
padding: 6px;
outline: none;
@include radius(3px);
+
+ &:focus {
+ border-color: $input-border-focused;
+ }
}
+
textarea {
resize: vertical;
}
-input[type="text"]:focus,
-textarea:focus {
- border-color: $input-border-focused;
-}
+
//input[type="checkbox"] {
// margin-left: 0;
//}
@@ -110,137 +114,6 @@ p, p code {
padding: $base-padding 0;
}
-.head {
- padding: 0 $side-padding;
-}
-.head-inner {
- //padding: 13px 0;
- position: relative;
- border-bottom: 2px $border-color solid;
-}
-.head-logo {
- padding: 4px 0;
- font-family: $ffMono;
- font-size: 15px;
- display: inline-block;
- position: absolute;
- left: 0;
- background-color: transparent;
- @include transition(background-color, 0.03s);
-}
-.head-logo {
- padding: 16px 0;
- background-color: #fff;
-}
-.head-logo:after {
- content: '';
- display: block;
- width: 40px;
- position: absolute;
- right: -40px;
- top: 0;
- bottom: 0;
- border-left: 8px #fff solid;
- box-sizing: border-box;
- background: linear-gradient(to left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%); /* W3C */
-}
-.head-logo > a {
- color: $fg;
- font-size: 14px;
-}
-.head-logo > a:hover {
- text-decoration: none;
-}
-.head-logo-enter {
- display: inline;
- opacity: 0;
- font-size: 11px;
- position: relative;
- background: #eee;
- padding: 2px 5px;
- color: #333;
- font-weight: normal;
- vertical-align: middle;
- top: -1px;
- @include transition(opacity, 0.03s);
-}
-.head-logo-enter-icon {
- width: 12px;
- height: 7px;
- display: inline-block;
- background: url(/img/enter.svg) 0 0 no-repeat;
- background-size: 12px 7px;
- margin-right: 5px;
-}
-.head-logo > a:hover .head-logo-enter {
- opacity: 1;
-}
-.head-logo-path {
- color: $fg;
- font-weight: bold;
- -webkit-font-smoothing: antialiased;
- @include transition(color, 0.03s);
-}
-.head-logo > a:hover .head-logo-path:not(.alwayshover) {
- color: #aaa;
-}
-.head-logo-path:not(.neverhover):hover {
- color: #000 !important;
-}
-.head-logo-dolsign {
- color: $head-green-color;
- font-weight: normal;
- &.is_root {
- color: $head-red-color;
- }
-}
-.head-logo-cd {
- display: none;
-}
-.head-logo > a:hover .head-logo-cd {
- display: inline;
-}
-.head-logo-path-mapped {
- padding: 3px 5px;
- background: #f1f1f1;
- pointer-events: none;
- @include radius(3px);
- margin: 0 2px;
-}
-
-.head-items {
- float: right;
- color: #777; // color of separators
- //padding: 8px 0;
-}
-a.head-item {
- color: $fg;
- font-size: $fs - 1px;
- display: block;
- float: left;
- padding: 16px 0;
-}
-a.head-item > span {
- padding: 0 12px;
- border-right: 1px #d0d0d0 solid;
-}
-a.head-item > span > span {
- padding: 2px 0;
-}
-a.head-item:last-child > span {
- border-right: 0;
- padding-right: 1px;
-}
-/*a.head-item:first-child > span {
- padding-left: 2px;
-}*/
-a.head-item:hover {
- //color: $link-color;
- text-decoration: none;
-}
-a.head-item:hover > span > span {
- border-bottom: 1px #d0d0d0 solid;
-}
table.contacts {
border: 0;
@@ -257,17 +130,17 @@ table.contacts td {
table.contacts td.label {
text-align: right;
width: 30%;
- color: #777;
+ color: $dark-grey;
}
table.contacts td.value {
text-align: left;
padding-left: 8px;
}
table.contacts td.value span {
- background: #eee;
+ background: $inline-code-block-bg;
padding: 3px 7px 4px;
border-radius: 3px;
- color: #333;
+ color: $fg;
font-family: $ffMono;
font-size: $fs - 1px;
}
@@ -283,13 +156,14 @@ table.contacts td pre {
table.contacts div.note {
font-size: $fs - 3px;
padding-top: 2px;
- color: #777;
+ color: $dark-grey;
> a {
- color: #777;
- border-bottom: 1px #ccc solid;
+ color: $dark-grey;
+ border-bottom: 1px $border-color solid;
&:hover {
text-decoration: none;
- border-bottom-color: #999;
+ color: $link-color;
+ border-bottom-color: $link-color;
}
}
}
@@ -360,11 +234,11 @@ table.contacts div.note {
//font-weight: bold;
}
.md-file-attach-size {
- color: #888;
+ color: $grey;
margin-left: 2px;
}
.md-file-attach-note {
- color: #000;
+ color: $fg;
margin-left: 2px;
}
@@ -402,7 +276,7 @@ table.contacts div.note {
}
.md-image-note {
line-height: 150%;
- color: #777;
+ color: $dark-grey;
padding: 2px 0 4px;
}
diff --git a/htdocs/scss/form.scss b/htdocs/scss/app/form.scss
index 4faa4d1..197732c 100644
--- a/htdocs/scss/form.scss
+++ b/htdocs/scss/app/form.scss
@@ -1,4 +1,4 @@
-@import 'vars';
+@import '../vars';
$form-field-label-width: 120px;
@@ -35,7 +35,7 @@ form { display: block; margin: 0; }
font-size: 12px;
letter-spacing: 0.5px;
text-transform: uppercase;
- color: #888;
+ color: $grey;
}
.form-field {
//margin-left: $form-field-label-width + 10px;
diff --git a/htdocs/scss/app/head.scss b/htdocs/scss/app/head.scss
new file mode 100644
index 0000000..fed30d1
--- /dev/null
+++ b/htdocs/scss/app/head.scss
@@ -0,0 +1,157 @@
+.head {
+ padding: 0 $side-padding;
+}
+.head-inner {
+ //padding: 13px 0;
+ position: relative;
+ border-bottom: 2px $border-color solid;
+}
+.head-logo {
+ padding: 4px 0;
+ font-family: $ffMono;
+ font-size: 15px;
+ display: inline-block;
+ position: absolute;
+ left: 0;
+ background-color: transparent;
+}
+body:not(.theme-changing) .head-logo {
+ @include transition(background-color, 0.03s);
+}
+.head-logo {
+ padding: 16px 0;
+ background-color: $bg;
+}
+.head-logo:after {
+ content: '';
+ display: block;
+ width: 40px;
+ position: absolute;
+ right: -40px;
+ top: 0;
+ bottom: 0;
+ border-left: 8px $bg solid;
+ box-sizing: border-box;
+ background: linear-gradient(to left, rgba($bg, 0) 0%, rgba($bg, 1) 100%); /* W3C */
+}
+.head-logo > a {
+ color: $fg;
+ font-size: 14px;
+}
+.head-logo > a:hover {
+ text-decoration: none;
+}
+.head-logo-enter {
+ background: $code-block-bg;
+ color: $hljs_fg;
+ display: inline;
+ opacity: 0;
+ font-size: 11px;
+ position: relative;
+ padding: 2px 5px;
+ font-weight: normal;
+ vertical-align: middle;
+ top: -1px;
+}
+body:not(.theme-changing) .head-logo-enter {
+ @include transition(opacity, 0.03s);
+}
+.head-logo-enter-icon {
+ width: 12px;
+ height: 7px;
+ display: inline-block;
+ margin-right: 5px;
+ position: relative;
+ top: 1px;
+
+ > svg {
+ path {
+ fill: $hljs_fg;
+ }
+ }
+}
+.head-logo > a:hover .head-logo-enter {
+ opacity: 1;
+}
+.head-logo-path {
+ color: $fg;
+ font-weight: bold;
+ -webkit-font-smoothing: antialiased;
+}
+body:not(.theme-changing) .head-logo-path {
+ @include transition(color, 0.03s);
+}
+.head-logo > a:hover .head-logo-path:not(.alwayshover) {
+ color: $light_grey;
+}
+.head-logo-path:not(.neverhover):hover {
+ color: $fg !important;
+}
+.head-logo-dolsign {
+ color: $head_green_color;
+ font-weight: normal;
+ &.is_root {
+ color: $head_red_color;
+ }
+}
+.head-logo-cd {
+ display: none;
+}
+.head-logo > a:hover .head-logo-cd {
+ display: inline;
+}
+.head-logo-path-mapped {
+ padding: 3px 5px;
+ background: #f1f1f1;
+ pointer-events: none;
+ @include radius(3px);
+ margin: 0 2px;
+}
+
+.head-items {
+ float: right;
+ color: #777; // color of separators
+ //padding: 8px 0;
+}
+a.head-item {
+ color: $fg;
+ font-size: $fs - 1px;
+ display: block;
+ float: left;
+ padding: 16px 0;
+
+ > span {
+ position: relative;
+ padding: 0 12px;
+ border-right: 1px $head-items-separator solid;
+
+ > span {
+ padding: 2px 0;
+
+ > span.moon-icon {
+ position: absolute;
+ left: 0;
+
+ > svg path {
+ fill: $fg;
+ }
+ }
+ }
+ }
+
+ &.is-theme-switcher > span {
+ padding-left: 20px;
+ }
+
+ &:last-child > span {
+ border-right: 0;
+ padding-right: 1px;
+ }
+}
+a.head-item:hover {
+ //color: $link-color;
+ text-decoration: none;
+}
+a.head-item:hover > span > span {
+ border-bottom: 1px $head-items-separator solid;
+} \ No newline at end of file
diff --git a/htdocs/scss/app/hljs.scss b/htdocs/scss/app/hljs.scss
new file mode 100644
index 0000000..913c45e
--- /dev/null
+++ b/htdocs/scss/app/hljs.scss
@@ -0,0 +1 @@
+@import "../hljs/github.css";
diff --git a/htdocs/scss/mobile.scss b/htdocs/scss/app/mobile.scss
index d4d0d25..a765e25 100644
--- a/htdocs/scss/mobile.scss
+++ b/htdocs/scss/app/mobile.scss
@@ -1,4 +1,4 @@
-@import 'vars';
+@import '../vars';
textarea {
-webkit-overflow-scrolling: touch;
diff --git a/htdocs/scss/pages.scss b/htdocs/scss/app/pages.scss
index 873a6ae..873a6ae 100644
--- a/htdocs/scss/pages.scss
+++ b/htdocs/scss/app/pages.scss
diff --git a/htdocs/scss/bundle_admin.scss b/htdocs/scss/bundle_admin.scss
new file mode 100644
index 0000000..06808d0
--- /dev/null
+++ b/htdocs/scss/bundle_admin.scss
@@ -0,0 +1,3 @@
+.admin-page {
+ line-height: 155%;
+}
diff --git a/htdocs/scss/bundle_common.scss b/htdocs/scss/bundle_common.scss
new file mode 100644
index 0000000..dd0bd6a
--- /dev/null
+++ b/htdocs/scss/bundle_common.scss
@@ -0,0 +1,10 @@
+@import "./app/common";
+@import "./app/head";
+@import "./app/blog";
+@import "./app/form";
+@import "./app/pages";
+@import "./hljs/github.scss";
+
+@media screen and (max-width: 600px) {
+ @import "./app/mobile";
+}
diff --git a/htdocs/scss/colors/dark.scss b/htdocs/scss/colors/dark.scss
new file mode 100644
index 0000000..c7c25cf
--- /dev/null
+++ b/htdocs/scss/colors/dark.scss
@@ -0,0 +1,46 @@
+$head_green_color: #0bad19;
+$head_red_color: #e23636;
+$link-color: #71abe5;
+
+$grey: #798086;
+$dark-grey: $grey;
+$light-grey: $grey;
+$fg: #eee;
+$bg: #222;
+
+$code-block-bg: #394146;
+$inline-code-block-bg: #394146;
+
+$light-bg: #464c4e;
+$dark-bg: #272C2D;
+$dark-fg: #999;
+
+$input-border: #48535a;
+$input-border-focused: #48535a;
+$input-bg: #30373b;
+$border-color: #48535a;
+
+$error-block-bg: #f9eeee;
+$error-block-fg: #d13d3d;
+
+$success-block-bg: #eff5f0;
+$success-block-fg: #2a6f34;
+
+$head-items-separator: #5e6264;
+
+// colors from https://github.com/Kelbster/highlightjs-material-dark-theme/blob/master/css/materialdark.css
+$hljs_fg: #CDD3D8;
+$hljs_bg: #2B2B2D;
+$hljs_quote: #6272a4;
+$hljs_string: #f1fa8c;
+$hljs_literal: #bd93f9;
+$hljs_title: #75A5FF;
+$hljs_keyword: #C792EA;
+$hljs_type: #da4939;
+$hljs_tag: #abb2bf;
+$hljs_regexp: #F77669;
+$hljs_symbol: #C792EA;
+$hljs_builtin: #C792EA;
+$hljs_meta: #75A5FF;
+$hljs_deletion: #e6e1dc;
+$hljs_addition: #144212; \ No newline at end of file
diff --git a/htdocs/scss/colors/light.scss b/htdocs/scss/colors/light.scss
new file mode 100644
index 0000000..e6c14ba
--- /dev/null
+++ b/htdocs/scss/colors/light.scss
@@ -0,0 +1,46 @@
+$head_green_color: #0bad19;
+$head_red_color: #ce1a1a;
+$link-color: #116fd4;
+
+$grey: #888;
+$dark-grey: #777;
+$light-grey: #999;
+$fg: #222;
+$bg: #fff;
+
+$code-block-bg: #f3f3f3;
+$inline-code-block-bg: #f1f1f1;
+
+$light-bg: #464c4e;
+$dark-bg: #272C2D;
+$dark-fg: #999;
+
+$input-border: #e0e0e0;
+$input-border-focused: #e0e0e0;
+$input-bg: #f7f7f7;
+$border-color: #e0e0e0;
+
+$error-block-bg: #f9eeee;
+$error-block-fg: #d13d3d;
+
+$success-block-bg: #eff5f0;
+$success-block-fg: #2a6f34;
+
+$head-items-separator: #d0d0d0;
+
+// github.com style (c) Vasily Polovnyov <vast@whiteants.net>
+$hljs_fg: #333;
+$hljs_bg: #f8f8f8;
+$hljs_quote: #998;
+$hljs_string: #d14;
+$hljs_literal: #008080;
+$hljs_title: #900;
+$hljs_keyword: $hljs_fg;
+$hljs_type: #458;
+$hljs_tag: #000080;
+$hljs_regexp: #009926;
+$hljs_symbol: #990073;
+$hljs_builtin: #0086b3;
+$hljs_meta: #999;
+$hljs_deletion: #fdd;
+$hljs_addition: #dfd; \ No newline at end of file
diff --git a/htdocs/scss/common-bundle.scss b/htdocs/scss/common-bundle.scss
deleted file mode 100644
index 397f0c3..0000000
--- a/htdocs/scss/common-bundle.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-@import "./common.scss";
-@import "./blog.scss";
-@import "./form.scss";
-@import "./hljs/github.scss";
-@import "./pages.scss";
-
-@media screen and (max-width: 600px) {
- @import "./mobile.scss";
-}
diff --git a/htdocs/scss/entries/admin/dark.scss b/htdocs/scss/entries/admin/dark.scss
new file mode 100644
index 0000000..d704436
--- /dev/null
+++ b/htdocs/scss/entries/admin/dark.scss
@@ -0,0 +1,2 @@
+@import '../../colors/dark';
+@import '../../bundle_admin'; \ No newline at end of file
diff --git a/htdocs/scss/entries/admin/light.scss b/htdocs/scss/entries/admin/light.scss
new file mode 100644
index 0000000..4ac8bf0
--- /dev/null
+++ b/htdocs/scss/entries/admin/light.scss
@@ -0,0 +1,2 @@
+@import '../../colors/light';
+@import '../../bundle_admin'; \ No newline at end of file
diff --git a/htdocs/scss/entries/common/dark.scss b/htdocs/scss/entries/common/dark.scss
new file mode 100644
index 0000000..f983214
--- /dev/null
+++ b/htdocs/scss/entries/common/dark.scss
@@ -0,0 +1,2 @@
+@import '../../colors/dark';
+@import '../../bundle_common'; \ No newline at end of file
diff --git a/htdocs/scss/entries/common/light.scss b/htdocs/scss/entries/common/light.scss
new file mode 100644
index 0000000..a3044bd
--- /dev/null
+++ b/htdocs/scss/entries/common/light.scss
@@ -0,0 +1,2 @@
+@import '../../colors/light';
+@import '../../bundle_common'; \ No newline at end of file
diff --git a/htdocs/scss/hljs.scss b/htdocs/scss/hljs.scss
deleted file mode 100644
index 36f52de..0000000
--- a/htdocs/scss/hljs.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "./hljs/github.css";
diff --git a/htdocs/scss/hljs/github.scss b/htdocs/scss/hljs/github.scss
index 791932b..ddbfc0a 100644
--- a/htdocs/scss/hljs/github.scss
+++ b/htdocs/scss/hljs/github.scss
@@ -1,27 +1,21 @@
-/*
-
-github.com style (c) Vasily Polovnyov <vast@whiteants.net>
-
-*/
-
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
- color: #333;
- background: #f8f8f8;
+ color: $hljs_fg;
+ background: $hljs_bg;
}
.hljs-comment,
.hljs-quote {
- color: #998;
+ color: $hljs_quote;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
- color: #333;
+ color: $hljs_fg;
font-weight: bold;
}
@@ -30,18 +24,18 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
- color: #008080;
+ color: $hljs_literal;
}
.hljs-string,
.hljs-doctag {
- color: #d14;
+ color: $hljs_string;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
- color: #900;
+ color: $hljs_title;
font-weight: bold;
}
@@ -51,43 +45,43 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
.hljs-type,
.hljs-class .hljs-title {
- color: #458;
+ color: $hljs_type;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
- color: #000080;
+ color: $hljs_tag;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
- color: #009926;
+ color: $hljs_regexp;
}
.hljs-symbol,
.hljs-bullet {
- color: #990073;
+ color: $hljs_symbol;
}
.hljs-built_in,
.hljs-builtin-name {
- color: #0086b3;
+ color: $hljs_builtin;
}
.hljs-meta {
- color: #999;
+ color: $hljs_meta;
font-weight: bold;
}
.hljs-deletion {
- background: #fdd;
+ background: $hljs_deletion;
}
.hljs-addition {
- background: #dfd;
+ background: $hljs_addition;
}
.hljs-emphasis {
diff --git a/htdocs/scss/vars.scss b/htdocs/scss/vars.scss
index e056740..cc67f04 100644
--- a/htdocs/scss/vars.scss
+++ b/htdocs/scss/vars.scss
@@ -4,42 +4,9 @@ $ff: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
$ffMono: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;
$base-width: 900px;
-//$sb-width: 120px;
$side-padding: 25px;
$base-padding: 18px;
-
$footer-height: 64px;
-$head-green-color: #0bad19;
-$head-red-color: #ce1a1a;
-$link-color: #116fd4;
-
-$bg: #f7f7f7;
-$content-bg: #fff;
-$code-block-bg: #f3f3f3;
-$inline-code-block-bg: #f1f1f1;
-
-$fg: #222;
-$blue1: #729fcf;
-$blue2: #3465a4;
-$blue3: #204a87;
-$orange1: #fcaf3e;
-$orange2: #f57900;
-$orange3: #ce5c00;
-
-$light-bg: #464c4e;
-$dark-bg: #272C2D;
-$dark-fg: #999;
-
-$input-border: #e0e0e0;
-$input-border-focused: #e0e0e0;
-$input-bg: #f7f7f7;
-$border-color: #e0e0e0;
-
-$error-block-bg: #f9eeee;
-$error-block-fg: #d13d3d;
-
-$success-block-bg: #eff5f0;
-$success-block-fg: #2a6f34;
@mixin radius($radius) {
-o-border-radius: $radius;
@@ -50,9 +17,9 @@ $success-block-fg: #2a6f34;
}
@mixin transition($property, $duration, $easing: linear) {
- transition: $property $duration $easing;
- -webkit-transition: $property $duration $easing;
- -moz-transition: $property $duration $easing;
+ transition: $property $duration $easing;
+ -webkit-transition: $property $duration $easing;
+ -moz-transition: $property $duration $easing;
}
@mixin linearGradient($top, $bottom){