summaryrefslogtreecommitdiff
path: root/doc/Design.md
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 /doc/Design.md
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 'doc/Design.md')
-rw-r--r--doc/Design.md1851
1 files changed, 1851 insertions, 0 deletions
diff --git a/doc/Design.md b/doc/Design.md
new file mode 100644
index 0000000..bddd04f
--- /dev/null
+++ b/doc/Design.md
@@ -0,0 +1,1851 @@
+# Design.md
+
+# たかしの記録 — Zola 基本・詳細設計書
+
+## 1. 文書目的
+
+本書は `Specifications.md` の要求を、Zolaによる静的Webサイトとして矛盾なく実装するための基本設計・詳細設計を定義する。
+
+設計上の基本原則は次のとおり。
+
+1. Zola公式のSection / Page / Taxonomy / Tera modelに従う
+2. Zola標準機能を優先する
+3. 外部dependencyを増やさない
+4. Build artifact `public/` のみで本番サイトを成立させる
+5. Client PCでbuildし、VPSでbuildしない
+6. 本番runtimeはCaddyのみ
+7. コンテンツ構造とデザインを不要に複雑化しない
+
+---
+
+## 2. 参照仕様とZola準拠方針
+
+本設計は `Specifications.md` を上位仕様とする。
+
+実装時は使用するZolaバージョンの公式ドキュメントを確認すること。
+設定キー・front matter・Tera関数を推測して追加してはならない。
+
+主に以下のZola概念を使用する。
+
+- `zola.toml`
+- Section (`_index.md`)
+- Page (`*.md`)
+- Taxonomy
+- Tera templates
+- Sass/SCSS compilation
+- Static assets
+- Colocated assets
+- Built-in feeds
+- Built-in sitemap
+- Built-in robots.txt
+- `page.toc`
+- `get_page`
+- `get_section`
+- `get_url`
+- `get_taxonomy_url`
+- Internal link `@/`
+
+Zolaはディレクトリ構造からSection/Pageを構成するため、独自CMS層やJSON indexを追加しない。
+
+---
+
+## 3. システム構成
+
+```text
+Client PC
+│
+├── Zola
+├── Git repository
+│ ├── zola.toml
+│ ├── content/
+│ ├── templates/
+│ ├── sass/
+│ └── static/
+│
+├── zola check
+└── zola build
+ │
+ ▼
+ public/
+ │
+ │ archive + SSH
+ ▼
+VPS
+└── /srv/www/takashi-2521.com/
+ ├── releases/<release-id>/
+ └── current -> releases/<release-id>/
+ │
+ ▼
+ Caddy
+```
+
+ZolaはVPSへインストールしない。
+
+---
+
+## 4. Zolaサイト構造
+
+```text
+website/
+├── zola.toml
+├── content/
+│ ├── _index.md
+│ ├── about.md
+│ ├── notes/
+│ │ ├── _index.md
+│ │ ├── example-note.md
+│ │ └── ...
+│ └── software/
+│ ├── _index.md
+│ ├── example-software.md
+│ └── ...
+├── templates/
+│ ├── base.html
+│ ├── index.html
+│ ├── page.html
+│ ├── notes/
+│ │ ├── section.html
+│ │ └── page.html
+│ ├── software/
+│ │ ├── section.html
+│ │ └── page.html
+│ ├── tags/
+│ │ ├── list.html
+│ │ └── single.html
+│ ├── partials/
+│ │ ├── header.html
+│ │ ├── footer.html
+│ │ ├── note-list-item.html
+│ │ ├── software-list-item.html
+│ │ ├── toc.html
+│ │ ├── related-notes.html
+│ │ └── related-software.html
+│ └── 404.html
+├── sass/
+│ ├── main.scss
+│ ├── _tokens.scss
+│ ├── _reset.scss
+│ ├── _base.scss
+│ ├── _typography.scss
+│ ├── _layout.scss
+│ ├── _header.scss
+│ ├── _footer.scss
+│ ├── _archive.scss
+│ ├── _article.scss
+│ ├── _software.scss
+│ ├── _taxonomy.scss
+│ ├── _code.scss
+│ ├── _theme.scss
+│ └── _utilities.scss
+├── static/
+│ ├── favicon.svg
+│ └── js/
+│ └── theme.js
+├── themes/
+└── public/ # generated; Git ignored
+```
+
+### 4.1 Themes
+
+`themes/` はZola標準ディレクトリとして存在してよいが、空のままとする。
+外部themeを使用しない。
+
+### 4.2 public
+
+`public/` は生成物でありGit管理対象外。
+
+---
+
+## 5. `zola.toml` 基本設計
+
+初期値の基準を以下とする。
+
+```toml
+base_url = "https://www.takashi-2521.com"
+title = "たかしの記録"
+description = "日々考えたこととか思ったことを記録します"
+default_language = "ja"
+
+output_dir = "public"
+compile_sass = true
+minify_html = false
+
+generate_feeds = true
+feed_filenames = ["atom.xml", "rss.xml"]
+
+generate_sitemap = true
+generate_robots_txt = true
+
+build_search_index = false
+
+taxonomies = [
+ { name = "tags", feed = false }
+]
+
+[markdown]
+render_emoji = false
+external_links_class = "external-link"
+external_links_target_blank = false
+external_links_no_follow = false
+external_links_no_referrer = false
+external_links_external = true
+smart_punctuation = false
+lazy_async_image = true
+bottom_footnotes = true
+insert_anchor_links = "heading"
+
+[markdown.highlighting]
+error_on_missing_language = true
+style = "class"
+light_theme = "github-light"
+dark_theme = "github-dark"
+
+[link_checker]
+internal_level = "error"
+external_level = "warn"
+
+[slugify]
+paths = "on"
+taxonomies = "on"
+anchors = "on"
+paths_keep_dates = false
+
+[extra]
+home_notes_limit = 5
+home_software_limit = 4
+```
+
+### 5.1 設定上の注意
+
+- `base_url` は本番URLと一致させる。
+- Searchは初期無効。
+- Taxonomyは`tags`のみ。
+- FeedはAtomとRSS。
+- Syntax highlightはclass方式とし、inline styleへの依存を避ける。
+- `external_links_class` を利用し外部リンク記号をCSSで表現する。
+- `minify_html` は開発中false。最終的にtrueへ変更する場合は生成結果を確認してから行う。
+- Highlight themeの具体設定は使用Zola版の公式仕様に合わせる。
+- 利用中Zola版で設定名・構造が異なる場合は、公式ドキュメントを優先してこの設計を等価に実現する。
+
+---
+
+## 6. Content model
+
+### 6.1 Root Section
+
+`content/_index.md`
+
+```toml
++++
+title = "たかしの記録"
+description = "日々考えたこととか思ったことを記録します"
++++
+```
+
+Home自体はZolaのroot sectionとして扱い、`templates/index.html` で描画する。
+
+### 6.2 About Page
+
+`content/about.md`
+
+```toml
++++
+title = "About"
+template = "page.html"
++++
+```
+
+本文に以下をMarkdownで記述する。
+
+- 名前
+- 一言プロフィール
+- サイトの目的
+- 関心分野
+- 連絡先
+
+構造化metadataを必要以上に増やさない。
+
+### 6.3 Notes Section
+
+`content/notes/_index.md`
+
+```toml
++++
+title = "Notes"
+sort_by = "date"
+template = "notes/section.html"
+page_template = "notes/page.html"
++++
+```
+
+#### 6.3.1 Notesのsort
+
+Sectionはdate順にする。
+テンプレートでは新しい順で表示されることを検証する。
+
+#### 6.3.2 Notes Page front matter
+
+```toml
++++
+title = "記事タイトル"
+description = "記事の短い説明"
+date = 2026-08-21
+updated = 2026-08-22
+
+[taxonomies]
+tags = ["情報工学", "AI"]
+
+[extra]
+related_software = [
+ "software/example-software.md"
+]
++++
+
+本文...
+```
+
+#### 6.3.3 Notes必須/任意項目
+
+| Field | 必須 | 用途 |
+|---|---:|---|
+| `title` | Yes | タイトル |
+| `date` | Yes | 公開日 |
+| `description` | No | 一覧・meta description |
+| `updated` | No | 更新日 |
+| `taxonomies.tags` | No | 一覧分類 |
+| `extra.related_software` | No | 明示的な関連Software |
+| Body | Yes | 本文 |
+
+#### 6.3.4 Slug
+
+Markdown filenameを英語ASCII slugとする。
+
+例:
+
+```text
+content/notes/llm-compute-and-energy.md
+```
+
+表示タイトルは日本語でよい。
+
+### 6.4 Software Section
+
+`content/software/_index.md`
+
+```toml
++++
+title = "Software"
+sort_by = "date"
+template = "software/section.html"
+page_template = "software/page.html"
++++
+```
+
+Software一覧の順序は初期状態ではdate順とする。
+公開日を表示する必要はないが、並び順制御に利用する。
+
+将来、並びを明示したくなった場合は`weight`へ変更可能。
+
+#### 6.4.1 Software Page front matter
+
+```toml
++++
+title = "example-software"
+description = "短い概要"
+date = 2026-08-21
+include_in_feeds = false
+
+[extra]
+language = ["Rust", "HTML"]
+license = "MIT"
+source = "https://git.takashi-2521.com/example-software/"
+github_mirror = "https://github.com/example/example-software"
+related_notes = [
+ "notes/example-note.md"
+]
++++
+
+## 概要
+
+...
+
+## 作った背景
+
+...
+
+## 開発の過程
+
+...
+```
+
+#### 6.4.2 Software項目
+
+| Field | 必須 | 用途 |
+|---|---:|---|
+| `title` | Yes | PJ名 |
+| `description` | No | 短い概要 |
+| `date` | Yes | 並び順 |
+| `include_in_feeds` | Yes (`false`) | Notes中心のsite feedからSoftwareを除外 |
+| `extra.language` | No | 使用言語 |
+| `extra.license` | No | ライセンス |
+| `extra.source` | Yes | cgit正本 |
+| `extra.github_mirror` | No | GitHub mirror |
+| `extra.related_notes` | No | 関連Note |
+| Body | Yes | 背景・過程・詳細 |
+
+#### 6.4.3 Software image
+
+画像をSoftwareに紐付ける場合、Zolaのcolocated assetを優先する。
+
+例:
+
+```text
+content/software/example-software/
+├── index.md
+└── screenshot.webp
+```
+
+この場合、Page URLは `/software/example-software/` とし、画像を同じPage Bundle内に置く。
+
+画像が不要なSoftwareは単一Markdownでよい。
+
+---
+
+## 7. Related content設計
+
+### 7.1 基本方針
+
+関連付けはタグから自動推測せず、front matterで明示する。
+
+理由:
+
+- 意図しない関連付けを防止
+- 記事数が少ないため手動管理コストが低い
+- Zola `get_page` で確実に参照できる
+
+### 7.2 Path形式
+
+`extra.related_software` / `extra.related_notes` には **contentディレクトリからのMarkdown path** を保存する。
+
+例:
+
+```toml
+related_software = ["software/ollama-web.md"]
+related_notes = ["notes/ollama-tool-calling.md"]
+```
+
+### 7.3 Tera resolution
+
+例:
+
+```tera
+{% for path in page.extra.related_notes %}
+ {% set related = get_page(path=path) %}
+ <a href="{{ related.permalink }}">{{ related.title }}</a>
+{% endfor %}
+```
+
+Missing referenceはbuild/checkで検出できるよう、原則 `allow_missing=true` を使用しない。
+
+---
+
+## 8. Template設計
+
+### 8.1 `base.html`
+
+責務:
+
+- HTML document skeleton
+- `<html lang="ja">`
+- `<head>`
+- charset / viewport
+- title
+- description
+- canonical
+- RSS/Atom autodiscovery
+- CSS
+- Zola生成syntax-highlight CSS (`giallo-light.css` / `giallo-dark.css`)
+- theme JS
+- Header
+- Main block
+- Footer
+
+概念構造:
+
+```tera
+<!doctype html>
+<html lang="ja">
+<head>
+ ...
+ <link rel="stylesheet" href="{{ get_url(path='main.css') }}">
+ <link id="syntax-light" rel="stylesheet" href="{{ get_url(path='giallo-light.css') }}" media="(prefers-color-scheme: light)">
+ <link id="syntax-dark" rel="stylesheet" href="{{ get_url(path='giallo-dark.css') }}" media="(prefers-color-scheme: dark)">
+ <script src="{{ get_url(path='js/theme.js') }}" defer></script>
+</head>
+<body>
+ {% include "partials/header.html" %}
+ <main id="main-content">
+ {% block content %}{% endblock content %}
+ </main>
+ {% include "partials/footer.html" %}
+</body>
+</html>
+```
+
+#### 8.1.1 Page title
+
+原則:
+
+- Home: `たかしの記録`
+- Other: `<Page title> | たかしの記録`
+
+Tera blockまたは共通変数で実現する。
+
+#### 8.1.2 meta description
+
+優先順位:
+
+1. `page.description` / `section.description`
+2. `config.description`
+
+### 8.2 Header
+
+`partials/header.html`
+
+Desktop:
+
+```text
+たかしの記録 Home Notes Software About [Theme]
+```
+
+Mobileでは自然にwrapさせ、初期実装ではHamburger menuを導入しない。
+
+サイト名自体はHomeへのリンク。
+
+Navigationには`aria-label="メインナビゲーション"`を設定する。
+
+### 8.3 Footer
+
+`partials/footer.html`
+
+表示:
+
+- `© <year> Takashi`
+- RSS
+- Mail
+
+Mail addressは設定値に直接埋め込むか、`config.extra`へ置く。
+公開時のspam対策を別途必要と判断した場合のみ変更する。
+
+### 8.4 Home Template
+
+`templates/index.html`
+
+処理:
+
+1. root `section`
+2. `get_section(path="notes/_index.md")`
+3. Notesから上位5件取得
+4. `get_section(path="software/_index.md")`
+5. Softwareから上位4件取得
+6. Aboutへのリンク
+
+概念:
+
+```tera
+{% set notes = get_section(path="notes/_index.md") %}
+{% set software = get_section(path="software/_index.md") %}
+```
+
+件数は`config.extra.home_notes_limit` / `home_software_limit`で管理する。
+
+Homeでタグは必須表示としない。
+
+### 8.5 Notes一覧 Template
+
+`templates/notes/section.html`
+
+#### 8.5.1 年別グルーピング
+
+Zola公式Archive patternに従い、`section.pages | group_by(attribute="year")` を利用する。
+
+表示:
+
+```text
+Notes
+
+2026
+ 08-21 タイトル
+ タグ1 / タグ2
+
+2025
+ ...
+```
+
+ZolaのSection `sort_by = "date"` を前提とする。
+
+#### 8.5.2 Note list item
+
+`partials/note-list-item.html`
+
+- `<article>` または適切なlist item
+- `<time datetime="">`
+- title link
+- tags
+- optional description
+
+タグURLは `get_taxonomy_url(kind="tags", term=...)` を利用する。
+
+### 8.6 Note detail Template
+
+`templates/notes/page.html`
+
+構造:
+
+```text
+article
+├── header
+│ ├── h1
+│ ├── published
+│ └── updated (optional)
+├── TOC
+├── body
+├── related software (optional)
+└── article footer
+```
+
+#### 8.6.1 Tags
+
+仕様に従い、本文詳細ではタグ一覧を主要表示しない。
+
+#### 8.6.2 TOC
+
+`page.toc` を使用する。
+
+- `page.toc` が空なら非表示
+- Sidebar化しない
+- 記事headerと本文の間に置く
+- H2/H3等の階層を維持
+- Recursive Tera partial/componentで描画可能
+
+#### 8.6.3 TOC accessibility
+
+- `<nav aria-label="目次">`
+- 見出し「目次」
+- ordered/unordered list
+- Anchorは`header.permalink`
+
+#### 8.6.4 Date
+
+公開:
+
+```html
+<time datetime="2026-08-21">2026-08-21</time>
+```
+
+更新日がある場合だけ表示。
+
+#### 8.6.5 Footnotes
+
+Zola Markdown rendererが生成するfootnote markupへSCSSを適用する。
+
+独自脚注システムを作らない。
+
+#### 8.6.6 References
+
+Markdown本文の通常Headingとして「参考文献」を記述する。
+
+例:
+
+```markdown
+## 参考文献
+
+1. ...
+2. ...
+```
+
+専用front matter schemaは導入しない。
+
+### 8.7 Software一覧 Template
+
+`templates/software/section.html`
+
+表示の中心はSoftware名。
+
+例:
+
+```text
+Software
+
+ollama-web
+短い説明(存在する場合)
+
+winagent-sandbox-mcp
+...
+```
+
+一覧には以下を表示しない。
+
+- screenshot
+- license
+- source URL全文
+- language一覧
+- 大量のbadge
+
+### 8.8 Software detail Template
+
+`templates/software/page.html`
+
+構造:
+
+```text
+article
+├── h1 Software名
+├── description
+├── metadata
+│ ├── 使用言語
+│ ├── ライセンス
+│ ├── Source
+│ └── GitHub mirror (optional)
+├── Body
+│ ├── 概要
+│ ├── 背景
+│ └── 過程等
+├── screenshot/assets (optional)
+└── Related Notes (optional)
+```
+
+SourceはGitHubより先に表示。
+
+外部リンクclassによって`↗`表示を適用する。
+
+### 8.9 About
+
+標準`page.html`で十分な場合は専用templateを作らない。
+
+`page.html` は汎用Editorial pageとして以下を描画。
+
+- h1
+- page.content
+
+About固有レイアウトが必要になった時だけ`about.html`を追加する。
+
+### 8.10 Taxonomy templates
+
+`tags/list.html`
+
+- 全タグの一覧
+- term name
+- article count
+
+`tags/single.html`
+
+- タグ名
+- 該当Pages一覧
+- Note/Softwareの混在が読みづらい場合は種類ごとに分離可能
+
+初期仕様ではタグは主にNotes用だが、Zola taxonomy自体はPages全般で利用可能。
+
+### 8.11 404
+
+`templates/404.html`
+
+- base designと同じHeader/Footer
+- 「ページが見つかりません」
+- Homeへのリンク
+- Notesへのリンク
+- Softwareへのリンク
+
+外部依存なし。
+
+---
+
+## 9. Internal Link設計
+
+Markdown本文内の内部リンクはZolaの `@/` syntaxを使用する。
+
+例:
+
+```markdown
+[関連する記事](@/notes/example-note.md)
+```
+
+Template内は`get_url`, `get_page`, `get_section`を使用する。
+
+Content pathを手書きURLへ変換しない。
+
+Broken internal linkは`zola check`でerror扱い。
+
+---
+
+## 10. Tags / Taxonomy設計
+
+`zola.toml`:
+
+```toml
+taxonomies = [
+ { name = "tags", feed = false }
+]
+```
+
+Page:
+
+```toml
+[taxonomies]
+tags = ["情報工学", "地球環境"]
+```
+
+### 10.1 Tag URL
+
+Zola slugificationに任せる。
+
+表示termは日本語を許容する。
+Taxonomy URL生成はZola APIを使用し、自前slug生成をしない。
+
+### 10.2 Category
+
+初期実装ではcategory taxonomyを作らない。
+
+---
+
+## 11. Feed設計
+
+Site-level feed:
+
+- `/atom.xml`
+- `/rss.xml`
+
+Site-level feedを使用する。Software Pageには `include_in_feeds = false` を設定し、日付を持つSoftwareがsite feedへ混入しないようにする。これにより初期feedは実質的にNotesを購読対象とする。
+
+Notes section固有feedは初期実装では生成しない。必要になった場合のみ `content/notes/_index.md` の `generate_feeds = true` を追加する。
+
+`base.html`にautodiscoveryを設定。
+
+概念:
+
+```tera
+<link rel="alternate"
+ type="application/atom+xml"
+ title="Atom"
+ href="{{ get_url(path='atom.xml', trailing_slash=false) }}">
+<link rel="alternate"
+ type="application/rss+xml"
+ title="RSS"
+ href="{{ get_url(path='rss.xml', trailing_slash=false) }}">
+```
+
+FooterのRSSリンクは`rss.xml`を優先してよい。
+Atomもアクセス可能とする。
+
+---
+
+## 12. Sitemap / robots
+
+Zola built-in生成を利用する。
+
+```toml
+generate_sitemap = true
+generate_robots_txt = true
+```
+
+独自generatorを作らない。
+
+robots policyを変更する必要が生じた場合のみbuilt-in template overrideまたはstatic fileを検討する。
+
+---
+
+## 13. Sass設計
+
+### 13.1 基本原則
+
+- 自前SCSS
+- CSS frameworkなし
+- Tailwindなし
+- external reset packageなし
+- BEM等の厳格な命名体系を強制しない
+- component responsibilityが分かる程度のclass設計
+
+### 13.2 Design tokens
+
+`_tokens.scss`
+
+初期候補:
+
+```scss
+:root {
+ --color-bg: #f6f5f1;
+ --color-surface: #fbfaf7;
+ --color-text: #202124;
+ --color-muted: #6d7177;
+ --color-border: #d6d8da;
+ --color-link: #315f82;
+ --color-link-hover: #244a67;
+
+ --font-sans:
+ system-ui, -apple-system, BlinkMacSystemFont,
+ "Segoe UI", "Noto Sans JP", sans-serif;
+
+ --font-mono:
+ ui-monospace, "Cascadia Code", "SFMono-Regular",
+ Consolas, "Liberation Mono", monospace;
+
+ --content-max: 72ch;
+ --site-max: 72rem;
+}
+```
+
+具体色は実装時に視認性を確認して調整可能。
+Accentは青系から逸脱しない。
+
+### 13.3 Dark tokens
+
+```scss
+@media (prefers-color-scheme: dark) {
+ :root:not([data-theme="light"]) {
+ --color-bg: #17191b;
+ --color-surface: #1d2022;
+ --color-text: #e9e9e6;
+ --color-muted: #a0a3a6;
+ --color-border: #363a3e;
+ --color-link: #86b6d8;
+ --color-link-hover: #add3ed;
+ }
+}
+```
+
+User override用`data-theme`も定義する。
+
+---
+
+## 14. Theme switch設計
+
+### 14.1 初期状態
+
+CSS `prefers-color-scheme` を優先。
+
+### 14.2 手動切替
+
+`static/js/theme.js` のみを使用。
+
+責務:
+
+- 現在theme取得
+- light/dark切替
+- `document.documentElement.dataset.theme`
+- `localStorage`保存
+- toggle buttonの`aria-pressed`/label更新
+- `#syntax-light` / `#syntax-dark` の `media` を切り替え、本文themeとsyntax highlighting themeを同期
+
+明示的にLightを選んだ場合:
+
+- `syntax-light.media = "all"`
+- `syntax-dark.media = "not all"`
+
+明示的にDarkを選んだ場合:
+
+- `syntax-light.media = "not all"`
+- `syntax-dark.media = "all"`
+
+保存themeがない場合はHTML/CSSとも `prefers-color-scheme` に従う。
+
+### 14.3 CSP
+
+JSは外部fileのみ。
+Inline scriptは使用しない。
+
+Theme JSが失敗してもOS themeにより読みやすい状態を保つ。
+
+### 14.4 No-JS
+
+No-JSではmanual toggleだけ利用不可。
+本文・navigation・Light/Dark OS preferenceは利用可能。
+
+---
+
+## 15. External link表示
+
+Zola Markdown設定:
+
+```toml
+external_links_class = "external-link"
+```
+
+SCSS:
+
+```scss
+.external-link::after {
+ content: " ↗";
+ font-size: 0.8em;
+ text-decoration: none;
+}
+```
+
+装飾SVG dependencyを使用しない。
+
+Navigationや内部リンクには付けない。
+
+---
+
+## 16. Layout設計
+
+### 16.1 Site container
+
+```scss
+.site-container {
+ width: min(100% - 2rem, var(--site-max));
+ margin-inline: auto;
+}
+```
+
+### 16.2 Article
+
+初期値:
+
+```scss
+.prose {
+ max-width: var(--content-max); // 72ch
+ margin-inline: auto;
+}
+```
+
+仕様で本文幅は未確定だったため、初期実装は **72ch** とする。
+実際の日本語可読性を確認し、65〜75ch相当の範囲で調整可能。
+
+### 16.3 Mobile
+
+- Side padding最低1rem
+- Header navigation wrap可
+- Horizontal body scroll禁止
+- pre/code/tableは必要に応じ内部scroll
+- 画像max-width:100%
+
+---
+
+## 17. Typography設計
+
+### 17.1 Body
+
+Sans-serif system stack。
+
+```scss
+body {
+ font-family: var(--font-sans);
+ line-height: 1.75;
+}
+```
+
+### 17.2 Heading
+
+Sans-serif。
+過度な巨大見出しにしない。
+Home H1だけやや大きくする。
+
+### 17.3 Metadata
+
+Monospaceまたは小さめSans。
+日付などにMonoを利用。
+
+### 17.4 Code
+
+`var(--font-mono)`。
+
+---
+
+## 18. Editorial visual rules
+
+- Border radius最小限
+- Card shadow原則なし
+- Gradientなし
+- Neon/glowなし
+- Glassmorphismなし
+- 1px ruleを主要区切りに使用
+- Section間余白でhierarchyを作る
+- 大きなHero画像なし
+- Iconsは最小限
+- Badge乱用なし
+
+---
+
+## 19. Code block設計
+
+Zola syntax highlightingを利用。
+
+- Client-side highlighting libraryなし
+- Prism/highlight.jsなし
+- class-based highlight
+- `github-light` / `github-dark` のdual theme
+- Zola生成 `giallo-light.css` / `giallo-dark.css` を読み込む
+- theme toggle時にstylesheet mediaも同期する
+- code blockは横scroll可
+- light/darkの視認性を確認
+
+Highlight CSSの生成/適用方法は使用Zola versionの公式仕様に従う。
+
+---
+
+## 20. Image設計
+
+### 20.1 Notes
+
+Markdown imageを使用。
+
+`lazy_async_image = true` により遅延loadを利用する。
+
+Altはplain textで記述。
+
+### 20.2 Software
+
+Colocated assetを推奨。
+
+Screenshotは本文内で説明と一緒に表示。
+
+### 20.3 Formats
+
+原則:
+
+- SVG: icon/diagram
+- WebP/AVIF/JPEG/PNG: screenshot用途に応じて選択
+
+画像最適化toolchainは初期実装に追加しない。
+
+---
+
+## 21. Accessibility設計
+
+### 21.1 Landmarks
+
+- `<header>`
+- `<nav>`
+- `<main>`
+- `<article>`
+- `<footer>`
+
+### 21.2 Skip link
+
+Header先頭にskip linkを設けることを推奨。
+
+```html
+<a class="skip-link" href="#main-content">本文へ移動</a>
+```
+
+### 21.3 Focus
+
+`:focus-visible`を明確に表示。
+
+### 21.4 Color
+
+リンクは青色だけでなく下線でも識別可能にする。
+
+### 21.5 Theme toggle
+
+Button要素を使用。
+Keyboard操作可能。
+
+### 21.6 TOC
+
+`nav aria-label="目次"`。
+
+---
+
+## 22. SEO / metadata設計
+
+最低限:
+
+- `<title>`
+- `<meta name="description">`
+- canonical URL
+- `lang="ja"`
+- RSS/Atom autodiscovery
+- sitemap
+- robots
+
+Open Graph / Twitter Cardは初期必須ではない。
+外部依存なしで容易に実装可能な場合は後で追加可。
+
+---
+
+## 23. SNS共有
+
+初期実装対象外。
+
+理由:
+
+- 仕様が条件付き
+- Editorial designを優先
+- Mastodon等は単一固定share endpointにしづらい
+- 外部service/仕様変化への依存を避ける
+
+将来追加する場合、以下の順で検討。
+
+1. Web Share API
+2. Copy link
+3. 外部dependencyなしのSNS share URL
+
+---
+
+## 24. Comments
+
+初期実装対象外。
+
+Template上に空のcomment UIや未使用placeholderを作らない。
+
+将来commentsを採用する場合は別設計として以下を再評価。
+
+- Data persistence
+- Authentication/abuse
+- Spam
+- Moderation
+- Privacy
+- CSP
+- Backup
+- VPS resource
+- External service dependency
+
+---
+
+## 25. Search
+
+初期:
+
+```toml
+build_search_index = false
+```
+
+Search UIを作らない。
+
+将来追加時はZola built-in search indexを第一候補とし、日本語indexing対応について使用Zola binaryの機能を確認する。
+
+---
+
+## 26. Git設計
+
+Git管理対象:
+
+- `zola.toml`
+- `content/`
+- `templates/`
+- `sass/`
+- `static/`
+- documentation
+- deploy script(別Phaseで追加)
+
+`.gitignore`:
+
+```gitignore
+/public/
+```
+
+Editor/OS生成物は必要に応じ追加。
+
+`themes/` が空でGitに残らない場合、`.gitkeep`は必須ではない。
+
+---
+
+## 27. Build設計
+
+### 27.1 Development
+
+```bash
+zola serve
+```
+
+### 27.2 Validation
+
+```bash
+zola check
+```
+
+### 27.3 Production build
+
+```bash
+zola build
+```
+
+Build成功後、`public/`が自己完結していること。
+
+### 27.4 Build Gate
+
+以下のいずれかで失敗したらDeploy不可。
+
+- `zola check` failure
+- `zola build` failure
+- broken internal link
+- required related content path missing
+- missing required template
+- missing syntax language when error_on_missing_language=true
+
+---
+
+## 28. Deployment interface
+
+Deployment詳細は別Phaseだが、Client siteは以下の契約を満たす。
+
+Input:
+
+```text
+source repository
+```
+
+Build output:
+
+```text
+public/
+```
+
+Deploy sideは`public/`の中身をrelease rootへ展開する。
+
+最終URL rootに余計な`public/` directory layerを作らない。
+
+例:
+
+```text
+release/
+├── index.html
+├── notes/
+├── software/
+├── tags/
+├── main.css
+└── ...
+```
+
+---
+
+## 29. Caddy互換性
+
+既存Caddy:
+
+```text
+root * /srv/www/takashi-2521.com/current
+file_server
+```
+
+Zola outputはCaddy static file serverだけで利用できること。
+
+以下を要求しない。
+
+- rewrite application router
+- server-side include
+- PHP
+- CGI
+- Node
+- Python backend
+
+404 handlingがCaddyで専用設定を必要とする場合は、Deploy統合Phaseで既存Caddy設定との整合を確認する。
+
+---
+
+## 30. CSP compatibility
+
+目標CSP:
+
+```text
+default-src 'self';
+script-src 'self';
+style-src 'self';
+img-src 'self' data:;
+font-src 'self';
+object-src 'none';
+base-uri 'self';
+frame-ancestors 'none';
+```
+
+実装規則:
+
+- Inline JSなし
+- Inline event handlerなし
+- External fontなし
+- External CSSなし
+- External JSなし
+- Evalなし
+- CSS assetはself
+- imageはself/data中心
+
+Syntax highlightがinline styleを生成しないclass modeを優先。
+
+---
+
+## 31. Error handling
+
+Static siteのためruntime error UIは不要。
+
+Build-timeに可能な限り失敗を検知する。
+
+- Broken internal links: error
+- Related page missing: Tera error
+- Missing templates: build error
+- Invalid front matter: build error
+
+External linksは一時障害を考慮し`warn`を基本とする。
+
+---
+
+## 32. Content authoring rules
+
+### 32.1 Notes
+
+- filename: lowercase ASCII kebab-case
+- `date`必須
+- title日本語可
+- tags任意
+- headingsはH2以降を本文主階層に使用
+- H1はtemplate titleに委ねる
+- referencesは本文末尾H2
+
+### 32.2 Software
+
+- filename: software slug
+- cgit source必須
+- GitHubはmirrorとしてoptional
+- Overview/background/processはMarkdown本文
+- screenshotは必要時のみ
+
+### 32.3 Internal references
+
+`@/` linkまたはfront matter pathを使用。
+公開URLを内部参照用にhard-codeしない。
+
+---
+
+## 33. Date display
+
+内部データはISO date。
+
+表示は初期実装で:
+
+```text
+2026-08-21
+```
+
+とする。
+
+将来日本語表記`2026年8月21日`へ変更してもcontent metadataは変えない。
+
+---
+
+## 34. Home content algorithm
+
+Pseudo:
+
+```text
+notes = get_section(notes)
+software = get_section(software)
+
+recent_notes = first 5 notes
+recent_software = first 4 software
+
+render:
+ site intro
+ recent notes
+ all notes link
+ software
+ all software link
+ about short text
+```
+
+Homeは最新更新日を強く演出せず、`最近のNotes`と表記する。
+
+---
+
+## 35. Archive algorithm
+
+Zola公式archive patternを使用。
+
+Pseudo Tera:
+
+```tera
+{% set pages_by_year = section.pages | group_by(attribute="year") %}
+{% for year, pages in pages_by_year %}
+ <section>
+ <h2>{{ year }}</h2>
+ {% for page in pages %}
+ ...
+ {% endfor %}
+ </section>
+{% endfor %}
+```
+
+使用Zola/Tera版でyear orderが期待通りでない場合、公式Archive例のreverse処理を採用する。
+
+---
+
+## 36. TOC recursive rendering
+
+`page.toc`の`children`を階層描画する。
+
+概念:
+
+```text
+toc(headers):
+ ul
+ foreach header
+ li
+ a header.permalink / title
+ if children
+ toc(children)
+```
+
+使用Zola版がTera componentを推奨する場合はcomponentを使用する。
+古いshortcode設計を新規導入しない。
+
+---
+
+## 37. Dark mode persistence
+
+`theme.js` concept:
+
+```text
+on load:
+ stored = localStorage.getItem("theme")
+ if stored light/dark:
+ set data-theme
+
+on toggle:
+ determine current
+ toggle
+ store
+ update accessible label
+```
+
+System preferenceはCSS側で処理する。
+
+localStorageが利用不可でもerrorで本文表示を妨げない。
+
+---
+
+## 38. Favicon
+
+初期faviconは自作SVG 1ファイル。
+
+モチーフは単純な文字または記号。
+
+例候補:
+
+- 「記」
+- `T`
+- 小さな本/ノートを抽象化した幾何形状
+
+初期実装では複雑なfavicon pipelineを作らない。
+
+---
+
+## 39. 404 design
+
+通常Pageと同じwidth/token/themeを使用。
+
+内容:
+
+```text
+404
+ページが見つかりません。
+
+Home
+Notes
+Software
+```
+
+Animationやillustration不要。
+
+---
+
+## 40. Testing / Validation checklist
+
+### 40.1 Zola
+
+- [ ] `zola check`
+- [ ] `zola build`
+- [ ] `/public/index.html`
+- [ ] `/public/notes/index.html`
+- [ ] `/public/software/index.html`
+- [ ] `/public/about/index.html`
+- [ ] `/public/404.html`
+- [ ] `/public/atom.xml`
+- [ ] `/public/rss.xml`
+- [ ] `/public/giallo-light.css`
+- [ ] `/public/giallo-dark.css`
+- [ ] sitemap
+- [ ] robots
+
+### 40.2 Content
+
+- [ ] Note 2件以上でyear grouping確認
+- [ ] 複数年でarchive確認
+- [ ] tag link確認
+- [ ] updatedあり/なし確認
+- [ ] TOCあり/なし確認
+- [ ] footnote確認
+- [ ] references style確認
+- [ ] related software確認
+- [ ] related note確認
+- [ ] Software GitHub mirrorあり/なし確認
+- [ ] Screenshotあり/なし確認
+
+### 40.3 Responsive
+
+- [ ] Desktop
+- [ ] Narrow desktop
+- [ ] Tablet
+- [ ] Mobile
+- [ ] Long title
+- [ ] Long URL
+- [ ] Code block
+- [ ] Table
+- [ ] Image
+
+### 40.4 Accessibility
+
+- [ ] Keyboard only
+- [ ] Focus visible
+- [ ] Skip link
+- [ ] Heading hierarchy
+- [ ] Theme toggle keyboard
+- [ ] Link underline
+- [ ] Dark contrast
+- [ ] Light contrast
+
+### 40.5 Security
+
+- [ ] no external JS
+- [ ] no external CSS
+- [ ] no npm
+- [ ] no Node
+- [ ] no inline event handler
+- [ ] no eval
+- [ ] CSP-compatible
+- [ ] no tracking script
+
+---
+
+## 41. Traceability / 仕様整合性確認
+
+| Specifications要求 | Design対応 | 状態 |
+|---|---|---|
+| Notes + Software中心 | Sectionsとして分離 | OK |
+| Home index | `index.html`で5 Notes / 4 Software | OK |
+| 年別Notes | Zola archive `group_by(year)` | OK |
+| tagsのみ | `taxonomies = [{name="tags"}]` | OK |
+| Note Sans/余白 | Typography/Layout | OK |
+| Note TOC常時 | `page.toc` inline nav | OK |
+| Footnotes | Zola Markdown標準 | OK |
+| References | Markdown H2 +共通SCSS | OK |
+| 公開日/更新日 | date/updated | OK |
+| Software一覧はPJ名中心 | software/section | OK |
+| Software背景・過程 | Markdown body | OK |
+| 言語/License | `extra` | OK |
+| cgit正本 | `extra.source`必須 | OK |
+| GitHub mirror | optional extra | OK |
+| Related Notes/Software | explicit content path + `get_page` | OK |
+| About | `about.md` | OK |
+| Header小型 | partial/header | OK |
+| Source navなし | Headerには含めない | OK |
+| 日本語のみ | `default_language="ja"` | OK |
+| Sans + Mono | SCSS token | OK |
+| 青accent | color token | OK |
+| Dark mode | CSS + minimal JS | OK |
+| Sidebarなし | article inline layout | OK |
+| タグは一覧中心 | Note detailで主要表示しない | OK |
+| RSS + Atom | built-in feeds | OK |
+| Search将来 | initial false | OK |
+| Comments条件付き | initial scope外 | OK |
+| SNS条件付き | initial scope外 | OK |
+| Analyticsなし | scriptなし | OK |
+| Images最小限 | colocated assets optional | OK |
+| No animation | motionなし | OK |
+| Blue links | SCSS | OK |
+| External marker | `external_links_class` + CSS | OK |
+| ASCII slug | authoring rules | OK |
+| Caddy static | public artifact only | OK |
+| npm/Nodeなし | no dependency toolchain | OK |
+
+---
+
+## 42. 仕様上の未確定事項に対する設計判断
+
+### 42.1 本文最大幅
+
+仕様では後決めだったため、初期値 **72ch** を採用。
+日本語本文で広すぎる場合は65〜75ch相当の範囲で調整する。
+
+### 42.2 青の具体色
+
+初期候補として落ち着いた`#315f82`系を採用。
+WCAG contrast確認後に調整可。
+
+### 42.3 Home件数
+
+仕様上「おまかせ」だったため以下を採用。
+
+- Notes 5
+- Software 4
+
+### 42.4 favicon
+
+自作単純SVGとし、外部assetを導入しない。
+最終モチーフはvisual tuning時に決定可能。
+
+### 42.5 Comments
+
+静的構成との境界が未確定のため、初期実装対象外。
+
+### 42.6 SNS共有
+
+「簡単に対応できれば」という条件付き要件のため、初期実装対象外。
+外部dependencyなしで必要性が確認できた時点で追加する。
+
+---
+
+## 43. 実装Phase
+
+### Phase C1 — Foundation
+
+- Zola version確認
+- `zola.toml`
+- content structure
+- base template
+- SCSS entry
+- `zola check/build`
+
+PASS:
+- Build成功
+- Home生成
+
+### Phase C2 — Information Architecture
+
+- Notes Section
+- Software Section
+- About
+- Tags taxonomy
+- URLs
+
+PASS:
+- `/notes/`, `/software/`, `/about/`, `/tags/`
+
+### Phase C3 — Editorial UI
+
+- Header/Footer
+- typography
+- layout
+- light/dark
+- links
+- responsive
+
+PASS:
+- Desktop/Mobile
+- no external dependencies
+
+### Phase C4 — Notes
+
+- year archive
+- tags in list
+- note dates
+- TOC
+- footnotes
+- references
+
+PASS:
+- 複数年sampleで表示確認
+
+### Phase C5 — Software
+
+- software list
+- detail metadata
+- source/mirror
+- related notes
+- optional images
+
+PASS:
+- Source優先表示
+- related page resolution
+
+### Phase C6 — Static Features
+
+- feeds
+- sitemap
+- robots
+- 404
+- syntax highlighting
+- favicon
+
+PASS:
+- expected artifacts生成
+
+### Phase C7 — Final Validation
+
+- `zola check`
+- `zola build`
+- link checks
+- accessibility
+- responsive
+- CSP compatibility
+- Git status
+
+PASS:
+- Specifications受入条件を全件満たす
+
+---
+
+## 44. 実装禁止事項
+
+Codex等の実装エージェントは以下を勝手に追加しない。
+
+- npm
+- Node.js
+- React
+- Vue
+- Svelte
+- htmx
+- Tailwind
+- Bootstrap
+- external CSS framework
+- external icon framework
+- external JS CDN
+- Google Fonts等external font
+- client-side syntax highlighter
+- analytics
+- comments
+- search
+- server backend
+- database
+- Docker
+- unnecessary build script
+- external Zola theme
+- animations
+
+必要が生じた場合は実装前に要求変更として報告する。
+
+---
+
+## 45. 完了判定
+
+Design実装完了時に以下を報告する。
+
+1. 使用Zola version
+2. 実装したdirectory tree
+3. `zola check`結果
+4. `zola build`結果
+5. 生成ファイル確認
+6. 主要URL一覧
+7. external dependencyがないこと
+8. Specifications traceability結果
+9. 未実装項目
+10. 仕様からの逸脱の有無
+
+仕様から逸脱した場合は、理由・影響・代替案を明記する。
+
+---
+
+## 46. 公式Zola仕様との整合上の注意
+
+- `zola.toml` を正式設定ファイルとして使用する。
+- `content/notes/_index.md` と `content/software/_index.md` をSection定義とする。
+- `about.md` はPageとして扱う。
+- Homepageはroot Sectionとして`templates/index.html`を使用する。
+- Notes/SoftwareはSectionの`template` / `page_template`で専用Templateへ接続する。
+- ZolaのTaxonomyで`tags`を実装する。
+- 年別ArchiveはZola公式例と同じ`group_by(attribute="year")`系の実装を使う。
+- 関連Pageは`get_page(path=...)`で解決する。
+- Markdown本文内の内部リンクは`@/`を優先する。
+- Feed、sitemap、robotsはZola built-inを優先する。
+- `static/`はas-is copy、`sass/`はZola compile対象として扱う。
+- Page/SectionのTera contextを使用し、独自content indexを作らない。
+- 利用Zola版でTera Componentsが利用可能・推奨なら、TOC等の再利用可能UIに採用してよい。
+- 将来Searchを有効化する際、日本語検索index対応はZola binary build featureの確認を必須とする。