Compare commits

...

11 commits

Author SHA1 Message Date
00d71d21e9 improve themability of notice blocks 2024-08-15 21:09:22 -05:00
ae966098ee fix for missing icon on old post notes 2024-08-15 21:08:59 -05:00
1301721d6f changelog: theme toggle 2024-08-15 16:21:19 -05:00
John Bowdre
d7e19b0a5c
Merge pull request #8 from jbowdre/theme_selection
Theme selection
2024-08-15 16:17:00 -05:00
2de36c1b02 implement dark/light toggle 2024-08-15 15:56:47 -05:00
3ced86d8d2 remove trailing space 2024-08-15 15:56:17 -05:00
3e90fb47a1 use separate color var for logo 2024-08-15 15:50:26 -05:00
baa8f624e4 use vars for colors in torchlight styling 2024-08-15 15:49:17 -05:00
b23983c02c change torchlight theme
this switches to a more neutral theme which looks okay against both
light and dark backgrounds
2024-08-15 15:43:39 -05:00
64ad1416d3 create light color palette 2024-08-15 15:36:46 -05:00
b9a8cdc849 update font-awesome 2024-08-15 15:36:13 -05:00
11 changed files with 239 additions and 114 deletions

View file

@ -126,17 +126,17 @@ opacity: 1;
Insert prompt indicators on interactive shells.
*/
.cmd::before {
color: var(--base07);
color: var(--user-prompt);
content: "$ ";
}
.cmd_root::before {
color: var(--base08);
color: var(--root-prompt);
content: "# ";
}
.cmd_pwsh::before {
color: var(--base07);
color: var(--user-prompt);
content: "PS> ";
}

40
assets/js/set-theme.js Normal file
View file

@ -0,0 +1,40 @@
const toggleButton = document.getElementById('themeToggle');
const htmlElement = document.documentElement;
function setTheme(theme) {
htmlElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
updateToggleButton(theme);
}
function updateToggleButton(theme) {
toggleButton.setAttribute('aria-checked', theme === 'dark');
}
function getPreferredTheme() {
const storedTheme = localStorage.getItem('theme');
if (storedTheme) {
return storedTheme;
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
// Ensure the toggle button state is correct on load
document.addEventListener('DOMContentLoaded', () => {
updateToggleButton(getPreferredTheme());
});
// Listen for toggle button clicks
toggleButton.addEventListener('click', () => {
const currentTheme = htmlElement.getAttribute('data-theme') || getPreferredTheme();
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
setTheme(newTheme);
});
// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem('theme')) {
const newTheme = e.matches ? 'dark' : 'light';
setTheme(newTheme);
}
});

View file

@ -1,7 +1,7 @@
---
title: "/changelog"
date: "2024-05-26T21:19:08Z"
lastmod: "2024-08-04T22:30:43Z"
lastmod: "2024-08-15T21:21:05Z"
description: "Maybe I should keep a log of all my site-related tinkering?"
featured: false
toc: false
@ -10,6 +10,9 @@ categories: slashes
---
*Running list of config/layout changes to the site. The full changelog is of course [on GitHub](https://github.com/jbowdre/runtimeterror/commits/main/).*
**2024-08-15:**
- Implemented light/dark theme toggle
**2024-08-04:**
- Dynamically build `robots.txt` based on [ai.robots.txt](https://github.com/ai-robots-txt/ai.robots.txt)

View file

@ -26,7 +26,7 @@
{{- if and (gt $ageDays 365) (not .Params.timeless) -}}
<br>
<div class="notice note">
<p class="first notice-title"><span class="icon-notice baseline"><svg><use href="#note-notice"></use></svg></span>Technology keeps moving but this post has not.</p>
<p class="first notice-title"><span class="icon-notice baseline"><svg id="note-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet"><path d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/></svg></span>Technology keeps moving but this post has not.</p>
What you're about to read hasn't been updated in more than a year. The information may be out of date. Let me know if you see anything that needs fixing.
</div>
{{- end -}}

View file

@ -1,7 +1,7 @@
{{ with .Site.Params.about }}
<div class="aside__about">
{{ with .logo }}<img class="about__logo" src="{{ . | absURL }}" alt="Logo">{{ end }}
<h1 class="about__title">{{ .title }}&nbsp;<a href="/feed.xml" aria-label="RSS"><i class="fa-solid fa-square-rss"></i></a>&nbsp;</h1>
<h1 class="about__title">{{ .title }}&nbsp;<a href="/feed.xml" aria-label="RSS"><i class="fa-solid fa-square-rss"></i></a></h1>
{{ partial "tagline.html" . }}
<br>
<a href="/about/"><i class="fa-regular fa-user"></i></a>&nbsp;<a href="/about/">{{ site.Params.Author.name }}</a>

View file

@ -15,3 +15,7 @@
{{ $jsCopy := resources.Get "js/code-copy-button.js" | minify }}
<script src="{{ $jsCopy.RelPermalink }}" async></script>
{{ end }}
<!-- theme switch -->
{{ $themeToggle := resources.Get "js/set-theme.js" | minify }}
<script src="{{ $themeToggle.RelPermalink }}"></script>

View file

@ -21,8 +21,20 @@
{{ partialCached "favicon" . }}
{{ partial "opengraph" . }}
<!-- load theme preference asap -->
<script>
(function() {
var savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
} else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
document.documentElement.setAttribute('data-theme', 'light');
}
})();
</script>
<!-- FontAwesome <https://fontawesome.com/> -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A==" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg==" crossorigin="anonymous" />
<!-- ForkAwesome <https://forkaweso.me/> -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css" integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">

View file

@ -7,4 +7,8 @@
{{ end }}
</ul>
</nav>
<button id="themeToggle" class="theme-toggle" aria-label="Toggle light/dark theme" title="Toggle light/dark theme">
<svg class="theme-toggle__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M448 256c0-106-86-192-192-192l0 384c106 0 192-86 192-192zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z"/>
</svg>
</button>

View file

@ -1,9 +1,113 @@
/* color and font overrides */
/* define fonts */
:root {
--code: var(--base06);
--font-monospace: 'Berkeley Mono', 'IBM Plex Mono', 'Cascadia Mono', 'Roboto Mono', 'Source Code Pro', 'Fira Mono', 'Courier New', monospace;
}
/* dark/light theming */
:root{
/* Default dark theme */
--bg: var(--dark-base00);
--code: var(--dark-base06);
--fg: var(--dark-base05);
--highlight: var(--dark-base0A);
--hover: var(--dark-base0C);
--inner-bg: var(--dark-base02);
--link: var(--dark-base0D);
--logo-text: var(--dark-base09);
--logo: var(--dark-base0B);
--muted: var(--dark-base03);
--off-bg: var(--dark-base01);
--off-fg: var(--dark-base04);
--root-prompt: var(--dark-base08);
--user-prompt: var(--dark-base07);
}
:root[data-theme="light"] {
--bg: var(--light-base00);
--off-bg: var(--light-base01);
--inner-bg: var(--light-base02);
--muted: var(--light-base03);
--off-fg: var(--light-base04);
--fg: var(--light-base05);
--code: var(--light-base06);
--user-prompt: var(--light-base07);
--root-prompt: var(--light-base08);
--logo-text: var(--light-base09);
--highlight: var(--light-base0A);
--logo: var(--light-base0B);
--hover: var(--light-base0C);
--link: var(--light-base0D);
}
@media (prefers-color-scheme: light) {
:root:not([data-theme="dark"]) {
--bg: var(--light-base00);
--off-bg: var(--light-base01);
--inner-bg: var(--light-base02);
--muted: var(--light-base03);
--off-fg: var(--light-base04);
--fg: var(--light-base05);
--code: var(--light-base06);
--user-prompt: var(--light-base07);
--root-prompt: var(--light-base08);
--logo-text: var(--light-base09);
--highlight: var(--light-base0A);
--logo: var(--light-base0B);
--hover: var(--light-base0C);
--link: var(--light-base0D);
}
}
body {
transition: background-color 0.3s ease, color 0.3s ease;
}
.theme-toggle {
position: absolute;
top: 1rem;
right: 1rem;
background: none;
border: none;
cursor: pointer;
padding: 0;
width: 2rem;
height: 2rem;
z-index: 1000;
transition: opacity 0.3s ease;
}
.theme-toggle:hover {
opacity: 0.7;
}
.theme-toggle:focus {
outline: none;
}
.theme-toggle:focus-visible {
outline: 2px solid var(--hover);
outline-offset: 2px;
}
.theme-toggle__icon {
width: 100%;
height: 100%;
transition: transform 0.3s ease, fill 0.3s ease;
fill: var(--off-fg);
}
.theme-toggle:hover .theme-toggle__icon {
fill: var(--hover);
}
[data-theme="dark"] .theme-toggle__icon {
transform: rotate(180deg);
}
.page__nav ul {
padding-right: 3rem;
}
/* load preferred font */
@font-face {
font-family: 'Berkeley Mono';
@ -30,7 +134,7 @@
/* logo tweaks */
.page__logo {
color: var(--off-fg);
color: var(--logo-text);
}
.page__logo-inner {
@ -70,59 +174,24 @@
/* Notice CSS Built on hugo-notice by Nicolas Martignoni: https://github.com/martignoni/hugo-notice */
.notice {
--root-color: #444;
--root-background: #eff;
--title-color: #fff;
--title-background: #7bd;
--warning-title: #c33;
--warning-content: #fee;
--info-title: #fb7;
--info-content: #fec;
--note-title: #6be;
--note-content: #e7f2fa;
--tip-title: #5a5;
--tip-content: #efe;
}
--notice-title-color: #fff;
--notice-warn-color: #c33;
--notice-info-color: #fb7;
--notice-note-color: #6be;
--notice-tip-color: #5a5;
@media (prefers-color-scheme: dark) {
.notice {
--root-color: #ddd;
--root-background: #eff;
--title-color: #fff;
--title-background: #7bd;
--warning-title: #800;
--warning-content: #400;
--info-title: #a50;
--info-content: #420;
--note-title: #069;
--note-content: #023;
--tip-title: #363;
--tip-content: #121;
}
}
--notice-padding: 18px;
--notice-line-height: 24px;
--notice-margin-bottom: 24px;
--notice-border-radius: 4px;
--notice-title-margin: 12px;
--notice-bg-opacity: 10%;
body.dark .notice {
--root-color: #ddd;
--root-background: #eff;
--title-color: #fff;
--title-background: #7bd;
--warning-title: #800;
--warning-content: #400;
--info-title: #a50;
--info-content: #420;
--note-title: #069;
--note-content: #023;
--tip-title: #363;
--tip-content: #121;
}
.notice {
padding: 18px;
line-height: 24px;
margin-bottom: 24px;
border-radius: 4px;
color: var(--root-color);
background: var(--root-background);
padding: var(--notice-padding);
line-height: var(--notice-line-height);
margin-bottom: var(--notice-margin-bottom);
border-radius: var(--notice-border-radius);
color: var(--fg);
}
.notice p:last-child {
@ -130,45 +199,23 @@ body.dark .notice {
}
.notice-title {
margin: -18px -18px 12px;
padding: 4px 18px;
border-radius: 4px 4px 0 0;
margin: calc(-1 * var(--notice-padding));
margin-bottom: var(--notice-title-margin);
padding: 4px var(--notice-padding);
border-radius: var(--notice-border-radius) var(--notice-border-radius) 0 0;
font-weight: 700;
color: var(--title-color);
background: var(--title-background);
color: var(--notice-title-color);
}
.notice.warning .notice-title {
background: var(--warning-title);
}
.notice.warning .notice-title { background: var(--notice-warning-color); }
.notice.info .notice-title { background: var(--notice-info-color); }
.notice.note .notice-title { background: var(--notice-note-color); }
.notice.tip .notice-title { background: var(--notice-tip-color); }
.notice.warning {
background: var(--warning-content);
}
.notice.info .notice-title {
background: var(--info-title);
}
.notice.info {
background: var(--info-content);
}
.notice.note .notice-title {
background: var(--note-title);
}
.notice.note {
background: var(--note-content);
}
.notice.tip .notice-title {
background: var(--tip-title);
}
.notice.tip {
background: var(--tip-content);
}
.notice.warning { background: color-mix(in srgb, var(--notice-warning-color) var(--notice-bg-opacity), transparent); }
.notice.info { background: color-mix(in srgb, var(--notice-info-color) var(--notice-bg-opacity), transparent); }
.notice.note { background: color-mix(in srgb, var(--notice-note-color) var(--notice-bg-opacity), transparent); }
.notice.tip { background: color-mix(in srgb, var(--notice-tip-color) var(--notice-bg-opacity), transparent); }
.icon-notice {
display: inline-flex;

View file

@ -2,20 +2,35 @@
*/
:root {
--base00: #090909; /* bg */
--base01: #1c1c1c; /* off-bg */
--base02: #292929; /* inner-bg */
--base03: #6d6c6c; /* muted */
--base04: #abaaaa; /* off-fg */
--base05: #d8d8d8; /* fg */
--base06: #75f558; /* code */
--base07: #5f8700; /* user prompt */
--base08: #ab4642; /* root prompt */
--base09: #dc9656;
--base0A: #f7ca88; /* highlight */
--base0B: #682523; /* logo */
--base0C: #ab2321; /* hover */
--base0D: #d36060; /* link */
--base0E: #ba8baf;
--base0F: #a16946;
/* dark theme colors */
--dark-base00: #090909; /* bg */
--dark-base01: #1c1c1c; /* off-bg */
--dark-base02: #292929; /* inner-bg */
--dark-base03: #6d6c6c; /* muted */
--dark-base04: #abaaaa; /* off-fg */
--dark-base05: #d8d8d8; /* fg */
--dark-base06: #75f558; /* code */
--dark-base07: #5f8700; /* user prompt */
--dark-base08: #ab4642; /* root prompt */
--dark-base09: #abaaaa; /* logo text */
--dark-base0A: #f7ca88; /* highlight */
--dark-base0B: #682523; /* logo */
--dark-base0C: #ab2321; /* hover */
--dark-base0D: #d36060; /* link */
/* light theme colors */
--light-base00: #ffffff; /* bg */
--light-base01: #f0f0f0; /* off-bg */
--light-base02: #dbdbdb; /* inner-bg */
--light-base03: #909090; /* muted */
--light-base04: #707070; /* off-fg */
--light-base05: #303030; /* fg */
--light-base06: #2a8f1f; /* code */
--light-base07: #3f5900; /* user prompt */
--light-base08: #c23d3d; /* root prompt */
--light-base09: #f0f0f0; /* logo-text */
--light-base0A: #d4a960; /* highlight */
--light-base0B: #af3a37; /* logo */
--light-base0C: #c62a28; /* hover */
--light-base0D: #a04545; /* link */
}

View file

@ -11,7 +11,7 @@ module.exports = {
// Which theme you want to use. You can find all of the themes at
// https://torchlight.dev/docs/themes.
theme: 'synthwave-84',
theme: 'material-theme-lighter',
// The Host of the API.
host: 'https://api.torchlight.dev',