feat: updates

This commit is contained in:
2025-08-17 22:09:53 +02:00
parent 998e955ec8
commit 8c0dc905d9
18 changed files with 869 additions and 776 deletions

View File

@@ -1,51 +1,43 @@
(function () {
const root = document.documentElement;
const key = "theme";
const stored = localStorage.getItem(key);
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const initial = stored || (prefersDark ? "mocha" : "latte");
root.setAttribute("data-theme", initial);
toggleChroma(initial);
const btn = document.getElementById("theme-toggle");
function updateToggleIcon(theme) {
if (!btn) return;
const isDark = theme === "mocha";
btn.textContent = isDark ? "☀️" : "🌙";
btn.setAttribute("aria-label", isDark ? "Switch to light theme" : "Switch to dark theme");
btn.setAttribute("title", isDark ? "Light theme" : "Dark theme");
// Home: show as many posts as fit the viewport height
(function () {
if (!document.body.classList.contains('is-home')) return;
const list = document.getElementById('home-post-items');
if (!list) return;
const items = Array.from(list.querySelectorAll('.home-post-item'));
const header = document.querySelector('.site-header');
const footer = document.querySelector('.site-footer');
function availableHeight() {
const vh = window.innerHeight;
const headerH = header ? header.getBoundingClientRect().height : 0;
const footerH = footer ? footer.getBoundingClientRect().height : 0;
const mainPadding = 48; // approx padding in main
return Math.max(0, vh - headerH - footerH - mainPadding);
}
function setTheme(next) {
root.setAttribute("data-theme", next);
localStorage.setItem(key, next);
toggleChroma(next);
updateToggleIcon(next);
}
function toggleChroma(theme) {
const latte = document.getElementById("chroma-latte");
const mocha = document.getElementById("chroma-mocha");
if (latte && mocha) {
if (theme === "mocha") {
mocha.removeAttribute("disabled");
latte.setAttribute("disabled", "disabled");
} else {
latte.removeAttribute("disabled");
mocha.setAttribute("disabled", "disabled");
function relayout() {
items.forEach(el => el.classList.add('hidden'));
let shown = 0;
let used = 0;
const gap = (() => {
const ul = list;
const styles = window.getComputedStyle(ul);
const rowGap = parseFloat(styles.rowGap || styles.gap || '0');
return isNaN(rowGap) ? 0 : rowGap;
})();
for (const el of items) {
el.classList.remove('hidden');
const h = el.getBoundingClientRect().height;
if (used + h + (shown > 0 ? gap : 0) > availableHeight()) {
el.classList.add('hidden');
break;
}
used += h + (shown > 0 ? gap : 0);
shown++;
}
}
updateToggleIcon(initial);
btn && btn.addEventListener("click", () => {
setTheme(root.getAttribute("data-theme") === "latte" ? "mocha" : "latte");
});
// Reading progress
const bar = document.getElementById("progress");
function onScroll() {
const t = document.documentElement;
const scrolled = (t.scrollTop / (t.scrollHeight - t.clientHeight)) * 100;
bar && (bar.style.width = scrolled + "%");
}
document.addEventListener("scroll", onScroll, { passive: true });
onScroll();
const ro = new ResizeObserver(relayout);
ro.observe(document.documentElement);
header && ro.observe(header);
footer && ro.observe(footer);
window.addEventListener('load', relayout);
window.addEventListener('orientationchange', relayout);
})();