11 changed files with 293 additions and 39 deletions
@ -0,0 +1,67 @@ |
|||||||
|
import { Controller } from '@hotwired/stimulus'; |
||||||
|
|
||||||
|
const STORAGE_KEY = 'unfold-color-scheme'; |
||||||
|
|
||||||
|
export default class extends Controller { |
||||||
|
static targets = ['moon', 'sun']; |
||||||
|
|
||||||
|
connect() { |
||||||
|
this.link = document.getElementById('theme-magazine-stylesheet'); |
||||||
|
this._syncFromDom(); |
||||||
|
this._refreshIcons(); |
||||||
|
} |
||||||
|
|
||||||
|
toggle() { |
||||||
|
const cur = document.documentElement.getAttribute('data-color-scheme') || 'light'; |
||||||
|
const next = cur === 'dark' ? 'light' : 'dark'; |
||||||
|
this.apply(next, true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param {'light'|'dark'} scheme |
||||||
|
* @param {boolean} persist |
||||||
|
*/ |
||||||
|
apply(scheme, persist) { |
||||||
|
const siteDefault = document.documentElement.getAttribute('data-color-scheme-default') || 'dark'; |
||||||
|
if (scheme !== 'dark' && scheme !== 'light') { |
||||||
|
scheme = siteDefault; |
||||||
|
} |
||||||
|
const darkHref = this.link?.getAttribute('data-href-dark'); |
||||||
|
if (scheme === 'dark' && !darkHref) { |
||||||
|
scheme = 'light'; |
||||||
|
} |
||||||
|
document.documentElement.setAttribute('data-color-scheme', scheme); |
||||||
|
if (persist) { |
||||||
|
try { |
||||||
|
localStorage.setItem(STORAGE_KEY, scheme); |
||||||
|
} catch (_) { |
||||||
|
/* private mode */ |
||||||
|
} |
||||||
|
} |
||||||
|
if (this.link) { |
||||||
|
const light = this.link.getAttribute('data-href-light'); |
||||||
|
this.link.setAttribute('href', scheme === 'dark' && darkHref ? darkHref : light); |
||||||
|
} |
||||||
|
this._refreshIcons(); |
||||||
|
} |
||||||
|
|
||||||
|
_syncFromDom() { |
||||||
|
/* Link href was set by inline script; icons follow current scheme. */ |
||||||
|
this._refreshIcons(); |
||||||
|
} |
||||||
|
|
||||||
|
_refreshIcons() { |
||||||
|
const dark = document.documentElement.getAttribute('data-color-scheme') === 'dark'; |
||||||
|
if (this.hasMoonTarget) { |
||||||
|
this.moonTarget.hidden = dark; |
||||||
|
} |
||||||
|
if (this.hasSunTarget) { |
||||||
|
this.sunTarget.hidden = !dark; |
||||||
|
} |
||||||
|
const btn = this.element.querySelector('.color-scheme-toggle'); |
||||||
|
if (btn) { |
||||||
|
btn.setAttribute('aria-label', dark ? 'Switch to light mode' : 'Switch to dark mode'); |
||||||
|
btn.setAttribute('title', dark ? 'Light mode' : 'Dark mode'); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 91 KiB |
@ -0,0 +1,62 @@ |
|||||||
|
/* |
||||||
|
* imwald / magazine dark color scheme (second stylesheet). |
||||||
|
* Loaded only when data-color-scheme="dark" and config theme_stylesheet_dark is set. |
||||||
|
* Override tokens here; keep components using var(--color-…). |
||||||
|
*/ |
||||||
|
html[data-color-scheme="dark"] { |
||||||
|
/* Backgrounds */ |
||||||
|
--color-bg: #1c1a18; |
||||||
|
--color-bg-light: #262320; |
||||||
|
--color-bg-primary: #2f2b27; |
||||||
|
/* Text */ |
||||||
|
--color-text: #e8e1d9; |
||||||
|
--color-text-mid: #b7ada3; |
||||||
|
--color-text-contrast: #1c1a18; |
||||||
|
/* Accents (muted greens) */ |
||||||
|
--color-primary: #8faf8f; |
||||||
|
--color-secondary: #a8c3a8; |
||||||
|
--color-primary-strong: #6f9a6f; |
||||||
|
--color-border: #3a3632; |
||||||
|
--color-border-soft: #2a2724; |
||||||
|
--color-text-light: var(--color-text-mid); |
||||||
|
--color-footer-bg: #1c1a18; |
||||||
|
--color-footer-text: var(--color-text); |
||||||
|
--color-footer-link: var(--color-primary); |
||||||
|
--color-highlight-mark-fg: #1c1a18; |
||||||
|
--color-link: #8faf8f; |
||||||
|
--color-link-hover: #a8c3a8; |
||||||
|
--color-link-visited: #7e9f7e; |
||||||
|
--color-focus-ring: #8faf8f; |
||||||
|
--color-shadow: color-mix(in srgb, #000 28%, transparent); |
||||||
|
--brand-color: #e8e1d9; |
||||||
|
--accent-color: var(--color-secondary); |
||||||
|
/* Reading pane / headline stack: clearly lifted from --color-bg (88/12 was visually identical). */ |
||||||
|
--article-reading-pane-bg: color-mix(in srgb, var(--color-bg) 28%, var(--color-bg-light) 72%); |
||||||
|
--article-reading-prose-color: color-mix(in srgb, var(--color-text-mid) 38%, var(--color-text) 62%); |
||||||
|
} |
||||||
|
|
||||||
|
html[data-color-scheme="dark"] a:visited { |
||||||
|
color: var(--color-link-visited); |
||||||
|
} |
||||||
|
|
||||||
|
html[data-color-scheme="dark"] .article-main p, |
||||||
|
html[data-color-scheme="dark"] .article-main ul, |
||||||
|
html[data-color-scheme="dark"] .article-main ol, |
||||||
|
html[data-color-scheme="dark"] .article-main li { |
||||||
|
font-weight: 450; |
||||||
|
} |
||||||
|
|
||||||
|
html[data-color-scheme="dark"] .home-aside-highlights__item-inner { |
||||||
|
border-left: 2px solid var(--color-primary); |
||||||
|
padding-left: 0.5rem; |
||||||
|
background: color-mix(in srgb, var(--color-bg-light) 55%, transparent); |
||||||
|
} |
||||||
|
|
||||||
|
html[data-color-scheme="dark"] .home-aside-highlights__quote { |
||||||
|
color: #d8d0c8; |
||||||
|
} |
||||||
|
|
||||||
|
html[data-color-scheme="dark"] .home-aside-highlights__item-inner:hover, |
||||||
|
html[data-color-scheme="dark"] .home-aside-highlights__item-inner:has(.home-aside-highlights__hit:focus-visible) { |
||||||
|
background: #2f2b27; |
||||||
|
} |
||||||
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 91 KiB |
Loading…
Reference in new issue