From 25837942fcbbe0f61bf8d102ddc9dd4c2a4976da Mon Sep 17 00:00:00 2001 From: speyll Date: Fri, 25 Apr 2025 01:55:36 +0100 Subject: [PATCH] optimized js --- public/click.ogg | Bin 0 -> 1058 bytes public/css/style.css | 125 +++++++++++++++++++++++++++++++++++++++++++ public/favicon.ico | Bin 0 -> 204 bytes public/icons.svg | 21 ++++++++ public/js/script.js | 73 +++++++++++++++++++++++++ static/js/script.js | 9 ++-- 6 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 public/click.ogg create mode 100644 public/css/style.css create mode 100644 public/favicon.ico create mode 100644 public/icons.svg create mode 100644 public/js/script.js diff --git a/public/click.ogg b/public/click.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f9c6dc0677c4e2273fbba937fb47863b1a8ed9a9 GIT binary patch literal 1058 zcmeZIPY-5bVt|4f`K6~p%pa`>S2GIx7nBxzq$Z{?GFdP->;^0G2PuaGka9*K&+o|T z?TmIHGXp(C5HbKMkp<$^yyX0p)FNA;WHM0F$Ot5|_P_16%~G#ztPQdn zh%tGKR6>2;a( z-nWmpxcw?L^;oDNs#JVeu(Rt#!FiXtHS>Ww{`RcA*C_ihDCgdZ^9|Bwj_=gItGszP zZDy>6>J!&6XR-W%xA9qFEW$!r{2>NvCw3oES`cut&cCLENs-sd^6g@OkHjLEH9LRS zn951BfBI|WIPFra1DnQmov$?%>fkTg{iF zYB(6bpL$;!f1&layh5_1)`qp49;w&7OzPjR9cp^TPUHJI#`{@C`K&;79}n{#Q!u_Q zrT0ks@LPo)H9QJ3{V&>LWHw2^e6=|NsNfB^X4ZCFmvdM1_ig@brZMxA(|m^n^OaAE zHt-|Kepdg@t^X~4Q*E9Yvw?eKTz6;ZPEm8EJ_jsncAPO%J2WGM>x=eHkeUq)Xlk5~ zwFjZ8*#tL7qsb4_6PEa$V2`vjs6aMg4$Zo70Rbnk)amScH7yHzLM zou2Gu7oL1}Z^Sg-J6AOJXiuMZyk*Zt<7@icW_Tz`3T(R8yGC-Ul=$S-q&YWy+^?P3 z`t?rzf1okvCq_pGOxK-~UZNEoSQ+_TfW2hx+r3uDzV${PEn;|?g^pO z<ueY1MH)MUq!H%%m#BQ5Mwkyw>HSsuAFlB4i|@6bA|5qQ zMB=GjqGHu5_8*Kh@|Sg1?l{b7HnU(B$k?c>TX?KzZ3$k!%w_Y+h-?et=G5)KZ}VT1 z*46U+^JQa0Vr}dHFQWgNHfn)XLz4h7lDWRLJ`NPy;}c!Rqu=mhKS)W_1q>xGF4g8O Qd-#n9sOF15NKMZK07QDkzyJUM literal 0 HcmV?d00001 diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 0000000..1affa22 --- /dev/null +++ b/public/css/style.css @@ -0,0 +1,125 @@ +:root { + --icon-size: 1.3rem; + --icon-color: var(--text); +} + +#nav-bar { + padding: 0.625rem 0 0; + display: flex; + flex-wrap: wrap; + gap: 0.25rem; + justify-content: flex-end; + align-items: center; +} + +#footer-container { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; +} + +.accent-data { + color: var(--accent); +} + +.theme-transition { + transition: color 0.3s ease, background-color 0.3s ease; +} + +.tags-data { + display: flex; + flex-direction: column; + flex-wrap: wrap; + justify-content: flex-end; + align-items: flex-start; + align-content: flex-end +} + +.title-list li { + margin-bottom: .375rem; +} + +/* icons settings */ +.icon { + width: var(--icon-size); + height: var(--icon-size); + display: inline-block; + vertical-align: middle; + color: var(--icon-color); + fill: currentColor; + transition: color 0.3s ease; + cursor: pointer; +} + +.icon:hover { + --icon-color: var(--accent); +} + +/* Theme toggle specific styles */ +.theme-toggle { + cursor: pointer; + padding: 0; + margin: 0; + background: none; + border: none; + display: inline-flex; +} + +.theme-toggle:hover .icon { + --icon-color: var(--accent); +} + +.theme-toggle:active { + transform: scale(0.95); +} + +/* footnotes */ +.footnote-definition { + margin: 0 0 0 .125rem; +} + +.footnote-definition-label { + color: var(--accent); +} + +.footnote-definition p { + display: inline; + margin: .625rem 0 0 .625rem; +} + +/* general classes */ +/* Cleaned no-style class */ +.no-style { + all: unset; + background: none !important; + border: none !important; +} + +.no-style:hover { + background: transparent; + color: inherit; +} + +/* Modern float replacement */ +.float-right { + margin-inline-start: auto; +} + +.float-left { + margin-inline-end: auto; +} + +.center { + text-align: center; +} + +.center img { + display: block; + margin: 1rem auto; +} + +/* shortcodes css */ +.webring { + margin: .375rem; +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7eb16eac96acaf14cbf976e8efb1caee8693285d GIT binary patch literal 204 zcmZQzU<5(|0R|wcz_5*hfk6z2I|KaOdAX#xfJ|Ob50@Yy4OGD(z`+J2gTe~DWM4f`EE<} literal 0 HcmV?d00001 diff --git a/public/icons.svg b/public/icons.svg new file mode 100644 index 0000000..6fe3989 --- /dev/null +++ b/public/icons.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/public/js/script.js b/public/js/script.js new file mode 100644 index 0000000..1a181b6 --- /dev/null +++ b/public/js/script.js @@ -0,0 +1,73 @@ +class ThemeManager { + constructor() { + this.toggle = document.getElementById('theme-toggle'); + if (!this.toggle) return; + + this.icon = document.getElementById('theme-icon'); + const { iconBase, iconDark, iconLight, soundSrc } = this.toggle.dataset; + this.iconBase = iconBase; + this.iconDark = iconDark; + this.iconLight = iconLight; + + // Create audio element lazily only when needed + this.sound = null; + this.soundSrc = soundSrc; + + this.init(); + } + + init() { + this.setInitialTheme(); + this.toggle.addEventListener('click', () => this.toggleTheme()); + } + + setInitialTheme() { + const savedTheme = localStorage.getItem('theme'); + const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + const initialTheme = savedTheme || (systemDark ? 'dark' : 'light'); + + document.documentElement.setAttribute('data-theme', initialTheme); + this.updateIcon(initialTheme === 'dark'); + } + + toggleTheme() { + document.body.classList.add('theme-transition'); + const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; + const newTheme = isDark ? 'light' : 'dark'; + + document.documentElement.setAttribute('data-theme', newTheme); + this.updateIcon(!isDark); + localStorage.setItem('theme', newTheme); + + // Lazy load sound only when needed + if (!this.sound && this.soundSrc) { + this.sound = new Audio(this.soundSrc); + } + + if (this.sound) { + this.sound.play().catch(() => {}); + } + + // Use requestAnimationFrame for better performance on transition + requestAnimationFrame(() => { + setTimeout(() => { + document.body.classList.remove('theme-transition'); + }, 300); + }); + } + + updateIcon(isDark) { + if (this.icon) { + this.icon.setAttribute('href', + `${this.iconBase}${isDark ? this.iconDark : this.iconLight}`); + } + } +} + + +// Initialize when content is loaded +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => new ThemeManager()); +} else { + new ThemeManager(); +} diff --git a/static/js/script.js b/static/js/script.js index 70d5970..1a181b6 100644 --- a/static/js/script.js +++ b/static/js/script.js @@ -2,17 +2,17 @@ class ThemeManager { constructor() { this.toggle = document.getElementById('theme-toggle'); if (!this.toggle) return; - + this.icon = document.getElementById('theme-icon'); const { iconBase, iconDark, iconLight, soundSrc } = this.toggle.dataset; this.iconBase = iconBase; this.iconDark = iconDark; this.iconLight = iconLight; - + // Create audio element lazily only when needed this.sound = null; this.soundSrc = soundSrc; - + this.init(); } @@ -31,6 +31,7 @@ class ThemeManager { } toggleTheme() { + document.body.classList.add('theme-transition'); const isDark = document.documentElement.getAttribute('data-theme') === 'dark'; const newTheme = isDark ? 'light' : 'dark'; @@ -57,7 +58,7 @@ class ThemeManager { updateIcon(isDark) { if (this.icon) { - this.icon.setAttribute('href', + this.icon.setAttribute('href', `${this.iconBase}${isDark ? this.iconDark : this.iconLight}`); } }