summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-08-22 00:18:56 +0900
committertanaka takashi <isazaka@gmail.com>2026-08-22 00:19:26 +0900
commit9f2fb3bda733c32995c008bd0f40365e43c348da (patch)
tree663a6b48ec83b2b6ba2c998dcfed89e0bb29f172 /static
parent31b19ee74469c23633bbea4e021d91ddd8c34e3a (diff)
feat: Zolaで「たかしの記録」を構築
Specifications.mdとDesign.mdを実装の基準として、個人アーカイブサイトをZola 0.23.3向けに構築する。 - Home、Notes、Software、About、Tagsの情報設計と専用URLを追加 - Notesの年別アーカイブ、タグ分類、目次、脚注、参考文献、更新日表示を実装 - Softwareの一覧・詳細、cgit/GitHub情報、Notesとの明示的な相互参照を実装 - Tera 2 componentによる再帰TOCと共通partialsを追加 - Minimal Editorial ArchiveのSCSS、レスポンシブ表示、アクセシビリティ対応を追加 - OS設定とlocalStorageに対応するLight/Darkテーマ切替を外部JavaScriptで実装 - Atom/RSS、sitemap、robots.txt、404、favicon、syntax highlightingを設定 - メールアドレスをzola.tomlへ一元化し、AboutとFooterから参照 - 表示名・内部ディレクトリ・変数・URLをSoftware/softwareへ統一 - public/をGit管理対象外とし、外部CDNやNode.js依存を導入しない - zola checkおよびzola buildの成功を確認
Diffstat (limited to 'static')
-rw-r--r--static/favicon.svg6
-rw-r--r--static/js/theme.js75
2 files changed, 81 insertions, 0 deletions
diff --git a/static/favicon.svg b/static/favicon.svg
new file mode 100644
index 0000000..39493b6
--- /dev/null
+++ b/static/favicon.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title">
+ <title id="title">たかしの記録</title>
+ <rect width="64" height="64" rx="6" fill="#202124"/>
+ <path d="M15 15h34v34H15z" fill="none" stroke="#86b6d8" stroke-width="3"/>
+ <path d="M24 23h16M24 31h16M24 39h11" stroke="#f6f5f1" stroke-width="3"/>
+</svg>
diff --git a/static/js/theme.js b/static/js/theme.js
new file mode 100644
index 0000000..3d2b25c
--- /dev/null
+++ b/static/js/theme.js
@@ -0,0 +1,75 @@
+(function () {
+ "use strict";
+
+ var root = document.documentElement;
+ root.classList.add("theme-ready");
+ var toggle = document.querySelector("[data-theme-toggle]");
+ var syntaxLight = document.getElementById("syntax-light");
+ var syntaxDark = document.getElementById("syntax-dark");
+ var media = window.matchMedia("(prefers-color-scheme: dark)");
+ var storedTheme = null;
+
+ try {
+ storedTheme = window.localStorage.getItem("theme");
+ } catch (error) {
+ storedTheme = null;
+ }
+
+ function activeTheme() {
+ if (root.dataset.theme === "light" || root.dataset.theme === "dark") {
+ return root.dataset.theme;
+ }
+ return media.matches ? "dark" : "light";
+ }
+
+ function syncSyntax(theme) {
+ if (!syntaxLight || !syntaxDark) {
+ return;
+ }
+ syntaxLight.media = theme === "light" ? "all" : "not all";
+ syntaxDark.media = theme === "dark" ? "all" : "not all";
+ }
+
+ function updateToggle() {
+ if (!toggle) {
+ return;
+ }
+ var dark = activeTheme() === "dark";
+ toggle.setAttribute("aria-pressed", String(dark));
+ toggle.setAttribute("aria-label", dark ? "ライトテーマに切り替える" : "ダークテーマに切り替える");
+ toggle.textContent = dark ? "Light" : "Dark";
+ }
+
+ function applyTheme(theme, persist) {
+ root.dataset.theme = theme;
+ syncSyntax(theme);
+ updateToggle();
+ if (persist) {
+ try {
+ window.localStorage.setItem("theme", theme);
+ } catch (error) {
+ // Storageが利用できなくても、現在のpageではthemeを維持する。
+ }
+ }
+ }
+
+ if (storedTheme === "light" || storedTheme === "dark") {
+ applyTheme(storedTheme, false);
+ } else {
+ syncSyntax(activeTheme());
+ updateToggle();
+ }
+
+ if (toggle) {
+ toggle.addEventListener("click", function () {
+ applyTheme(activeTheme() === "dark" ? "light" : "dark", true);
+ });
+ }
+
+ media.addEventListener("change", function () {
+ if (!root.dataset.theme) {
+ syncSyntax(activeTheme());
+ updateToggle();
+ }
+ });
+})();