Skip to content

Commit 8628021

Browse files
committed
added dark mode to all pages
1 parent 4653db6 commit 8628021

File tree

5 files changed

+341
-4
lines changed

5 files changed

+341
-4
lines changed

WFCalculator/script.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,87 @@ document.getElementById("goBackBtn").addEventListener("click", () => {
9595
// keep same behavior as before
9696
window.location.href = "../index.html";
9797
});
98+
99+
// Universal Dark Mode Toggle
100+
(function () {
101+
const STORAGE_KEY = "darkMode", body = document.body;
102+
103+
// Dark mode CSS
104+
const sheet = document.createElement("style");
105+
sheet.id = "universal-dark-mode-sheet";
106+
sheet.textContent = `
107+
.dark-mode {
108+
--dm-bg:#0f0f10;--dm-surface:#1e1e1e;--dm-text:#eaeaea;--dm-muted:#bdbdbd;--dm-accent:#eaeaea;
109+
}
110+
.dark-mode, .dark-mode body {background-color:var(--dm-bg)!important;color:var(--dm-text)!important;}
111+
.dark-mode .dm-btn {background:#2a2a2a!important;color:var(--dm-text)!important;border:1px solid rgba(200,200,200,0.45)!important;border-radius:8px!important;box-shadow:0 0 10px rgba(200,200,200,0.18)!important;}
112+
.dark-mode .dm-title {color:var(--dm-accent)!important;}
113+
.dark-mode .dm-note {color:var(--dm-muted)!important;font-style:italic;}
114+
.dark-mode .dm-panel {background:var(--dm-surface)!important;color:var(--dm-text)!important;border:1px solid rgba(255,255,255,0.03)!important;box-shadow:0 6px 18px rgba(0,0,0,0.35) inset!important;}
115+
.dark-mode * {transition:color 0.25s ease,background-color 0.25s ease,border-color 0.25s ease,box-shadow 0.25s ease!important;}
116+
`;
117+
document.head.appendChild(sheet);
118+
119+
// Toggle button
120+
const toggle = Object.assign(document.createElement("button"), {
121+
id: "dark-mode-toggle",
122+
textContent: "🌙",
123+
onclick() {
124+
const enabled = body.classList.toggle("dark-mode");
125+
toggle.textContent = enabled ? "☀️" : "🌙";
126+
localStorage.setItem(STORAGE_KEY, enabled ? "true" : "false");
127+
enabled ? applyDark() : restoreStyles();
128+
}
129+
});
130+
Object.assign(toggle.style, {
131+
position:"fixed",bottom:"15px",right:"15px",background:"transparent",
132+
border:"2px solid rgba(200,200,200,0.22)",borderRadius:"8px",
133+
fontSize:"1.4rem",cursor:"pointer",zIndex:2147483647,
134+
padding:"6px",lineHeight:"1",display:"flex",
135+
alignItems:"center",justifyContent:"center",
136+
transition:"transform 0.18s ease,border-color 0.18s ease,opacity 0.18s ease"
137+
});
138+
toggle.onmouseenter = () => { toggle.style.transform="scale(1.15)"; toggle.style.borderColor="rgba(200,200,200,0.7)"; };
139+
toggle.onmouseleave = () => { toggle.style.transform="scale(1)"; toggle.style.borderColor="rgba(200,200,200,0.22)"; };
140+
document.body.appendChild(toggle);
141+
142+
// Load preference
143+
const saved = localStorage.getItem(STORAGE_KEY);
144+
if (saved === "true" || (!saved && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
145+
body.classList.add("dark-mode"); toggle.textContent="☀️"; applyDark();
146+
}
147+
148+
const brightness = rgb => (rgb[0]*299 + rgb[1]*587 + rgb[2]*114)/1000;
149+
150+
function applyDark() {
151+
document.querySelectorAll("*").forEach(el => {
152+
if (el.dataset.dmProcessed) return;
153+
el.dataset.dmOriginalStyle = el.getAttribute("style")||"";
154+
const added = [];
155+
try {
156+
const cs = getComputedStyle(el), bg = cs.backgroundColor || "", color = cs.color || "", fs = parseFloat(cs.fontSize||0);
157+
if (el.tagName==="BUTTON" || el.getAttribute("role")==="button") added.push("dm-btn", el.classList.add("dm-btn"));
158+
else {
159+
if (/[\p{Emoji}]/u.test(el.textContent||"") || fs>=18) added.push("dm-title", el.classList.add("dm-title"));
160+
else if (fs<=12 || cs.fontStyle==="italic") added.push("dm-note", el.classList.add("dm-note"));
161+
if (bg && bg!=="rgba(0, 0, 0, 0)" && bg.match(/\d+/)) {
162+
const rgb = bg.match(/\d+/g).map(Number);
163+
if (brightness(rgb)>150) added.push("dm-panel", el.classList.add("dm-panel"));
164+
}
165+
if (el.tagName==="INPUT" && ["button","submit","reset"].includes((el.type||"").toLowerCase())) added.push("dm-btn", el.classList.add("dm-btn"));
166+
}
167+
if (added.length) el.dataset.dmAddedClasses = added.join(" ");
168+
} catch(e){}
169+
el.dataset.dmProcessed = "1";
170+
});
171+
}
172+
173+
function restoreStyles() {
174+
document.querySelectorAll("[data-dm-processed='1']").forEach(el=>{
175+
const orig = el.dataset.dmOriginalStyle||""; orig ? el.setAttribute("style",orig) : el.removeAttribute("style");
176+
(el.dataset.dmAddedClasses||"").split(/\s+/).forEach(c=>c&&el.classList.remove(c));
177+
delete el.dataset.dmProcessed; delete el.dataset.dmOriginalStyle; delete el.dataset.dmAddedClasses;
178+
});
179+
body.classList.remove("dark-mode");
180+
}
181+
})();

loanCalculator/script.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,87 @@ function downloadCsv(schedule) {
210210
document.getElementById("goBackBtn").addEventListener("click", () => {
211211
window.location.href = "../index.html";
212212
});
213+
214+
// Universal Dark Mode Toggle
215+
(function () {
216+
const STORAGE_KEY = "darkMode", body = document.body;
217+
218+
// Dark mode CSS
219+
const sheet = document.createElement("style");
220+
sheet.id = "universal-dark-mode-sheet";
221+
sheet.textContent = `
222+
.dark-mode {
223+
--dm-bg:#0f0f10;--dm-surface:#1e1e1e;--dm-text:#eaeaea;--dm-muted:#bdbdbd;--dm-accent:#eaeaea;
224+
}
225+
.dark-mode, .dark-mode body {background-color:var(--dm-bg)!important;color:var(--dm-text)!important;}
226+
.dark-mode .dm-btn {background:#2a2a2a!important;color:var(--dm-text)!important;border:1px solid rgba(200,200,200,0.45)!important;border-radius:8px!important;box-shadow:0 0 10px rgba(200,200,200,0.18)!important;}
227+
.dark-mode .dm-title {color:var(--dm-accent)!important;}
228+
.dark-mode .dm-note {color:var(--dm-muted)!important;font-style:italic;}
229+
.dark-mode .dm-panel {background:var(--dm-surface)!important;color:var(--dm-text)!important;border:1px solid rgba(255,255,255,0.03)!important;box-shadow:0 6px 18px rgba(0,0,0,0.35) inset!important;}
230+
.dark-mode * {transition:color 0.25s ease,background-color 0.25s ease,border-color 0.25s ease,box-shadow 0.25s ease!important;}
231+
`;
232+
document.head.appendChild(sheet);
233+
234+
// Toggle button
235+
const toggle = Object.assign(document.createElement("button"), {
236+
id: "dark-mode-toggle",
237+
textContent: "🌙",
238+
onclick() {
239+
const enabled = body.classList.toggle("dark-mode");
240+
toggle.textContent = enabled ? "☀️" : "🌙";
241+
localStorage.setItem(STORAGE_KEY, enabled ? "true" : "false");
242+
enabled ? applyDark() : restoreStyles();
243+
}
244+
});
245+
Object.assign(toggle.style, {
246+
position:"fixed",bottom:"15px",right:"15px",background:"transparent",
247+
border:"2px solid rgba(200,200,200,0.22)",borderRadius:"8px",
248+
fontSize:"1.4rem",cursor:"pointer",zIndex:2147483647,
249+
padding:"6px",lineHeight:"1",display:"flex",
250+
alignItems:"center",justifyContent:"center",
251+
transition:"transform 0.18s ease,border-color 0.18s ease,opacity 0.18s ease"
252+
});
253+
toggle.onmouseenter = () => { toggle.style.transform="scale(1.15)"; toggle.style.borderColor="rgba(200,200,200,0.7)"; };
254+
toggle.onmouseleave = () => { toggle.style.transform="scale(1)"; toggle.style.borderColor="rgba(200,200,200,0.22)"; };
255+
document.body.appendChild(toggle);
256+
257+
// Load preference
258+
const saved = localStorage.getItem(STORAGE_KEY);
259+
if (saved === "true" || (!saved && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
260+
body.classList.add("dark-mode"); toggle.textContent="☀️"; applyDark();
261+
}
262+
263+
const brightness = rgb => (rgb[0]*299 + rgb[1]*587 + rgb[2]*114)/1000;
264+
265+
function applyDark() {
266+
document.querySelectorAll("*").forEach(el => {
267+
if (el.dataset.dmProcessed) return;
268+
el.dataset.dmOriginalStyle = el.getAttribute("style")||"";
269+
const added = [];
270+
try {
271+
const cs = getComputedStyle(el), bg = cs.backgroundColor || "", color = cs.color || "", fs = parseFloat(cs.fontSize||0);
272+
if (el.tagName==="BUTTON" || el.getAttribute("role")==="button") added.push("dm-btn", el.classList.add("dm-btn"));
273+
else {
274+
if (/[\p{Emoji}]/u.test(el.textContent||"") || fs>=18) added.push("dm-title", el.classList.add("dm-title"));
275+
else if (fs<=12 || cs.fontStyle==="italic") added.push("dm-note", el.classList.add("dm-note"));
276+
if (bg && bg!=="rgba(0, 0, 0, 0)" && bg.match(/\d+/)) {
277+
const rgb = bg.match(/\d+/g).map(Number);
278+
if (brightness(rgb)>150) added.push("dm-panel", el.classList.add("dm-panel"));
279+
}
280+
if (el.tagName==="INPUT" && ["button","submit","reset"].includes((el.type||"").toLowerCase())) added.push("dm-btn", el.classList.add("dm-btn"));
281+
}
282+
if (added.length) el.dataset.dmAddedClasses = added.join(" ");
283+
} catch(e){}
284+
el.dataset.dmProcessed = "1";
285+
});
286+
}
287+
288+
function restoreStyles() {
289+
document.querySelectorAll("[data-dm-processed='1']").forEach(el=>{
290+
const orig = el.dataset.dmOriginalStyle||""; orig ? el.setAttribute("style",orig) : el.removeAttribute("style");
291+
(el.dataset.dmAddedClasses||"").split(/\s+/).forEach(c=>c&&el.classList.remove(c));
292+
delete el.dataset.dmProcessed; delete el.dataset.dmOriginalStyle; delete el.dataset.dmAddedClasses;
293+
});
294+
body.classList.remove("dark-mode");
295+
}
296+
})();

ptracker/script.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,91 @@ document.getElementById("noClear").onclick = () => {
573573

574574
document.getElementById("goBackBtn").onclick = () => window.location.href = "../index.html";
575575

576+
// Universal Dark Mode Toggle
577+
(function () {
578+
const STORAGE_KEY = "darkMode", body = document.body;
579+
580+
// Dark mode CSS
581+
const sheet = document.createElement("style");
582+
sheet.id = "universal-dark-mode-sheet";
583+
sheet.textContent = `
584+
.dark-mode {
585+
--dm-bg:#0f0f10;--dm-surface:#1e1e1e;--dm-text:#eaeaea;--dm-muted:#bdbdbd;--dm-accent:#eaeaea;
586+
}
587+
.dark-mode, .dark-mode body {background-color:var(--dm-bg)!important;color:var(--dm-text)!important;}
588+
.dark-mode .dm-btn {background:#2a2a2a!important;color:var(--dm-text)!important;border:1px solid rgba(200,200,200,0.45)!important;border-radius:8px!important;box-shadow:0 0 10px rgba(200,200,200,0.18)!important;}
589+
.dark-mode .dm-title {color:var(--dm-accent)!important;}
590+
.dark-mode .dm-note {color:var(--dm-muted)!important;font-style:italic;}
591+
.dark-mode .dm-panel {background:var(--dm-surface)!important;color:var(--dm-text)!important;border:1px solid rgba(255,255,255,0.03)!important;box-shadow:0 6px 18px rgba(0,0,0,0.35) inset!important;}
592+
.dark-mode * {transition:color 0.25s ease,background-color 0.25s ease,border-color 0.25s ease,box-shadow 0.25s ease!important;}
593+
`;
594+
document.head.appendChild(sheet);
595+
596+
// Toggle button
597+
const toggle = Object.assign(document.createElement("button"), {
598+
id: "dark-mode-toggle",
599+
textContent: "🌙",
600+
onclick() {
601+
const enabled = body.classList.toggle("dark-mode");
602+
toggle.textContent = enabled ? "☀️" : "🌙";
603+
localStorage.setItem(STORAGE_KEY, enabled ? "true" : "false");
604+
enabled ? applyDark() : restoreStyles();
605+
}
606+
});
607+
Object.assign(toggle.style, {
608+
position:"fixed",bottom:"15px",right:"15px",background:"transparent",
609+
border:"2px solid rgba(200,200,200,0.22)",borderRadius:"8px",
610+
fontSize:"1.4rem",cursor:"pointer",zIndex:2147483647,
611+
padding:"6px",lineHeight:"1",display:"flex",
612+
alignItems:"center",justifyContent:"center",
613+
transition:"transform 0.18s ease,border-color 0.18s ease,opacity 0.18s ease"
614+
});
615+
toggle.onmouseenter = () => { toggle.style.transform="scale(1.15)"; toggle.style.borderColor="rgba(200,200,200,0.7)"; };
616+
toggle.onmouseleave = () => { toggle.style.transform="scale(1)"; toggle.style.borderColor="rgba(200,200,200,0.22)"; };
617+
document.body.appendChild(toggle);
618+
619+
// Load preference
620+
const saved = localStorage.getItem(STORAGE_KEY);
621+
if (saved === "true" || (!saved && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
622+
body.classList.add("dark-mode"); toggle.textContent="☀️"; applyDark();
623+
}
624+
625+
const brightness = rgb => (rgb[0]*299 + rgb[1]*587 + rgb[2]*114)/1000;
626+
627+
function applyDark() {
628+
document.querySelectorAll("*").forEach(el => {
629+
if (el.dataset.dmProcessed) return;
630+
el.dataset.dmOriginalStyle = el.getAttribute("style")||"";
631+
const added = [];
632+
try {
633+
const cs = getComputedStyle(el), bg = cs.backgroundColor || "", color = cs.color || "", fs = parseFloat(cs.fontSize||0);
634+
if (el.tagName==="BUTTON" || el.getAttribute("role")==="button") added.push("dm-btn", el.classList.add("dm-btn"));
635+
else {
636+
if (/[\p{Emoji}]/u.test(el.textContent||"") || fs>=18) added.push("dm-title", el.classList.add("dm-title"));
637+
else if (fs<=12 || cs.fontStyle==="italic") added.push("dm-note", el.classList.add("dm-note"));
638+
if (bg && bg!=="rgba(0, 0, 0, 0)" && bg.match(/\d+/)) {
639+
const rgb = bg.match(/\d+/g).map(Number);
640+
if (brightness(rgb)>150) added.push("dm-panel", el.classList.add("dm-panel"));
641+
}
642+
if (el.tagName==="INPUT" && ["button","submit","reset"].includes((el.type||"").toLowerCase())) added.push("dm-btn", el.classList.add("dm-btn"));
643+
}
644+
if (added.length) el.dataset.dmAddedClasses = added.join(" ");
645+
} catch(e){}
646+
el.dataset.dmProcessed = "1";
647+
});
648+
renderCalendar();
649+
}
650+
651+
function restoreStyles() {
652+
document.querySelectorAll("[data-dm-processed='1']").forEach(el=>{
653+
const orig = el.dataset.dmOriginalStyle||""; orig ? el.setAttribute("style",orig) : el.removeAttribute("style");
654+
(el.dataset.dmAddedClasses||"").split(/\s+/).forEach(c=>c&&el.classList.remove(c));
655+
delete el.dataset.dmProcessed; delete el.dataset.dmOriginalStyle; delete el.dataset.dmAddedClasses;
656+
});
657+
body.classList.remove("dark-mode");
658+
}
659+
})();
660+
576661
// -------------------- Init --------------------
577662
loadSettings();
578663
loadData();

ptracker/styles.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ h1 {
9494
.day:hover { background: #f5f5f5; }
9595

9696
.today { border: 2px solid #000; }
97-
.period { background: #ffb3ba; }
98-
.fertile { background: #baffc9; }
99-
.ovulation { background: #bae1ff; font-weight: bold; }
100-
.predicted { background: #dab6fc; }
97+
.period { background: #ff9aa4; }
98+
.fertile { background: #00be29; }
99+
.ovulation { background: #00811c; font-weight: bold; }
100+
.predicted { background: #ff00ff; }
101101

102102
.day span {
103103
position: absolute;

script.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,87 @@ document.getElementById("copyBTC").addEventListener("click", () => {
7777
messageSpan.style.color = "red";
7878
});
7979
});
80+
81+
// Universal Dark Mode Toggle
82+
(function () {
83+
const STORAGE_KEY = "darkMode", body = document.body;
84+
85+
// Dark mode CSS
86+
const sheet = document.createElement("style");
87+
sheet.id = "universal-dark-mode-sheet";
88+
sheet.textContent = `
89+
.dark-mode {
90+
--dm-bg:#0f0f10;--dm-surface:#1e1e1e;--dm-text:#eaeaea;--dm-muted:#bdbdbd;--dm-accent:#eaeaea;
91+
}
92+
.dark-mode, .dark-mode body {background-color:var(--dm-bg)!important;color:var(--dm-text)!important;}
93+
.dark-mode .dm-btn {background:#2a2a2a!important;color:var(--dm-text)!important;border:1px solid rgba(200,200,200,0.45)!important;border-radius:8px!important;box-shadow:0 0 10px rgba(200,200,200,0.18)!important;}
94+
.dark-mode .dm-title {color:var(--dm-accent)!important;}
95+
.dark-mode .dm-note {color:var(--dm-muted)!important;font-style:italic;}
96+
.dark-mode .dm-panel {background:var(--dm-surface)!important;color:var(--dm-text)!important;border:1px solid rgba(255,255,255,0.03)!important;box-shadow:0 6px 18px rgba(0,0,0,0.35) inset!important;}
97+
.dark-mode * {transition:color 0.25s ease,background-color 0.25s ease,border-color 0.25s ease,box-shadow 0.25s ease!important;}
98+
`;
99+
document.head.appendChild(sheet);
100+
101+
// Toggle button
102+
const toggle = Object.assign(document.createElement("button"), {
103+
id: "dark-mode-toggle",
104+
textContent: "🌙",
105+
onclick() {
106+
const enabled = body.classList.toggle("dark-mode");
107+
toggle.textContent = enabled ? "☀️" : "🌙";
108+
localStorage.setItem(STORAGE_KEY, enabled ? "true" : "false");
109+
enabled ? applyDark() : restoreStyles();
110+
}
111+
});
112+
Object.assign(toggle.style, {
113+
position:"fixed",bottom:"15px",right:"15px",background:"transparent",
114+
border:"2px solid rgba(200,200,200,0.22)",borderRadius:"8px",
115+
fontSize:"1.4rem",cursor:"pointer",zIndex:2147483647,
116+
padding:"6px",lineHeight:"1",display:"flex",
117+
alignItems:"center",justifyContent:"center",
118+
transition:"transform 0.18s ease,border-color 0.18s ease,opacity 0.18s ease"
119+
});
120+
toggle.onmouseenter = () => { toggle.style.transform="scale(1.15)"; toggle.style.borderColor="rgba(200,200,200,0.7)"; };
121+
toggle.onmouseleave = () => { toggle.style.transform="scale(1)"; toggle.style.borderColor="rgba(200,200,200,0.22)"; };
122+
document.body.appendChild(toggle);
123+
124+
// Load preference
125+
const saved = localStorage.getItem(STORAGE_KEY);
126+
if (saved === "true" || (!saved && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
127+
body.classList.add("dark-mode"); toggle.textContent="☀️"; applyDark();
128+
}
129+
130+
const brightness = rgb => (rgb[0]*299 + rgb[1]*587 + rgb[2]*114)/1000;
131+
132+
function applyDark() {
133+
document.querySelectorAll("*").forEach(el => {
134+
if (el.dataset.dmProcessed) return;
135+
el.dataset.dmOriginalStyle = el.getAttribute("style")||"";
136+
const added = [];
137+
try {
138+
const cs = getComputedStyle(el), bg = cs.backgroundColor || "", color = cs.color || "", fs = parseFloat(cs.fontSize||0);
139+
if (el.tagName==="BUTTON" || el.getAttribute("role")==="button") added.push("dm-btn", el.classList.add("dm-btn"));
140+
else {
141+
if (/[\p{Emoji}]/u.test(el.textContent||"") || fs>=18) added.push("dm-title", el.classList.add("dm-title"));
142+
else if (fs<=12 || cs.fontStyle==="italic") added.push("dm-note", el.classList.add("dm-note"));
143+
if (bg && bg!=="rgba(0, 0, 0, 0)" && bg.match(/\d+/)) {
144+
const rgb = bg.match(/\d+/g).map(Number);
145+
if (brightness(rgb)>150) added.push("dm-panel", el.classList.add("dm-panel"));
146+
}
147+
if (el.tagName==="INPUT" && ["button","submit","reset"].includes((el.type||"").toLowerCase())) added.push("dm-btn", el.classList.add("dm-btn"));
148+
}
149+
if (added.length) el.dataset.dmAddedClasses = added.join(" ");
150+
} catch(e){}
151+
el.dataset.dmProcessed = "1";
152+
});
153+
}
154+
155+
function restoreStyles() {
156+
document.querySelectorAll("[data-dm-processed='1']").forEach(el=>{
157+
const orig = el.dataset.dmOriginalStyle||""; orig ? el.setAttribute("style",orig) : el.removeAttribute("style");
158+
(el.dataset.dmAddedClasses||"").split(/\s+/).forEach(c=>c&&el.classList.remove(c));
159+
delete el.dataset.dmProcessed; delete el.dataset.dmOriginalStyle; delete el.dataset.dmAddedClasses;
160+
});
161+
body.classList.remove("dark-mode");
162+
}
163+
})();

0 commit comments

Comments
 (0)