# たかしの記録 — 技術設計書 ## 1. 文書の役割 本書は、[Specifications.md](Specifications.md)で定義した利用者向け要求を、現在のリポジトリでどのように実現しているかを記録する。 記載対象は、実装済みの構成、設定、コンテンツモデル、テンプレート、スタイル、クライアント処理、生成物、検証方法である。将来案や完了済みの実装計画は含めない。コードと本書が異なる場合はコードを正とし、本書を同じ変更内で更新する。 ## 2. システム構成 ### 2.1 技術要素 | 項目 | 採用内容 | |---|---| | Static Site Generator | Zola 0.23.3 | | Content | Markdown + TOML Front Matter | | Template | Tera 2 | | Style | SCSSをZolaでコンパイル | | Client script | theme切替用のVanilla JavaScript 1ファイル | | Syntax highlight | Zola組み込み、class方式、`github-light`/`github-dark` | | 配信形式 | 静的なHTML、CSS、JavaScript、XML、SVG、記事asset | | 外部theme | 使用しない。`themes/`は空で保持する。 | | Node.js/frontend framework | 使用しない | | CDN/外部font | 使用しない | | Backend/database | 使用しない | ### 2.2 生成フロー ```text content/*.md ─┐ templates/* ──┼─> Zola ─> public/ ─> 静的配信 sass/*.scss ──┤ static/* ─────┘ ``` ZolaがSection、Page、Taxonomyを解決し、TeraでHTMLを生成する。SCSSは`main.css`へコンパイルし、`static/`とPage Bundle内のassetを出力へコピーする。公開環境は`public/`の内容だけで成立する。 ## 3. リポジトリ構造 ```text . ├── zola.toml ├── content/ │ ├── _index.md │ ├── about.md │ ├── notes/ │ │ ├── _index.md │ │ └── .md │ └── software/ │ ├── _index.md │ ├── .md │ └── / │ ├── index.md │ └── ├── templates/ │ ├── base.html │ ├── index.html │ ├── page.html │ ├── 404.html │ ├── notes/ │ ├── software/ │ ├── tags/ │ └── partials/ ├── sass/ │ ├── main.scss │ └── _*.scss ├── static/ │ ├── favicon.svg │ └── js/theme.js ├── doc/ │ ├── Specifications.md │ ├── Design.md │ └── content-templates/ ├── draft/ ├── themes/ └── public/ ``` | ディレクトリ | 管理方針 | |---|---| | `content/` | 公開対象の原稿だけを置く。 | | `draft/` | 非公開原稿を置き、Git管理とZola処理の対象外にする。 | | `themes/` | 外部themeを導入せず空で保持する。 | | `public/` | ビルド生成物。Git管理対象外とする。 | ## 4. Zola設定 設定の完全な値と各項目の説明は`zola.toml`を正とする。本節では、サイト構造に影響する設定をまとめる。 ### 4.1 サイト設定 | Key | 現在値 | 用途 | |---|---|---| | `base_url` | `https://www.takashi-2521.com` | canonical URLと絶対URLの基準 | | `title` | `たかしの記録` | Header、HTML title、Feed | | `description` | サイト説明文 | meta description、About、Feed | | `default_language` | `ja` | HTML言語と既定言語 | | `output_dir` | `public` | 生成先 | | `compile_sass` | `true` | SCSSコンパイル | | `minify_html` | `false` | HTMLを可読な状態で出力 | | `author` | `Takashi` | PageとFeedの既定author | ### 4.2 配信機能 | Key | 現在値 | 結果 | |---|---|---| | `generate_feeds` | `true` | サイト全体のFeedを生成 | | `feed_filenames` | `atom.xml`, `rss.xml` | AtomとRSSを生成 | | `taxonomies` | `tags`, `feed=false` | タグページを生成し、タグ別Feedは生成しない | | `build_search_index` | `false` | 検索indexを生成しない | | `generate_sitemap` | `true` | `sitemap.xml`を生成 | | `generate_robots_txt` | `true` | `robots.txt`を生成 | Software Pageは`include_in_feeds = false`とし、日付を持っていてもサイトFeedへ含めない。現在のサイトFeedは実質的にNotesを購読対象とする。 ### 4.3 Markdown | 設定 | 現在値 | 設計意図 | |---|---|---| | `bottom_footnotes` | `true` | 脚注を記事末尾へ集約し、本文への戻りリンクを生成 | | `insert_anchor_links` | `heading` | 見出し全体をdeep linkにする | | `lazy_async_image` | `true` | 画像へ遅延・非同期decode属性を付与 | | `external_links_class` | `external-link` | 外部リンクをCSSで識別 | | `external_links_external` | `true` | 外部リンクへ`rel="external"`を付与 | | `smart_punctuation` | `false` | 原稿の文字を自動置換しない | ### 4.4 Syntax highlight | 設定 | 現在値 | |---|---| | 出力方式 | `class` | | Light theme | `github-light` | | Dark theme | `github-dark` | | 未対応言語 | エラー | | 生成CSS | `giallo-light.css`, `giallo-dark.css` | class方式を使用し、コード色をHTMLのinline styleへ埋め込まない。Light/Dark用CSSは`base.html`から個別に読み込む。 ### 4.5 カスタム設定 `[extra]`はTeraから参照するサイト固有値である。 | Key | 参照先 | |---|---| | `home_notes_limit` | Homeに表示するNotes件数 | | `home_software_limit` | Homeに表示するSoftware件数 | | `copyright_year` | Footer | | `mail` | AboutとFooter | | `cgit` | Software一覧 | | `github` | 予約済み。現在のTemplateでは未使用 | ## 5. コンテンツモデル ### 5.1 SectionとPage | Source | Zola model | Template | 並び順 | |---|---|---|---| | `content/_index.md` | Root Section | `index.html` | 各Sectionの設定に従う | | `content/about.md` | Page | `page.html` | 対象外 | | `content/notes/_index.md` | Section | `notes/section.html` | `date`降順 | | `content/notes/*.md` | Page | `notes/page.html` | `date` | | `content/software/_index.md` | Section | `software/section.html` | `date`降順 | | `content/software/*.md` | Page | `software/page.html` | `date` | | `content/software/*/index.md` | Page Bundle | `software/page.html` | `date` | `_index.md`はSection、通常の`.md`と`index.md`はPageとして扱う。Softwareに画像などを併置する場合だけPage Bundleを使用する。 ### 5.2 Notes Front Matter 完全な作成用雛形は[content-templates/note.md](content-templates/note.md)に置く。 | Field | 型 | 必須 | 利用箇所 | |---|---|---:|---| | `title` | String | Yes | 一覧、詳細、HTML title | | `description` | String | No | 一覧、詳細、meta description | | `date` | Date | Yes | 公開日、並び順、年別分類 | | `updated` | Date | No | 詳細の更新日 | | `taxonomies.tags` | Array[String] | No | 一覧、タグページ | | `extra.related_software` | Array[String] | No | 詳細末尾の関連Software | Markdownファイル名は英語ASCIIのslugとする。表示タイトルは日本語を許可する。 ### 5.3 Software Front Matter 完全な作成用雛形は[content-templates/software.md](content-templates/software.md)に置く。 | Field | 型 | 必須 | 利用箇所 | |---|---|---:|---| | `title` | String | Yes | 一覧、詳細、HTML title | | `description` | String | No | 一覧、詳細、meta description | | `date` | Date | Yes | 並び順 | | `include_in_feeds` | Boolean | Yes | `false`でサイトFeedから除外 | | `extra.language` | Array[String] | No | 詳細の使用言語 | | `extra.license` | String | No | 詳細のライセンス | | `extra.source` | URL String | Yes | cgit正本へのリンク | | `extra.github_mirror` | URL String | No | GitHub mirrorへのリンク | | `extra.related_notes` | Array[String] | No | 詳細末尾の関連Notes | 本文の章立ては固定しないが、原則として概要、背景、開発の過程を含める。スクリーンショットはPage Bundle内へ置き、相対pathで参照する。 ### 5.4 Aboutとサイト共通値 Aboutは汎用`page.html`を使用する。サイト説明とメールアドレスは本文へ重複記載せず、`config.description`と`config.extra.mail`を参照する。 ### 5.5 関連コンテンツ 関連付けはタグから自動推測せず、Front Matterで明示する。 ```toml [extra] related_software = ["software/example/index.md"] related_notes = ["notes/example.md"] ``` pathは`content/`を基準にしたMarkdown pathとする。Partial内で`get_page(path=path)`を使用するため、対象を削除すると`zola check`が失敗する。記事削除時は相互参照と本文中の内部リンクも同時に削除する。 ## 6. URLと生成物 ### 6.1 Page URL | 種別 | URL | |---|---| | Home | `/` | | About | `/about/` | | Notes一覧 | `/notes/` | | Note詳細 | `/notes//` | | Software一覧 | `/software/` | | Software詳細 | `/software//` | | タグ一覧 | `/tags/`(タグ使用時) | | タグ別一覧 | `/tags//`(タグ使用時) | | 404 | `/404.html` | `slugify.paths`、`slugify.taxonomies`、`slugify.anchors`は`on`とする。Markdown内の内部リンクは`@/`記法、Tera内は`get_url(path="@/...")`を使用し、`base_url`や配置変更へ追従させる。 ### 6.2 サイト共通出力 | 出力 | 生成元 | |---|---| | `main.css` | `sass/main.scss` | | `giallo-light.css` | Zola syntax highlight | | `giallo-dark.css` | Zola syntax highlight | | `js/theme.js` | `static/js/theme.js` | | `favicon.svg` | `static/favicon.svg` | | `atom.xml` | Zola built-in Feed template | | `rss.xml` | Zola built-in Feed template | | `sitemap.xml` | Zola built-in sitemap template | | `robots.txt` | Zola built-in robots template | ## 7. Template設計 ### 7.1 継承構造 ```text base.html ├── index.html ├── page.html ├── 404.html ├── notes/section.html ├── notes/page.html ├── software/section.html ├── software/page.html ├── tags/list.html └── tags/single.html ``` `base.html`は文書骨格、metadata、共通CSS/JavaScript、Header、Footer、`main`を提供する。各ページは`title`、`description`、`content` blockを上書きする。 ### 7.2 共通部品 | Partial | 役割 | |---|---| | `partials/header.html` | サイト名、Home/Notes/Software/About、theme切替 | | `partials/footer.html` | copyright、Atom、RSS、Mail | | `partials/note-list-item.html` | Noteの日付、タイトル、説明、タグ | | `partials/software-list-item.html` | Software名と説明 | | `partials/related-notes.html` | Softwareから関連Notesを解決 | | `partials/related-software.html` | Noteから関連Softwareを解決 | | `partials/toc.html` | Zolaの階層化された目次を再帰描画 | ### 7.3 Metadata `base.html`は全ページへ次を出力する。 - UTF-8とresponsive viewport - `lang="ja"` - ページ固有またはサイト共通のdescription - ページ固有のtitle - canonical URL - SVG favicon - Atom/RSS autodiscovery - Light/Dark syntax CSS - `main.css`と`theme.js` Page titleは詳細・一覧とも`<ページ名> | <サイト名>`、Homeはサイト名だけとする。 ### 7.4 HeaderとFooter Headerは`current_path`から現在地を判定し、対象リンクへ`aria-current="page"`を付ける。モバイルではHeaderを折り返し、ナビゲーションを次行へ配置する。 `body`を縦Flex、`main`を可変領域、Footerを固定高ではない終端領域とする。短いページではFooterをviewport下端へ置き、長いページでは本文の直後へ配置する。Footer内の上下paddingは全ページ共通である。 ### 7.5 Home Homeは本文用`h1`や紹介文を表示せず、最近のNotesとSoftwareだけを表示する。それぞれのSection Pageを取得し、`config.extra.home_*_limit`件まで描画する。対象が0件の場合は説明付き空状態を表示する。 ### 7.6 Notes 一覧は`section.pages`を`year`でgroup化し、年見出しとNote一覧を生成する。詳細はタイトル、公開日、任意の更新日・説明、目次、本文、関連Softwareの順に描画する。 目次は`page.toc`が空でない場合だけ表示する。脚注はMarkdown rendererが記事末尾へ生成する。 ### 7.7 Software 一覧はSoftware名と説明を簡潔に表示し、末尾からサイト共通のcgitへ案内する。詳細はタイトル、説明、metadata、本文、関連Notesの順に描画する。 metadataはデスクトップで2列、モバイルで1列とする。項目数が奇数の場合、最後の項目を全幅にして罫線を維持する。Sourceは必須、language、license、Mirrorは値がある場合だけ表示する。 ### 7.8 Tagsと404 タグ一覧は`terms`の名称と記事数を表示する。タグ別ページは`term.pages`をNote一覧Partialで表示する。404はHome、Notes、Softwareへの復帰導線を持つ。 ## 8. Presentation設計 ### 8.1 SCSS構成 `sass/main.scss`から次の順でPartialを読み込む。 | Partial | 責務 | |---|---| | `_tokens.scss` | 色、font、幅、罫線のcustom properties | | `_reset.scss` | box modelと既定marginの初期化 | | `_base.scss` | body、link、focus、外部link | | `_typography.scss` | 見出しとmetadata文字 | | `_layout.scss` | container、page余白、共通配置 | | `_header.scss` | Header、navigation、theme button | | `_footer.scss` | Footer | | `_archive.scss` | Notes一覧、タグ表示、空状態 | | `_article.scss` | 記事header、目次、本文、脚注、関連項目 | | `_software.scss` | Software一覧とmetadata | | `_taxonomy.scss` | タグ一覧 | | `_code.scss` | inline codeとcode block | | `_theme.scss` | 手動themeとreduced motion | | `_utilities.scss` | skip link、視覚非表示utility | ### 8.2 Design tokens | Token | Light | Dark | |---|---|---| | Background | `#f6f5f1` | `#17191b` | | Surface | `#fbfaf7` | `#1d2022` | | Text | `#202124` | `#e9e9e6` | | Muted | `#666b70` | `#a0a3a6` | | Border | `#d6d8da` | `#363a3e` | | Link | `#315f82` | `#86b6d8` | | Focus | `#1e668f` | `#86b6d8` | 本文fontはsystem sans-serif、metadataとcodeはsystem monospaceを使用する。外部fontは読み込まない。本文最大幅は`72ch`、サイト最大幅は`72rem`とする。 ### 8.3 Responsive layout | 対象 | Breakpoint | 変更 | |---|---:|---| | Footer | `32rem` | 縦積み | | Home section heading | `38rem` | 縦積み | | Notes一覧 | `40rem` | 年・日付と本文を1列化 | | Header/Software | `42rem` | Header折返し、Softwareを1列化 | containerは左右に最低`1rem`の余白を確保する。表とcode blockは必要に応じて横スクロールさせ、ページ全体の横overflowを防ぐ。画像はcontainer幅を超えない。 ## 9. Theme切替 初期themeは`prefers-color-scheme`に従う。JavaScriptが動作するとtheme buttonを表示し、選択した`light`または`dark`を`localStorage.theme`へ保存する。 `static/js/theme.js`は次を同期する。 1. `` 2. theme buttonの表示、`aria-label`、`aria-pressed` 3. Light/Dark syntax CSSの`media` 4. OS theme変更。ただし手動選択済みの場合は上書きしない。 Storageへアクセスできない場合も現在のページでは切替を継続する。JavaScriptが無効な場合はbuttonを非表示にし、CSSの`prefers-color-scheme`だけで表示する。 ## 10. Accessibility設計 | 要求 | 実装 | |---|---| | Landmark | `header`、`nav`、`main`、`article`、`section`、`footer`を用途に応じて使用 | | Skip link | ページ先頭から`#main-content`へ移動 | | 現在地 | Header linkの`aria-current="page"` | | Focus | 全操作要素へ3px outlineを表示 | | 見出し | 一覧・詳細はページ名を`h1`、本文を`h2`以下とする。Homeはサイト名の重複表示を避け、各領域を`h2`とする。 | | 日付 | 表示値と`datetime`を持つ`time` | | 目次 | `nav`と`aria-label="目次"` | | Theme | buttonの状態と操作内容をARIAへ反映 | | Motion | `prefers-reduced-motion: reduce`でanimationとtransitionを抑制 | | 画像 | Markdownで代替textを必須とする | ## 11. Feed・Taxonomy・SEO ### 11.1 Feed サイトrootへAtomとRSSを生成し、全HTMLからautodiscovery linkを提供する。SoftwareはPage単位でFeedから除外する。タグ別Feedは生成しない。 ### 11.2 Taxonomy `tags`だけを定義する。Noteの`taxonomies.tags`からタグ一覧とタグ別ページを自動生成する。タグを持つNoteが0件の場合、Zolaはタグページを生成しない。タグURLは`slugify.taxonomies = "on"`に従う。 ### 11.3 SEO metadata 全ページにtitle、description、canonical URLを設定する。sitemapとrobots.txtはZola組み込みtemplateで生成する。Open Graph、SNS card、構造化dataは実装しない。 ## 12. Security・Privacy・Performance ### 12.1 SecurityとPrivacy - inline scriptとinline event handlerを使用しない。 - Syntax highlightはclass方式とし、inline styleを生成しない。 - 外部theme、CDN、外部font、analytics、commentsを使用しない。 - 新しいtabを開く明示的な外部linkには`noopener noreferrer`を付ける。 - theme選択以外の利用者dataを保存しない。 - 動的入力、認証、server-side処理を持たない。 この構成は厳格なContent Security Policyを適用しやすいが、CSP header自体は配信環境の責務であり本リポジトリでは設定しない。 ### 12.2 Performance - JavaScriptはtheme切替の1ファイルだけを`defer`で読み込む。 - system fontを使用し、font downloadを発生させない。 - Markdown画像へlazy loadingとasync decodingを付ける。 - Pageごとに必要な静的HTMLを生成し、実行時renderingを行わない。 - Syntax CSSはthemeごとに分離する。 ## 13. 執筆・保守手順 ### 13.1 記事追加 1. [content-templates/README.md](content-templates/README.md)を確認する。 2. NotesまたはSoftwareの雛形をコピーする。 3. Front Matterの説明コメントを削除し、必須値を入力する。 4. 関連pathとMarkdown内部リンクを確認する。 5. `zola check`と`zola build`を実行する。 Markdownを追加するだけでSection一覧、個別URL、Homeの最新一覧へ反映される。Templateの変更は不要である。 ### 13.2 記事削除 削除対象を参照する次の箇所を先に検索する。 ```text extra.related_notes extra.related_software Markdownの @/ 内部リンク ``` 参照を残すと`get_page`またはlink checkerによりビルドが失敗する。削除後は必ず`zola check`を実行する。 ### 13.3 Draft 公開しない原稿はrootの`draft/`へ置く。`draft/`は`.gitignore`に含まれ、Gitでも管理しない。公開時にFront Matterを整え、対応する`content/`配下へ移す。 ## 14. Build・検証・配信境界 ### 14.1 Command | 目的 | Command | |---|---| | 開発表示 | `zola serve` | | 構造・link検証 | `zola check` | | 生成 | `zola build` | ### 14.2 必須検証 | 分類 | 確認内容 | |---|---| | Zola | `zola check`と`zola build`が成功する。 | | Page | Home、About、Notes、Software、404が生成され、タグ使用時はTagsも生成される。 | | Feed | `atom.xml`と`rss.xml`が生成され、Softwareを含まない。 | | Crawler | `sitemap.xml`と`robots.txt`が生成される。 | | Asset | `main.css`、syntax CSS 2種、theme.js、favicon、記事assetが生成される。 | | Link | 削除済みPage、存在しない関連path、誤った内部linkがない。 | | HTML | canonical URLとFeed autodiscoveryが正しい。 | | Security | inline script、inline event handler、外部CDN参照がない。 | | Responsive | Header、一覧、Software metadata、Footerが各breakpointで崩れない。 | | Accessibility | skip link、focus、現在地、見出し順、theme buttonを確認する。 | ### 14.3 配信境界 本リポジトリの責務は`public/`の生成までとする。VPS、Caddy、TLS、cache、CSP header、deploy scriptは外部の配信環境で管理し、本設計の対象外とする。 ## 15. 仕様との対応 | 仕様領域 | 主な実装箇所 | |---|---| | Home | `templates/index.html`、`home_*_limit` | | Notes | `content/notes/`、`templates/notes/`、`_archive.scss`、`_article.scss` | | Tags | `taxonomies`、`templates/tags/`、`_taxonomy.scss` | | Software | `content/software/`、`templates/software/`、`_software.scss` | | About | `content/about.md`、`templates/page.html`、`zola.toml` | | 共通navigation | `partials/header.html`、`partials/footer.html` | | Theme | `_tokens.scss`、`_theme.scss`、`static/js/theme.js` | | Accessibility | `base.html`、各semantic template、`_utilities.scss` | | Feed・crawler | `zola.toml`、`base.html`、Zola built-in templates | | Privacy・Security | `zola.toml`、`base.html`、local asset構成 |