Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _includes/head_custom.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible:wght@400;700&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
<link rel="sitemap" type="application/xml" title="Sitemap" href="{{ '/sitemap.xml' | absolute_url }}">
<script src="{{ '/assets/js/appearance.js' | relative_url }}"></script>
11 changes: 11 additions & 0 deletions _includes/header_custom.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="appearance-control">
<button id="appearance" type="button" aria-label="Switch to dark mode" title="Switch to dark mode">
<svg class="appearance-moon" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
<path d="M20.5 13.2A8.5 8.5 0 0 1 10.8 3.5a8.5 8.5 0 1 0 9.7 9.7Z" />
</svg>
<svg class="appearance-sun" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round">
<circle cx="12" cy="12" r="4" />
<path d="M12 2v2m0 16v2M2 12h2m16 0h2M4.9 4.9l1.4 1.4m11.4 11.4 1.4 1.4m0-14.2-1.4 1.4M6.3 17.7l-1.4 1.4" />
</svg>
</button>
</div>
154 changes: 154 additions & 0 deletions _sass/custom/appearance.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
.search-input::placeholder, .search-icon { color: #66707b; }

.appearance-control {
display: none;
align-items: center;
padding: .5rem 1rem;
flex-shrink: 0;
font-size: .75rem;

button {
display: grid;
place-items: center;
width: 2.5rem;
height: 2.5rem;
padding: .5rem;
border: 0;
border-radius: .5rem;
background: transparent;
color: #2a2f36;
font: inherit;
cursor: pointer;
}
}

:root[data-theme] .appearance-control { display: flex; }
.appearance-control button:hover { background: #e5e9ed; }
.appearance-control svg { width: 1.25rem; height: 1.25rem; }
.appearance-sun { display: none; }
:root[data-theme="dark"] .appearance-moon { display: none; }
:root[data-theme="dark"] .appearance-sun { display: block; }

.appearance-control button:focus-visible {
outline: 2px solid #5f7ea1;
outline-offset: 3px;
}

// keep appearance available when the mobile navigation is collapsed
@media (max-width: 49.99rem) {
body .side-bar + .main .main-header,
body .side-bar + .main .main-header.nav-open { display: flex; }
.search { min-width: 0; }
.appearance-control { padding-left: 0; }
}

@mixin dark-appearance {
color-scheme: dark;

body { color: #c9d2de; background: #141a23; }
h1, h2, h3, h4, h5, h6, #toctitle { color: #edf2f8; }
a, .main-content a { color: #9cc9ec; }
a:not([class]) { text-decoration-color: #526b82; }
a:not([class]):hover { text-decoration-color: #9cc9ec; }
:focus-visible { outline-color: #9cc9ec; }
hr { background: #303c4c; }

.side-bar {
background: radial-gradient(ellipse at top left, rgba(104, 151, 194, .08), transparent 65%), #191f29;
border-color: #303c4c;
}
.site-header, .main-header, .site-nav, .site-footer { border-color: #303c4c; }
body .side-bar + .main .main-header { background: #141a23; }
.site-title { color: #edf2f8 !important; }
.site-title:hover, .site-button:hover { background: #242f3e; }
.site-footer { color: #9baabc; }
.icon, .site-button, .nav-list .nav-list-item .nav-list-expander { color: #9cc9ec; }
.nav-list .nav-list-item > .nav-list .nav-list-item .nav-list-link,
.nav-list .nav-list-item > .nav-list .nav-list-item .nav-list-expander { color: #b8c7d8; }
.nav-list .nav-list-item .nav-list-link:hover,
.nav-list .nav-list-item .nav-list-link.active,
.nav-list .nav-list-item .nav-list-expander:hover {
background: linear-gradient(90deg, rgba(104, 151, 194, .04), rgba(104, 151, 194, .16));
color: #d1e9ff;
}
.nav-list-link.active { box-shadow: inset 3px 0 #8dbce2; }
.breadcrumb-nav-list-item::after { color: #77889b; }

.search-input, .search-results, .search-result { color: #c9d2de; background: #191f29; }
.search-input { background: #141a23; }
.search-input::placeholder, .search-icon { color: #9baabc; }
.search-result:hover, .search-result.active { background: #243244; }
.search-result-title, .search-result-doc, .search-result-section { color: #d1e9ff; }
.search-result-preview { color: #b8c7d8; }
.search-result-previews { border-color: #405169; }
.search-result-doc.search-result-doc-parent { opacity: 1; color: #9baabc; }
.search-result-doc .search-result-icon { color: #9baabc; }
.search-result-rel-url { color: #9baabc; }
.search-result-highlight { color: #edf2f8; }
.search-results { border: 1px solid #303c4c; box-shadow: 0 16px 40px #0006; }

.appearance-control { color: #9baabc; }
.appearance-control button { color: #dce6f2; }
.appearance-control button:hover { background: #29394c; }
.appearance-control button:focus-visible { outline-color: #9cc9ec; }

.main-content :not(pre) > code { color: #d1e9ff; background: #253142; border-color: #35465b; }
.main-content pre.highlight,
.main-content div.highlighter-rouge,
.main-content #lj-editor,
.main-content .lj-output {
background: #101620;
border-color: #344256;
box-shadow: none;
}
.main-content .highlight .c,
.main-content .highlight .cm,
.main-content .highlight .c1,
.main-content .highlight .cs { color: #9baabc; }
.main-content img:not(.home-banner img) { border-color: #344256; box-shadow: none; }
.home-banner img { filter: brightness(.82) saturate(.9); }
.home-banner { border: 1px solid #344256; background: #101620; }
.main-content blockquote { background: #1d2836; border-color: #718da9; }

.card-panel, .page-nav-link {
background: #1c2531;
border-color: #334154;
box-shadow: none;
}
.card-panel:hover, .page-nav-link:hover { background: #232f3e; border-color: #6383a2; box-shadow: none; }
.page-nav-label { color: #9baabc; }
.page-nav-title { color: #dce6f2; }
.page-nav-link:focus-visible { outline: 2px solid #9cc9ec; outline-offset: 3px; box-shadow: none; }
.main-content .home-button { background: #9cc9ec; color: #142332; box-shadow: none; }
.main-content .home-button:hover { background: #bcdef7; color: #142332; }
th, td { background: #1c2531; border-color: #334154; }
thead th { background: #253142; border-color: #405169; color: #edf2f8; }
.table-wrapper { border: 1px solid #334154; box-shadow: none; }

@each $name, $accent, $surface in (note, #9cc9ec, #1d2c3d), (tip, #a7d9b9, #1d302d), (warn, #e5c784, #322e23) {
.main-content p.#{$name}, .main-content blockquote.#{$name} {
background: $surface;
border-color: $accent;
box-shadow: none;
&::before, > .#{$name}-title { color: $accent; }
}
}

.lj-toolbar label { color: #b8c7d8; }
.lj-toolbar select { color: #dce6f2; background: #202b39; border-color: #405169; }
.lj-toolbar select:hover { background: #29394c; border-color: #8dbce2; }
.lj-toolbar button { color: #9cc9ec; border-color: #405169; }
.lj-toolbar button:hover:not(:disabled) { background: #29394c; border-color: #8dbce2; }
.lj-toolbar #lj-verify, .lj-toolbar #lj-reset { color: #142332; background: #9cc9ec; border-color: #9cc9ec; }
.lj-toolbar #lj-verify:hover:not(:disabled), .lj-toolbar #lj-reset:hover { color: #142332; background: #bcdef7; border-color: #bcdef7; }
.lj-toolbar #lj-verify[data-state="busy"] { color: #fff; background: #a8323d; border-color: #cb6871; }
.lj-toolbar #lj-verify[data-state="busy"]:hover { background: #bd3d49; }
.lj-toolbar button:disabled, .lj-toolbar #lj-verify:disabled { color: #9baabc; background: #293342; border-color: #405169; }
}

:root[data-theme="dark"] { @include dark-appearance; }

// the system theme also works without JavaScript
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) { @include dark-appearance; }
}
20 changes: 17 additions & 3 deletions _sass/custom/custom.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
.site-header {
border-bottom: 1px solid rgba(23, 26, 31, 0.08);
.site-header,
.main-header {
border-bottom: 0;
}

.main-content > hr {
display: none;
}

.site-title {
Expand Down Expand Up @@ -248,6 +253,14 @@
list-style: disc;
}

.main-content ul > li::before {
content: none;
}

.main-content .task-list-item {
list-style: none;
}

.main-content li > ul,
.main-content li > ol {
margin-top: 0.35rem;
Expand Down Expand Up @@ -333,7 +346,6 @@
gap: 0.75rem;
margin: 2.25rem 0 0.25rem;
padding-top: 1.25rem;
border-top: 1px solid rgba(17, 24, 39, 0.08);
}

.page-nav-link {
Expand Down Expand Up @@ -402,3 +414,5 @@
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}

@import "custom/appearance";
35 changes: 35 additions & 0 deletions assets/js/appearance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(() => {
const root = document.documentElement;
const system = window.matchMedia('(prefers-color-scheme: dark)');
const key = 'liquidjava-appearance';
let preference = 'system';
let button;
try {
const saved = localStorage.getItem(key);
if (['light', 'dark'].includes(saved)) preference = saved;
} catch (_) { /* appearance still works when storage is unavailable */ }

function apply() {
root.dataset.theme = preference === 'system'
? (system.matches ? 'dark' : 'light') : preference;
if (button) {
const label = root.dataset.theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode';
button.setAttribute('aria-label', label);
button.title = label;
}
}
apply();
system.addEventListener('change', apply);

document.addEventListener('DOMContentLoaded', () => {
button = document.getElementById('appearance');
apply();
button.addEventListener('click', () => {
preference = root.dataset.theme === 'dark' ? 'light' : 'dark';
try {
localStorage.setItem(key, preference);
} catch (_) { /* keep the selection for this page */ }
apply();
});
});
})();
Loading