diff --git a/assets/css/torchlight.css b/assets/css/torchlight.css
index 5def64b..a864f1a 100644
--- a/assets/css/torchlight.css
+++ b/assets/css/torchlight.css
@@ -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> ";
}
diff --git a/assets/js/set-theme.js b/assets/js/set-theme.js
new file mode 100644
index 0000000..5ee4ac4
--- /dev/null
+++ b/assets/js/set-theme.js
@@ -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);
+ }
+});
\ No newline at end of file
diff --git a/layouts/partials/about.html b/layouts/partials/about.html
index f78bae7..d0e4a3e 100644
--- a/layouts/partials/about.html
+++ b/layouts/partials/about.html
@@ -1,7 +1,7 @@
{{ with .Site.Params.about }}
{{ with .logo }}
{{ end }}
-
{{ .title }}
+
{{ .title }}
{{ partial "tagline.html" . }}
{{ site.Params.Author.name }}
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html
index 9f713ba..d1ba2ac 100644
--- a/layouts/partials/footer.html
+++ b/layouts/partials/footer.html
@@ -15,3 +15,7 @@
{{ $jsCopy := resources.Get "js/code-copy-button.js" | minify }}
{{ end }}
+
+
+{{ $themeToggle := resources.Get "js/set-theme.js" | minify }}
+
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index 113b5ee..4691e45 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -21,8 +21,20 @@
{{ partialCached "favicon" . }}
{{ partial "opengraph" . }}
+
+
+
-
+
diff --git a/layouts/partials/header.html b/layouts/partials/header.html
index 45c46ce..c3435de 100644
--- a/layouts/partials/header.html
+++ b/layouts/partials/header.html
@@ -7,4 +7,8 @@
{{ end }}
-
+
\ No newline at end of file
diff --git a/static/css/custom.css b/static/css/custom.css
index c7c6ddf..0398121 100644
--- a/static/css/custom.css
+++ b/static/css/custom.css
@@ -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 {
diff --git a/static/css/palettes/runtimeterror.css b/static/css/palettes/runtimeterror.css
index 76e566e..5d6b2a9 100644
--- a/static/css/palettes/runtimeterror.css
+++ b/static/css/palettes/runtimeterror.css
@@ -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 */
}
diff --git a/torchlight.config.js b/torchlight.config.js
index bc799f9..8c44c81 100644
--- a/torchlight.config.js
+++ b/torchlight.config.js
@@ -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',