初回コミット: パーソナル図解ツールキット

Made-with: Cursor
This commit is contained in:
snc777 2026-03-20 15:51:26 +09:00
commit 4216635369
32 changed files with 3508 additions and 0 deletions

View File

@ -0,0 +1,68 @@
---
name: creating-skills
description: スキルを作成・更新・改善するスキル。「スキルを作って」「このスキルを改善して」「スキルを更新して」など依頼された際やスキルを更新する際に使用する。
---
# Skill Creator
**品質方針**: スキル作成は時間より品質を優先する。手順のスキップや品質チェックの省略は禁止。全ステップを確実に実行し、品質チェックを通過してから完了とする。
## 必読リファレンス(省略禁止)
**作業開始前に必ず全て読むこと。時間短縮のためにスキップしない:**
1. [references/principles.md](references/principles.md) — 核心原則・構造・判断基準
2. [references/ssot-audit.md](references/ssot-audit.md) — SSoT 監査・ハードコード不整合レビュー(ゲートとして必ず実行)
3. [references/exemplar.md](references/exemplar.md) — 模範例・品質チェックリスト
4. [references/patterns.md](references/patterns.md) — 設計パターン・サイズ目安
## 作成プロセス
### Step 0: リファレンスを読む
上記4つのリファレンスを全て読む。省略禁止。
### Step 1: 種類を判断
汎用スキルかプロジェクト固有スキルかを判断する。
→ [principles.md](references/principles.md)(スキルの種類)
### Step 2: 情報を分離
SKILL.md に置く情報と references/ に置く情報を分離する。
→ [patterns.md](references/patterns.md)ディレクトリパターン、3段階ローディング
### Step 3: 洗練
核心原則に基づいてスキルの内容を精査する。
→ [principles.md](references/principles.md)(洗練、簡潔性)
### Step 4: SSoT 監査(ゲート)
**SSoT 監査を通過するまで次のステップに進めない。**
[ssot-audit.md](references/ssot-audit.md) の全ステップを実行し、違反がないことを確認する。違反が見つかったら修正してから再監査。
### Step 5: 品質チェック
[exemplar.md](references/exemplar.md) のチェックリストを全項目確認する。未通過の項目があれば修正。
### Step 6: ハードコード・不整合レビュー(ゲート)
**このレビューを通過するまで完了としない。**
作成したスキルに以下の問題がないか最終確認する:
1. **ハードコードされた詳細情報がないか** — 参照先を読めばわかる具体的な値・構造・手順がスキル内にベタ書きされていないか
2. **参照先変更時の不整合リスクがないか** — 参照先が更新されたとき、スキル内の記述が古くなる箇所がないか
→ [ssot-audit.md](references/ssot-audit.md)(ハードコード・不整合レビュー)
### Step 7: 評価と反復
スキルを書いて終わりにしない。実際の使用を観察して改善する。
→ [exemplar.md](references/exemplar.md)(評価と反復プロセス)

View File

@ -0,0 +1,321 @@
# スキル模範例とチェックリスト
## 目次
- description の書き方
- 汎用スキル例
- プロジェクト固有スキル例
- コード付きスキル例
- スクリプトの品質
- 評価と反復プロセス
- チェックリスト
---
## description の書き方
### 三人称ルール
descriptionはシステムプロンプトに注入される。視点の不一致はスキル発見の問題を引き起こす。
```yaml
# 良い: 三人称
description: スキルを作成・更新・改善するスキル。「スキルを作って」「このスキルを改善して」と依頼された際に使用する。
# 悪い: 一人称
description: 私がスキルの作成を手伝います。
# 悪い: 二人称
description: あなたがスキルを作成する時に使えます。
```
### トリガーフレーズ
Claudeが100+のスキルから選択する判断材料。具体的なキーワードを含める。
```yaml
# 良い: トリガーフレーズ3つ以上 + 具体的なキーワード
description: |
Cursor Hooksを作成・設定するスキル。
「フックを作って」「hookを追加して」「afterFileEditを設定して」と依頼された際に使用する。
# 悪い: トリガーがない
description: Hooksを処理するスキル。
# 悪い: 抽象的すぎる
description: 設定関連の作業を支援する。
```
### 命名規則
gerund形式動詞+ingが活動を明確に伝える。
```
良い: processing-pdfs, analyzing-data, managing-hooks
許容: pdf-processing, data-analysis名詞句
避ける: helper, utils, tools曖昧
```
---
## 汎用スキル
プロジェクト固有の実装に依存しない。公式ドキュメント・仕様に基づく。
### 例: hook-creator
```markdown
---
name: hook-creator
description: Cursor Hooksを作成・設定するスキル。「フックを作って」「hookを追加して」「afterFileEditを設定して」と依頼された際に使用する。
---
# Hook Creator
Cursor Hooksの作成・設定を支援する。
## 概要
Hooksはエージェントループの特定タイミングでカスタムスクリプトを実行する仕組み。
## クイックスタート
[最小限の例]
## フックイベント一覧
| イベント | タイミング | 出力 |
|---------|-----------|------|
| afterFileEdit | ファイル編集後 | なし |
| stop | Agent停止時 | followup_message |
**詳細スキーマ** → [references/events.md](references/events.md)
```
**ポイント**:
- 公式ドキュメントの内容のみ
- プロジェクト固有の実装パターンなし
---
## プロジェクト固有スキル
特定プロジェクトのワークフロー・データ構造に依存。依存先を明示する。
### 構造例
```markdown
---
name: project-specific-skill
description: プロジェクト固有の作業を行うスキル。「〇〇を作って」「〇〇を更新して」と依頼された際に使用する。
---
# Project Specific Skill
## 依存
- `path/to/` 配下のディレクトリ構造
- `config.json` スキーマreferences/schema.md
- 品質チェックフロー(.cursor/hooks/validate.sh
## ワークフロー
[プロジェクト固有のワークフロー]
## 出力形式
[プロジェクト固有のスキーマ]
```
**ポイント**:
- 依存先を「依存」セクションで明示
- 変更時の影響範囲が把握できる
---
## コード付きスキル
スクリプトで決定的処理を実行し、SKILL.md は仕組み・実行方法・出力を記載する。
### 例: hooks-toggle
```markdown
---
name: hooks-toggle
description: Cursorフックを一時的に無効化/有効化するスキル。「フックを止めて」「フックを無効にして」「フックを有効にして」「hooks off」「hooks on」と依頼された際に使用する。
---
# Hooks Toggle
Cursor hooks と SDK hooks を同時に無効化/有効化する。
## 仕組み
`hooks-disabled` ファイルの有無でフックが動作を判定。
- ファイルあり → フック無効
- ファイルなし → フック有効
## 実行
bash .claude/skills/hooks-toggle/scripts/toggle-hooks.sh
## 出力
| 状態 | 出力 |
|------|------|
| 有効→無効 | `Hooks disabled (Cursor + SDK)` |
| 無効→有効 | `Hooks enabled (Cursor + SDK)` |
## 依存
- `.cursor/hooks/on-quiz-edit.ts` - スキップ判定ロジック
- `drill/tools/quiz-viewer/server/hooks/index.ts` - スキップ判定ロジック
```
**ポイント**:
- `scripts/toggle-hooks.sh` で状態管理(ファイル作成/削除)を確実に実行
- SKILL.md は**仕組み・実行方法・出力**を記載(スクリプトの実装詳細は書かない)
- 依存セクションでフック判定ロジックの所在を明示
---
## スクリプトの品質
### Solve, don't punt
スクリプト内でエラーを処理する。Claudeに丸投げしない。
```python
# 良い: エラーを自力で処理
def process_file(path):
try:
with open(path) as f:
return f.read()
except FileNotFoundError:
print(f"File {path} not found, creating default")
with open(path, "w") as f:
f.write("")
return ""
# 悪い: Claudeに丸投げ
def process_file(path):
return open(path).read()
```
### マジックナンバー禁止
設定値には根拠を示す。
```python
# 良い: 根拠がある
REQUEST_TIMEOUT = 30 # HTTPリクエストは通常30秒以内に完了
MAX_RETRIES = 3 # 大半の間欠的エラーは2回目で解消
# 悪い: 根拠不明
TIMEOUT = 47 # なぜ47?
RETRIES = 5 # なぜ5?
```
### 検証可能な中間出力
複雑なタスクでは「計画→検証→実行」パターンでエラーを早期発見する。
```
analyze → changes.json作成 → validate_changes.py → 問題なければ実行
```
バリデーションスクリプトのエラーメッセージは具体的に:
- 良い: `Field 'signature_date' not found. Available: customer_name, order_total`
- 悪い: `Validation failed`
---
## 評価と反復プロセス
### 評価駆動開発
スキルを書く前に、まずClaudeの現状の能力を測定する。
1. **ベースライン計測**: スキルなしでClaudeにタスクを実行させる
2. **Gap特定**: 失敗箇所・不足情報を文書化
3. **評価シナリオ作成**: Gapをテストする3つ以上のシナリオを用意
4. **最小限の記述**: Gapを埋める最小限のスキル内容を書く
5. **反復**: 評価を実行し、ベースラインと比較し、改善
```json
{
"skills": ["pdf-processing"],
"query": "このPDFからテキストを抽出してoutput.txtに保存して",
"files": ["test-files/document.pdf"],
"expected_behavior": [
"PDFライブラリを使用してファイルを正常に読み取る",
"全ページからテキストを漏れなく抽出する",
"output.txtに読みやすい形式で保存する"
]
}
```
### Claude A/B パターン
- **Claude A**(設計者): スキルの内容を設計・改善する会話
- **Claude B**(使用者): スキルを使って実際のタスクを実行する会話
Claude Bの挙動を観察してClaude Aに報告し、改善する:
| 観察 | 対応 |
|------|------|
| Claudeがバンドルファイルを一度も読まない | 不要か、SKILL.mdでの参照が不十分 |
| 同じファイルを繰り返し読む | そのコンテンツをSKILL.mdに昇格 |
| 参照リンクをたどらない | リンクをより目立たせる |
| 予想外の順序でファイルを読む | 構造が直感的でない可能性 |
### チーム展開時
- スキルをチームメンバーに共有し、使用状況を観察
- 「期待通りに発動するか?」「指示は明確か?」「何が足りないか?」を確認
---
## チェックリスト
### 全スキル共通
- [ ] descriptionに「何をするか」と「いつ使うか」の両方がある
- [ ] descriptionにトリガーフレーズ3つ以上
- [ ] descriptionが三人称で書かれている
- [ ] SKILL.md 500行以内
- [ ] 冗長な説明なし
- [ ] 一貫した用語を使用
- [ ] 時間依存情報なし
- [ ] 具体的な例がある
- [ ] ワークフローに明確なステップがある
- [ ] **SSoT 監査を通過済み**[ssot-audit.md](ssot-audit.md) の全ステップを実行し、違反なしを確認)
- [ ] **ハードコード・不整合レビューを通過済み**[ssot-audit.md](ssot-audit.md) のレビュー全項目を確認)
- [ ] 参照は1階層まで深いネスト禁止
- [ ] 100行超の参照ファイルに目次がある
### 汎用スキル
- [ ] 公式ドキュメント・仕様に基づいている
- [ ] プロジェクト固有のパターン・実装がない
- [ ] 他プロジェクトでも使える
### プロジェクト固有スキル
- [ ] 「依存」セクションがある
- [ ] 依存するファイル・ワークフローが明示されている
- [ ] 依存先が変更されたときの影響範囲が分かる
### コード付きスキル
- [ ] 実行方法が SKILL.md に記載されている
- [ ] 決定的処理がスクリプトで実装されている
- [ ] スクリプトがエラーを自力で処理する
- [ ] 設定値に根拠がある(マジックナンバーなし)
- [ ] 必要なパッケージが明記されている
### テスト
- [ ] 実際のタスクでテスト済み
- [ ] 3つ以上の評価シナリオがある
- [ ] 使用予定の全モデルでテスト済みHaiku/Sonnet/Opus

View File

@ -0,0 +1,299 @@
# パターン集
SKILL.mdを簡潔に保ちながら、必要な情報を適切なタイミングで提供するための設計パターン。
## 目次
- 3段階ローディング
- ディレクトリパターン(ハイレベルガイド / ドメイン分割 / 基本と応用 / コード付き)
- 自由度パターン
- ワークフローパターン
- フィードバックループ
- テンプレートパターン
- 条件分岐パターン
- アンチパターン
- サイズ目安
---
## 3段階ローディング
```
Level 1: description常時 → トリガー判定〜100トークン/スキル)
Level 2: SKILL.mdトリガー時 → 指示・手順〜5kトークン
Level 3: references/(必要時) → 詳細情報(実質無制限)
```
Level 3はファイルシステム上に存在するだけで、アクセスされるまでコンテキストを消費しない。スクリプトは実行のみで、コード自体はコンテキストに入らない出力のみ
---
## ディレクトリパターン
### パターン1: ハイレベルガイド
概要クイックスタートをSKILL.mdに、詳細をreferences/に。
```
skill/
├── SKILL.md # 概要 + クイックスタート
└── references/
├── schema.md # 詳細スキーマ
└── examples.md # 使用例
```
**使用場面**: APIドキュメント、チュートリアル系
### パターン2: ドメイン分割
複数ドメインをサポート。必要なドメインのみ読む。
```
skill/
├── SKILL.md # 選択ガイド + 共通手順
└── references/
├── aws.md
├── gcp.md
└── azure.md
```
**使用場面**: マルチプラットフォーム対応
### パターン3: 基本と応用
基本機能はSKILL.md、高度な機能はreferences/に分離。
```
skill/
├── SKILL.md # 基本操作
└── references/
└── advanced.md # 高度な機能
```
**使用場面**: 基本と応用で複雑さが異なる
### パターン4: コード付きスキル
決定的処理をスクリプトで実行し、SKILL.md は目的・実行方法・出力を記載。
```
skill/
├── SKILL.md # 目的 + 実行方法 + 出力
├── scripts/
│ └── do-something.ts # 決定的処理
└── references/ (任意)
```
**使用場面**: ファイルシステム操作、外部ツール連携、状態管理
スクリプトの実行意図を明確にする:
- 「`analyze_form.py` を実行してフィールドを抽出」→ 実行
- 「`analyze_form.py` の抽出アルゴリズムを参照」→ 読む
---
## 自由度パターン
タスクの性質に応じて、指示の具体度を3段階で調整する。
### 高自由度(テキストベースの方針)
ヒューリスティクスが指針となり、文脈で判断が変わり、複数のアプローチが妥当な場合。
```markdown
## コードレビュー
1. コード構造と設計を分析
2. バグや境界ケースの可能性を確認
3. 可読性・保守性の改善を提案
4. プロジェクト規約への準拠を検証
```
### 中自由度(パラメータ付きの擬似コード)
設定が挙動に影響し、ある程度の変動は許容されるが、推奨パターンがある場合。
```markdown
## レポート生成
以下のテンプレートを必要に応じてカスタマイズ:
def generate_report(data, format="markdown", include_charts=True):
# データ処理
# 指定形式で出力
# オプションでチャートを含める
```
### 低自由度(具体的なスクリプト、変更禁止)
操作が壊れやすく、一貫性が必須で、特定の手順を踏む必要がある場合。
```markdown
## データベースマイグレーション
以下のスクリプトをそのまま実行:
python scripts/migrate.py --verify --backup
コマンドを変更したり、フラグを追加しないこと。
```
---
## ワークフローパターン
複雑なタスクを明確なステップに分解する。チェックリストを使うとClaudeが進捗を追跡できる。
```markdown
## ワークフロー
このチェックリストをコピーして進捗を管理:
- [ ] Step 1: フォームを解析analyze_form.py実行
- [ ] Step 2: フィールドマッピングを作成fields.json編集
- [ ] Step 3: マッピングを検証validate_fields.py実行
- [ ] Step 4: フォームに記入fill_form.py実行
- [ ] Step 5: 出力を検証verify_output.py実行
**Step 1: フォームを解析**
実行: `python scripts/analyze_form.py input.pdf`
...
**Step 5: 出力を検証**
検証に失敗した場合、Step 2に戻る。
```
**ポイント**:
- 明確なステップがスキップを防ぐ
- チェックリストでClaudeとユーザーの双方が進捗を把握
---
## フィードバックループ
「実行 → 検証 → 修正 → 再検証」のパターン。出力品質を大幅に改善する。
### コード付きスキルの場合
```markdown
## 編集プロセス
1. `word/document.xml` を編集
2. **即座に検証**: `python scripts/validate.py unpacked_dir/`
3. 検証失敗時:
- エラーメッセージを確認
- XMLを修正
- 再度検証を実行
4. **検証が通るまで次に進まない**
5. リビルド: `python scripts/pack.py unpacked_dir/ output.docx`
```
### コードなしスキルの場合
```markdown
## コンテンツレビュー
1. STYLE_GUIDE.md のガイドラインに従ってコンテンツを作成
2. チェックリストでレビュー:
- 用語の一貫性
- 例のフォーマット準拠
- 必須セクションの網羅
3. 問題があれば修正して再レビュー
4. 全要件を満たすまで次に進まない
```
**ポイント**: バリデーションスクリプトのエラーメッセージは具体的に(例: 「フィールド 'signature_date' が見つかりません。利用可能: customer_name, order_total」
---
## テンプレートパターン
出力形式を指定する。要件の厳密さに応じて表現を変える。
### 厳密な要件
```markdown
## レポート構造
必ずこのテンプレート構造を使用:
# [分析タイトル]
## 要約
[主要な発見の概要1段落]
## 主要な発見
- 発見1データ付き
- 発見2データ付き
## 推奨事項
1. 具体的なアクション
2. 具体的なアクション
```
### 柔軟なガイダンス
```markdown
## レポート構造
以下はデフォルト形式。分析内容に応じて判断:
# [分析タイトル]
## 要約
## 主要な発見
## 推奨事項
セクションは分析の種類に応じて調整すること。
```
---
## 条件分岐パターン
Claudeを決定ポイントで適切な分岐へ導く。
```markdown
## ドキュメント変更ワークフロー
1. 変更の種類を判定:
**新規作成?** → 下の「作成ワークフロー」へ
**既存の編集?** → 下の「編集ワークフロー」へ
2. 作成ワークフロー:
- docx-jsライブラリを使用
- ドキュメントをゼロから構築
- .docx形式にエクスポート
3. 編集ワークフロー:
- 既存ドキュメントを展開
- XMLを直接修正
- 変更ごとにバリデーション
- 完了後にリパック
```
ワークフローが大規模になる場合は、別ファイルに分離してClaudeに適切なファイルを読ませる。
---
## アンチパターン
| 問題 | 解決 |
|------|------|
| SKILL.md 500行超え | references/に分割 |
| references/が深いネスト2階層以上 | 1階層に平坦化 |
| 情報の重複 | 1箇所にのみ記載SSoT |
| descriptionにトリガーなし | トリガーフレーズ3つ以上 |
| 用語の不統一(「抽出」「取得」「取り出し」混在) | 1つの概念に1つの用語 |
| 選択肢の提示しすぎ | デフォルト1つ + 例外時の代替 |
| 時間依存情報「2025年8月以前は〜」 | 現在の方法のみ記載 |
---
## サイズ目安
| ファイル | 推奨 | 上限 |
|----------|------|------|
| description | 〜200文字 | 1024文字 |
| SKILL.md | 〜200行 | 500行 |
| references/各ファイル | 〜300行 | 目次必須100行超 |

View File

@ -0,0 +1,119 @@
# 核心原則
## 目次
- 洗練 (Refine)
- 簡潔性 (Concise)
- SSoT 厳守
- 段階的開示・自由度
- スキルの種類
- 構造とフロントマター
- コード vs プロンプトの判断
- コンテンツガイドライン
---
## 洗練 (Refine)
スキルは**公式ドキュメントや安定した仕様**に基づいて書く。
| 良い | 避ける |
|------|--------|
| 公式APIスキーマ | 現在の実装コード |
| 安定した仕様 | 変更されうるパターン |
| 普遍的な原則 | プロジェクト固有のワークフロー |
**例外**: プロジェクト固有スキルは意図的に依存してよい(→ スキルの種類)
---
## 簡潔性 (Concise)
コンテキストウィンドウは共有資源。**本当に必要な情報だけ**を含める。
- 冗長な説明より簡潔な例
- 「このトークンコストに見合う価値があるか」「Claudeが既に知っていないか」を問う
---
## SSoT 厳守
**参照先の情報をスキル内に書かない。** 情報は必ず1箇所だけに存在させ、他の箇所からは参照する。スキーマが変更された時、スキル内のコピーは古くなり、矛盾が生じる。
違反パターンの具体例・監査手順 → [ssot-audit.md](ssot-audit.md)
---
## 段階的開示・自由度
詳細 → [patterns.md](patterns.md)3段階ローディング、自由度パターン
---
## スキルの種類
### 汎用スキル
どのプロジェクトでも使える。公式ドキュメント・仕様に基づく。
**原則**: プロジェクト固有の実装パターンに依存しない
### プロジェクト固有スキル
特定プロジェクトのワークフロー・データ構造に依存。
**原則**: 依存先を「依存」セクションで明示し、変更時の影響範囲を把握できるようにする
---
## 構造とフロントマター
### ディレクトリ構造
```
skill-name/
├── SKILL.md (必須)
├── scripts/ (任意)
│ └── *.ts / *.sh
└── references/ (任意)
└── *.md
```
### フロントマター
```yaml
---
name: kebab-case64文字以内、小文字・数字・ハイフンのみ
description: 三人称で記述。何をするかトリガーフレーズ3つ以上1024文字以内
---
```
descriptionの書き方・良い例・悪い例 → [exemplar.md](exemplar.md)descriptionの書き方
---
## コード vs プロンプトの判断
スキルの処理を **scripts/ のコード** で実装するか、**SKILL.md のプロンプト指示** に任せるか。
| コードを書くscripts/ | プロンプトで指示するSKILL.md |
|--------------------------|--------------------------------|
| 決定的(毎回同じ結果が必要) | 創造的・文脈依存 |
| ファイルシステム操作(再帰削除、ツリー構築) | コンテンツ生成・判断 |
| 外部ツール連携git, gh, surge | コードレビュー・分析 |
| 状態管理(フラグファイル、タイムスタンプ) | 対話的ワークフロー |
| スキーマに基づくファイル生成 | 自然言語の出力 |
### コード作成時の規約
- **TypeScript**: Bun で実行。`pnpm` スクリプト経由で呼び出す(直接実行禁止)
- **Bash**: 標準Unixツールのみ。`bash path/to/script.sh` で実行
- SKILL.md にはスクリプトの**目的・実行方法・出力**を記載(実装詳細は書かない)
スクリプト品質の原則と具体例 → [exemplar.md](exemplar.md)(スクリプトの品質)
---
## コンテンツガイドライン
禁止事項・サイズ目安 → [patterns.md](patterns.md)(アンチパターン、サイズ目安)

View File

@ -0,0 +1,259 @@
# SSoT 監査ガイド
スキル作成・更新時に必ず実行する SSoTSingle Source of Truth監査の手順。**この監査を通過するまでスキルを完成扱いにしない。**
## 目次
- SSoT 違反とは
- 違反パターンと修正方法
- 監査手順
- 判断に迷うケース
- ハードコード・不整合レビュー
---
## SSoT 違反とは
**同じ情報が2箇所以上に存在し、片方を更新しても他方が古いまま残るリスクがある状態。**
スキルにおける SSoT 違反は2つの場面で発生する:
1. **スキル内部**: SKILL.md と references/ の間で情報が重複
2. **スキル ↔ 外部**: スキルが参照するファイル(スキーマ、設定、コード)の情報をスキル内にコピー
---
## 違反パターンと修正方法
### パターン1: スキーマ・設定のコピー
```markdown
# 違反
## 出力形式
JSONは以下の構造:
- name: string (必須)
- age: number (任意)
- email: string (必須)
# 正解
## 出力形式
SSoT: `path/to/schema.ts` の型定義を参照
```
### パターン2: ルール一覧の転記
```markdown
# 違反
## バリデーション
以下のルールでチェック:
1. nameは3文字以上
2. emailは@を含む
3. ageは0以上
# 正解
## バリデーション
SSoT: `path/to/validator.ts` のバリデーションルールに従う
```
### パターン3: SKILL.md と references/ の重複
```markdown
# 違反
SKILL.md に品質チェックリストを書き、references/exemplar.md にも同じリストがある
# 正解
チェックリストは exemplar.md のみに記載。SKILL.md は「品質チェック → exemplar.md」と参照
```
### パターン4: 他スキルとの重複
```markdown
# 違反
スキルAとスキルBの両方に同じデプロイ手順を記載
# 正解
共通手順を共有リファレンスに置き、両方から参照
```
---
## 監査手順
スキルの作成・更新が完了したら、以下の全ステップを実行する。
### Step 1: 情報ソースの列挙
スキルが参照する外部ファイルを全て列挙する:
- スキーマファイル(.ts, .json
- 設定ファイル
- 他のスキルの references/
- プロジェクトのドキュメント
### Step 2: スキル内コンテンツの監査
SKILL.md と references/ 内の**各テーブル・リスト・コードブロック**について問う:
**「この情報の真のソース(原本)はどこか?」**
- **スキル内が原本** → Step 3 へ
- **スキル外に原本がある** → 違反。参照に置き換える
### Step 3: 重複の検索
スキル内が原本の情報について、プロジェクト内に同じ情報がないか確認:
```bash
grep -r "キーワード" --include="*.md" --include="*.ts" --include="*.json"
```
重複が見つかったら:
- どちらを原本にするか決定
- もう片方を参照に置き換え
### Step 4: スキル内部の重複チェック
SKILL.md と references/ の間で同じ情報が書かれていないか確認:
- SKILL.md に書いた内容が references/ にもないか
- references/ の複数ファイルに同じ情報がないか
### Step 5: 最終確認
以下を全て満たすことを確認:
- [ ] スキル内の全テーブル・リストが「このスキルでしか定義されていない情報」のみを含む
- [ ] 外部ファイルの情報をスキル内にコピーしていない
- [ ] SKILL.md と references/ の間に重複がない
- [ ] references/ の複数ファイル間に重複がない
---
## 判断に迷うケース
### 「要約」は許されるか?
**原則: 方向性を示す一文は許容。詳細リストのコピーは禁止。**
```markdown
# OK: 方向性だけ示して参照
## 概要
核心原則に基づいてスキルを設計する。
詳細 → references/principles.md
# NG: リストのコピー(要約に見せかけた重複)
## 概要
原則:
- 洗練: 公式ドキュメントに基づく
- 簡潔性: 必要最小限の情報
- SSoT: 情報は1箇所のみ
```
判断基準: **「参照先が変更された時、この記述も更新が必要か?」**
- Yes → SSoT 違反。参照に置き換える
- No → 許容
### テーブルの一部引用は?
**禁止。** テーブルの一部でも、元テーブルに行が追加された時に古くなる。
```markdown
# NG: 一部引用
主要なイベント: afterFileEdit, stop全一覧は references/ を参照)
# OK: 参照のみ
イベント一覧 → references/events.md
```
### 「例」としての引用は?
**形式の例示は1つだけ許容。内容の列挙は禁止。**
```markdown
# OK: 形式を1つだけ示す
フロントマターの例:
---
name: my-skill
description: ...
---
詳細な書き方 → exemplar.md
# NG: 複数パターンの列挙(内容のコピー)
良い例:
- feat(認証): メールアドレスでのログイン機能を追加
- fix(決済): 税率計算の誤りを修正
悪い例:
- バグを修正
- 対応
```
---
## ハードコード・不整合レビュー
SSoT 監査(上記 Step 1〜5が「情報のコピー」を検出するのに対し、このレビューは **ハードコードされた詳細****暗黙的な依存** を検出する。SSoT 監査を通過したスキルに対して追加で実行する。
### チェック1: ハードコードされた詳細情報
参照先を読めばわかる**具体的な値・構造・手順**がスキル内に直接書かれていないか確認する。
**検出対象**:
- ディレクトリ構造の展開(ツリー表示)
- 設定値・パラメータの列挙
- 外部ツールのコマンドオプション一覧
- スキーマのフィールド名・型の網羅的リスト
- ファイルパスの詳細な列挙
**判断基準**: 「この詳細が変更されたとき、スキルを手動で更新する必要があるか?」
- Yes → 参照に置き換えるか、方向性のみの記述に変更
- No → 許容
```markdown
# NG: ディレクトリ構造をハードコード
## 出力先
contents/
├── 講義/
│ └── Nヶ月目/第N回/
│ ├── meta.json
│ ├── slides.json
│ └── script.md
# OK: 参照先を示す
## 出力先
`contents/講義/` 配下に、実際のディレクトリ構造に従って配置する。
```
### チェック2: 参照先変更時の不整合リスク
スキル内の記述が参照先の内容に**暗黙的に依存**していないか確認する。コピーではないが、参照先の更新により事実と乖離するリスクのある記述を検出する。
**検出対象**:
- 参照先の件数に依存する表現「3つの原則」「5つのステップ」
- 参照先の内容を要約した記述(要約は参照先が変われば古くなる)
- 参照先の特定ステップ名・ラベルをインラインで使った記述
**判断基準**: 「参照先のファイルが更新されたとき、この記述はまだ正確か?」
- 不確実 → 参照先に依存しない表現に書き換える
- 常に正確 → 許容
```markdown
# NG: 参照先の個数に暗黙的に依存
3つの核心原則に基づいてスキルを設計する。
→ 原則が追加・削除されたら不正確になる
# OK: 個数に依存しない
核心原則に基づいてスキルを設計する。
詳細 → references/principles.md
```
### レビュー最終確認
以下を全て満たすことを確認:
- [ ] スキル内にディレクトリ構造・スキーマ・設定値のベタ書きがない
- [ ] 参照先の件数・名前に依存する表現がない
- [ ] 参照先が更新されてもスキル内の記述が正確なままである

View File

@ -0,0 +1,218 @@
---
name: creating-visual-explainers
description: Generates an illustrated HTML page about any topic and deploys it to surge.sh. Triggered by requests like "図解を作って", "図解を生成して", "このトピックを図解して", or "図解してデプロイして".
---
# Creating Visual Explainers
任意のトピックについて、前提知識がなくても理解できる図解HTMLを生成し、surge.shに公開する。品質基準は「入社したての新卒社会人が読んでも腹落ちする明快さ」だが、この基準は出力には表示しない。
## 依存
- `references/base.html` — 図解テンプレートTailwind CSS CDN・Lucide Icons CDN・ADS配色を含む「額縁」
- `references/model-answer.html` — 模範回答品質基準・デザインパターンの実例。base.htmlと同一の額縁を含む完全なHTMLファイル
## ワークフロー
### Step 0: 前提確認
`references/base.html` が存在するか確認する。
存在しない場合、以下を伝えて終了:
> テンプレートファイルが見つかりません。スキルのフォルダ構成が壊れている可能性があります。運営に連絡してください。
### Step 1: 模範回答の読み込み
`references/model-answer.html` を読み、以下を把握する:
- 完成品の品質水準
- デザインパターン(色使い・余白・カード・フロー図などの視覚表現)
- Tailwind CSSクラスの使い方
- Lucide Iconsの使い方
- コンテンツの構成・情報量・説明の深さ
模範回答がデザインガイドラインの代わりになる。パーツ一覧やルールではなく、実物から読み取る。
### Step 2: テンプレートの読み込み
`references/base.html` を読み、額縁の構造を把握する:
- `<!-- CONTENT_START -->``<!-- CONTENT_END -->` のプレースホルダー位置
- `<!-- TITLE -->`, `<!-- DESCRIPTION -->` のプレースホルダー
- ADS配色のTailwind設定
- 読み込み済みのCDNTailwind CSS・Lucide Icons
### Step 3: ウェブで情報収集
トピックについてウェブ検索を行い、正確かつ最新の情報を収集する。
検索は **2〜3回** に絞る。以下の観点でクエリを組み立てる:
1. **正確な定義**: トピックの公式な定義、公式ドキュメントの説明
2. **最新動向**: 直近の変更点、アップデート、現在のベストプラクティス
3. **具体例**: 実際の使われ方、初心者に伝わるたとえに使える事例
検索結果から以下を整理し、Step 4 の参考情報とする:
- トピックの正確な定義検索結果を優先。AIの学習データだけに頼らない
- 最近変わった点があれば、それを明記する
- たとえ話に使えそうな事例や数字
- **出典URL**: 図解に採用した情報のソースURLを控えておくStep 4 でインライン出典に使う)
### Step 4: コンテンツ生成
Step 3 で収集した情報をもとに、図解HTMLを生成する。検索結果で得た定義・事実・具体例を優先的に採用する。
模範回答のデザインを参考にしつつ、Tailwindの語彙で自由にレイアウトを組む。模範回答のパターンに合うものはそのまま使い、合わないものはTailwindクラスでその場で作る。テンプレートの定義済みパーツに縛られない。
### Step 5: ファイル作成
1. `output/` ディレクトリがなければ作成する
2. トピックに関連する短い英単語のスラッグを決める(例: `api-basics`, `git-rebase`
3. `references/base.html``output/{スラッグ}.html` にコピーする
4. コピーしたファイル内のプレースホルダーをすべて置換する:
- `<!-- TITLE -->` → 図解のタイトル
- `<!-- DESCRIPTION -->` → 内容を要約した1文
- `<!-- CONTENT_START -->``<!-- CONTENT_END -->` → Step 4で生成したコンテンツ
5. ファイルを保存する(ブラウザで開くのは Step 6 のデプロイ後に行う。ローカルでは開かない)
### Step 6: 公開
ファイル保存後、公開する前にまず Node.js の有無を確認する。
```bash
node --version
```
バージョン番号が表示された → そのまま「公開の実行」に進む。
`command not found` と表示された → `references/node-install-guide.md` の手順に従ってNode.jsのインストールを案内する。
#### 公開の実行
以下のスクリプトを**実行する**(中身を読む必要はない)。
**macOS / Git BashWindowsの場合:**
```bash
bash .claude/skills/creating-visual-explainers/scripts/deploy-diagram.sh output/{スラッグ}.html [スラッグ]
```
**WindowsPowerShellで bash が使えない場合:**
```powershell
npx --yes surge output/{スラッグ}.html --domain diagram-[スラッグ].surge.sh
```
スラッグにはトピックに関連する短い英単語を指定する(例: `git-rebase`, `api-basics`)。
#### 初回の場合Surge未登録
ターミナルにメールアドレスとパスワードの入力を求められる。以下を伝える:
> 初回のみアカウント登録が必要です。
> メールアドレスを入力して Enter → パスワードを決めて入力して Enter。
> 確認メールが届いたらリンクをクリックすれば登録完了です。
> 次回以降はこの手順は不要です。
#### エラーが出た場合
エラーメッセージをそのまま見せず、**何が起きていて何をすれば解決するか**を、専門用語を避けて平易に説明する。
よくあるエラーと対応:
- **`npx: command not found`** — Node.js がまだ入っていない。`references/node-install-guide.md` の手順を案内する
- **`surge: not found` / surge関連エラー** — `npm install -g surge` を実行してから再度試す
- **認証エラー / `Login required`**`npx surge login` を実行してメールアドレスとパスワードを入力する
- **その他** — エラーの内容を読み、「何が問題で」「次に何をすればいいか」を平易に説明する
### 図解の削除
ユーザーが「この図解を削除して」と依頼した場合:
1. `deploy-history.log` を読み、直近のデプロイURLを特定する
- ログが存在しない場合 → ユーザーに削除したいURLを聞く
2. `npx surge teardown [ドメイン]` を実行する
3. 削除完了をユーザーに伝える
### Step 7: 完了報告
#### 公開に成功した場合
```
完成・公開完了: 【図解のタイトル】
図解の内容を1〜2文で要約
公開URL:
https://diagram-スラッグ.surge.sh
図解の主なポイント:
- 主要トピックを3〜5個
この図解を削除したいとき:
チャット欄で「この図解を削除して」と伝えてください。
```
#### 公開できなかった場合
```
完成: 【図解のタイトル】
図解の内容を1〜2文で要約
ファイルの保存先:
output/{スラッグ}.htmlブラウザにドラッグドロップすると表示できます
図解の主なポイント:
- 主要トピックを3〜5個
URLで共有したいとき:
チャット欄で「この図解を公開して」と伝えてください。
```
## 守ること(禁止事項)
- **React・shadcn/ui を使わない** — 静的な図解にJSフレームワークは不要。AIの出力を制限し、モデルによる品質差も限定的にしてしまう
- **絵文字を使わない** — OS依存で表示が変わる。アイコンはLucide Iconsを使う
- **インタラクティブ要素を入れない** — トグル、フェードイン、アニメーション、フォーム、クリックで開閉する要素は一切禁止
- **`<style>` タグを追加しない** — スタイリングはTailwind CSSクラスで行う。インラインの `style` 属性も避ける
- **`<script>` を追加しない** — テンプレートに含まれるもの以外のJavaScriptは禁止
- **外部リソースを追加しない** — テンプレートに含まれるCDN以外の外部読み込み画像URL・フォント・追加CDNは禁止
- **テンプレートの額縁構造を変更しない**`<head>`・CDN読み込み・meta タグはそのまま維持する
- **PDF印刷で消える表現を使わない**`bg-clip-text text-transparent` によるグラデーション文字はPDF出力時に透明のまま消える。テンプレートの print CSS でフォールバックを入れているが、グラデーション文字を使った場合はPDF出力で色が単色`#2563EB`)に変わる点を意識すること
## コンテンツ生成の指針
- **概論 → 各論** — いきなり詳細に入らない。全体像を見せてから個別の話に入る
- **専門用語は初出で必ず解説** — 「APIApplication Programming Interfaceソフトウェア同士がやり取りするための窓口」のように、括弧書きで平易に説明する
- **たとえ話で身近な体験に結びつける** — レストランの注文、郵便配達、信号機など、技術を知らない人でもイメージできる例を使う
- **簡潔にまとめすぎない** — 理解に必要な情報量は削らない。腹落ちするまで丁寧に説明する
- **図を早く見せる** — 見出しから最初のビジュアルまでに、テキストは最大2段落各2〜3行。それ以上の説明が必要な場合は、図を先に見せてから図の後にテキストで補足する図→説明の順。「説明してから図を見せる」より「図を見せてから説明する」方が、同じ文量でも「読まされている感」がなくなる。テキストで述べたたとえ話ゲーム、レストラン等も、テキストだけで済まさずミニビジュアル化を検討する
- **「見たことがあるもの」は説明するのではなく見せる** — 図解の中で読者がすでに体験しているものアプリの画面、ツールのUI、Webサイトに言及するとき、テキストで「〜という画面が表示されます」と書く代わりに、その画面自体をTailwind CSSで再現して配置する。「天気アプリの画面」なら天気アプリのモックアップを、「チャット画面」ならチャットUIを、「ターミナル」ならターミナルウィンドウを見せる。読者の「見たことある」という記憶が発火する瞬間が、テキスト説明より圧倒的に理解を深める
- **ビジュアルには2つの役割がある** — 図解に使うビジュアルは「構造を示す図」と「体験を再現する図」の2種類。どちらか一方ではなく、両方を組み合わせて使う:
- **構造パターン(仕組みを頭で理解する図)** — 知識の種類に応じて選ぶ:
- **「Xとは何か」(定義)** → アナロジー図: 身近なたとえの登場人物を配置し、矢印で関係を示す。主役を中央に大きく
- **「Xはどう動くか」(プロセス)** → ステップフロー: 番号つき横並び(モバイルは縦)。各ステップにアイコン+一言。色はステップごとに変える
- **「XとYの違い」(比較)** → 左右対比: 2カラムで並べ、同じ観点を同じ行に揃える。✗/✓ や赤/緑で差を一目で伝える
- **「Xの具体例」(事例)** → カードグリッド: 2列のカードにアイコンタイトル説明。カード内で「表の顔」と「裏の仕組み」を分けると深みが出る
- **「Xのすごさ」(数値)** → 数字カード: 3カラムに大きな数字。text-3xl font-black で存在感を出し、色を各数字で変える
- **「Xの構造・中身」(階層)** → 入れ子ブロック: 外側の大きなブロック内に構成要素を配置。ボーダーや背景色の濃淡で階層を表現
- **「Xの誤解」(訂正)** → 誤解→正解カード: 赤ヘッダーに誤解、本文に緑で正解。✗と✓の対比
- **「Xの変遷」(時系列)** → タイムライン: 左にボーダーライン、各時点に年号・ラベル・要約。色のグラデーションで時代の変化を表現
- **体験再現パターン(読者の「見たことある」記憶と結びつける図)** — 読者が実際に触れたことのある画面をTailwind CSSで再現する。「あなたが見ているもの」「〜の画面では」「実際に使うとき」のような文脈が出てきたら、テキスト説明ではなくこちらを使う:
- **チャットUI** — 吹き出し形式の対話画面。暗い背景ユーザー吹き出し右寄せAI吹き出し左寄せ入力欄モック
- **エディタUI** — タイトルバー赤黄緑ボタンサイドバーファイルツリーコードペイン。AIチャットパネルを加えた3ペインも可
- **ターミナルUI** — タイトルバー(赤黄緑ボタン)+プロンプト($)+コマンド+出力。コードブロックとの違いはウィンドウ枠がある点
- **ブラウザUI** — タイトルバー(赤黄緑ボタン)+アドレスバー+ページ内容
- **アプリ画面** — 上記に当てはまらないアプリ(天気予報、地図、決済画面など)。角丸カード内にアイコン+数値+ラベルでミニ画面を再現
- 共通ルール: 中身はリアルすぎず要点が伝わるミニマルな内容にする。特定ブランドのロゴや名称は使わず汎用的な表現にする。Tailwind CSSクラスのみで構成する
- **冒頭にヒーロー+一枚絵サマリー** — タイトルで「何の図解か」を伝えたあと、そのままトピックの核心を1枚の図で見せる。ヒーローの説明文を図への導入「ひとことで言えば──」のような引きにし、図の直後に各論への橋渡し「ここからひとつずつ解説していきます」を置く。ヒーロー → 一言の答え → 図 → 各論が一本の流れになること。一枚絵サマリーの構成:
- **一言の答え**: トピックの核心を1文で太字表示カード冒頭。読者が「なるほど」と思える定義を先に読ませ、そのあとの図で視覚的に裏付ける
- **コア図解**: 一言の答えを図にしたもの。アイコン+矢印+ラベルで表現
- **身近な接点**: 読者がすでに体験している具体例を、アイコン一言のピルで2〜4個並べる
- **読者のレベルに言及しない** — 「初心者向け」「入門」「未経験者でもわかる」のように読者を特定のレベルにラベリングする表現をタイトル・見出し・本文に入れない。「わかりやすく説明する」のは図解の品質であって、読者のレベルではない。たとえ話や専門用語の解説で自然に噛み砕けば、ラベルなしで誰にでも伝わる
- **ヒーローバッジはトピックカテゴリ** — タイトル上のバッジには、トピックのカテゴリを入れる(テクノロジー、ビジネス、開発ツール、デザイン、マーケティングなど)。「初心者向け」「入門」など読者のレベルを示すラベルは入れない
- **インライン出典** — 検索結果から採用した事実・定義・数字のすぐ近くに、出典リンクをさりげなく添える。本文の読みやすさを損なわないよう `text-xs text-ads-dim` で小さく薄く表示し、リンクテキストはURLそのままではなく「出典: ○○公式ドキュメント」のようにページ内容がわかる名前にする。段落末やカード下部など、視線の流れを邪魔しない位置に置く
- **日本語で** — 英語メインのトピックでも、図解は日本語で書く

View File

@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex, nofollow, noarchive, nosnippet, noimageindex">
<meta name="googlebot" content="noindex, nofollow">
<meta property="og:title" content="<!-- TITLE -->">
<meta property="og:description" content="<!-- DESCRIPTION -->">
<meta property="og:type" content="article">
<title><!-- TITLE --></title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='20' fill='%23FFFFFF'/><rect x='8' y='8' width='84' height='84' rx='14' fill='none' stroke='%233B82F6' stroke-width='4'/><circle cx='32' cy='40' r='10' fill='%233B82F6' opacity='0.8'/><circle cx='68' cy='40' r='10' fill='%2360A5FA' opacity='0.8'/><rect x='25' y='62' width='50' height='6' rx='3' fill='%2394A3B8' opacity='0.6'/><rect x='30' y='74' width='40' height='6' rx='3' fill='%2394A3B8' opacity='0.3'/></svg>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700;900&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
ads: {
bg: '#FFFFFF',
surface: '#F8FAFC',
hover: '#F1F5F9',
border: '#E2E8F0',
accent: '#3B82F6',
'accent-light': '#2563EB',
text: '#1E293B',
muted: '#64748B',
dim: '#94A3B8',
positive: '#10B981',
negative: '#EF4444',
warning: '#F59E0B',
}
},
fontFamily: {
sans: ['"Noto Sans JP"', '"Hiragino Sans"', '"Hiragino Kaku Gothic ProN"', '"Yu Gothic UI"', '"Meiryo"', 'sans-serif'],
}
}
}
}
</script>
<style>
@media print {
.no-print { display: none !important; }
body { border-top: none !important; }
.rounded-xl { break-inside: avoid; }
.md\:flex-row { flex-direction: row !important; }
.md\:hidden { display: none !important; }
.hidden.md\:block { display: block !important; }
.md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
.sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
.md\:mb-20 { margin-bottom: 5rem !important; }
.md\:py-16 { padding-top: 4rem !important; padding-bottom: 4rem !important; }
.bg-clip-text.text-transparent {
-webkit-background-clip: initial !important;
background-clip: initial !important;
color: #2563EB !important;
-webkit-text-fill-color: #2563EB !important;
}
}
</style>
</head>
<body class="bg-ads-bg text-slate-600 antialiased leading-relaxed border-t-4 border-ads-accent">
<div class="no-print max-w-3xl mx-auto px-5 pt-2 flex justify-end">
<button onclick="window.print()" class="flex items-center gap-1.5 text-xs text-ads-dim hover:text-ads-accent transition-colors cursor-pointer">
<i data-lucide="download" class="w-3.5 h-3.5"></i>
PDF
</button>
</div>
<main class="max-w-3xl mx-auto px-5 py-10 md:py-16">
<!-- CONTENT_START -->
<!-- CONTENT_END -->
</main>
<footer class="max-w-3xl mx-auto px-5 pb-10 pt-6 border-t border-ads-border/30">
<p class="text-xs text-ads-dim text-center">AI-Driven School の図解ツールで作成</p>
</footer>
<script src="https://unpkg.com/lucide@latest"></script>
<script>lucide.createIcons();</script>
</body>
</html>

View File

@ -0,0 +1,968 @@
<!-- このファイルの<head>はreferences/base.htmlと同一に保つ。base.html変更時は必ずこちらも更新する -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex, nofollow, noarchive, nosnippet, noimageindex">
<meta name="googlebot" content="noindex, nofollow">
<meta property="og:title" content="APIの仕組み">
<meta property="og:description" content="APIの仕組みを、身近な例とビジュアルでわかりやすく図解します。">
<meta property="og:type" content="article">
<title>APIの仕組み</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='20' fill='%23FFFFFF'/><rect x='8' y='8' width='84' height='84' rx='14' fill='none' stroke='%233B82F6' stroke-width='4'/><circle cx='32' cy='40' r='10' fill='%233B82F6' opacity='0.8'/><circle cx='68' cy='40' r='10' fill='%2360A5FA' opacity='0.8'/><rect x='25' y='62' width='50' height='6' rx='3' fill='%2394A3B8' opacity='0.6'/><rect x='30' y='74' width='40' height='6' rx='3' fill='%2394A3B8' opacity='0.3'/></svg>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700;900&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
ads: {
bg: '#FFFFFF',
surface: '#F8FAFC',
hover: '#F1F5F9',
border: '#E2E8F0',
accent: '#3B82F6',
'accent-light': '#2563EB',
text: '#1E293B',
muted: '#64748B',
dim: '#94A3B8',
positive: '#10B981',
negative: '#EF4444',
warning: '#F59E0B',
}
},
fontFamily: {
sans: ['"Noto Sans JP"', '"Hiragino Sans"', '"Hiragino Kaku Gothic ProN"', '"Yu Gothic UI"', '"Meiryo"', 'sans-serif'],
}
}
}
}
</script>
<style>
@media print {
.no-print { display: none !important; }
body { border-top: none !important; }
.rounded-xl { break-inside: avoid; }
.md\:flex-row { flex-direction: row !important; }
.md\:hidden { display: none !important; }
.hidden.md\:block { display: block !important; }
.md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
.sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
.md\:mb-20 { margin-bottom: 5rem !important; }
.md\:py-16 { padding-top: 4rem !important; padding-bottom: 4rem !important; }
.bg-clip-text.text-transparent {
-webkit-background-clip: initial !important;
background-clip: initial !important;
color: #2563EB !important;
-webkit-text-fill-color: #2563EB !important;
}
}
</style>
</head>
<body class="bg-ads-bg text-slate-600 antialiased leading-relaxed border-t-4 border-ads-accent">
<div class="no-print max-w-3xl mx-auto px-5 pt-2 flex justify-end">
<button onclick="window.print()" class="flex items-center gap-1.5 text-xs text-ads-dim hover:text-ads-accent transition-colors cursor-pointer">
<i data-lucide="download" class="w-3.5 h-3.5"></i>
PDF
</button>
</div>
<main class="max-w-3xl mx-auto px-5 py-10 md:py-16">
<!-- CONTENT_START -->
<!-- ============================================================ -->
<!-- HERO -->
<!-- ============================================================ -->
<div class="text-center mb-8 md:mb-10">
<div class="inline-flex items-center gap-2 bg-ads-accent/10 text-ads-accent-light px-4 py-1.5 rounded-full text-sm font-medium mb-6">
<i data-lucide="cpu" class="w-4 h-4"></i>
テクノロジー
</div>
<h1 class="text-3xl md:text-5xl font-black text-slate-900 tracking-tight mb-6">
<span class="bg-gradient-to-r from-blue-600 to-cyan-600 bg-clip-text text-transparent">API</span>の仕組み
</h1>
<p class="text-lg text-ads-muted max-w-xl mx-auto leading-relaxed">
「APIって何」と聞かれて、うまく答えられない。<br>
ひとことで言うと ──
</p>
</div>
<!-- ============================================================ -->
<!-- ONE-PAGE SUMMARY -->
<!-- ============================================================ -->
<div class="bg-ads-surface border border-ads-border rounded-2xl p-6 md:p-10 mb-6">
<div class="text-center mb-8 md:mb-10">
<p class="text-xl md:text-2xl font-black text-slate-900 mb-2">
API = ソフトウェアの<span class="text-ads-accent-light">「注文窓口」</span>
</p>
<p class="text-sm text-ads-muted">
中身を知らなくても、決まった形で頼めば結果が届く
</p>
</div>
<!-- Core flow: App → API → Server -->
<div class="flex flex-col md:flex-row items-center justify-center gap-2 md:gap-0 mb-8">
<!-- App -->
<div class="flex flex-col items-center w-36 p-3">
<div class="w-14 h-14 rounded-xl bg-blue-500/10 border border-blue-500/20 flex items-center justify-center mb-2.5">
<i data-lucide="smartphone" class="w-7 h-7 text-blue-600"></i>
</div>
<div class="font-bold text-slate-900 text-sm">あなたのアプリ</div>
<div class="text-[11px] text-blue-600/70 mt-0.5">「天気を教えて」</div>
</div>
<!-- Arrow 1: Request -->
<div class="flex items-center justify-center md:w-16 py-1 md:py-0">
<div class="flex flex-col items-center gap-0.5">
<span class="text-[9px] font-medium text-ads-accent tracking-wider">リクエスト</span>
<i data-lucide="arrow-right" class="w-5 h-5 text-ads-accent hidden md:block"></i>
<i data-lucide="arrow-down" class="w-5 h-5 text-ads-accent md:hidden"></i>
</div>
</div>
<!-- API (centerpiece — visually prominent) -->
<div class="flex flex-col items-center w-40 p-4 bg-ads-accent/5 border-2 border-ads-accent/20 rounded-2xl">
<div class="w-16 h-16 rounded-2xl bg-ads-accent/15 border-2 border-ads-accent/30 flex items-center justify-center mb-2.5">
<i data-lucide="arrow-left-right" class="w-8 h-8 text-ads-accent-light"></i>
</div>
<div class="font-bold text-ads-accent-light text-base">API</div>
<div class="text-[11px] text-ads-muted mt-0.5 mb-2">注文を届け、結果を返す</div>
<div class="text-[10px] text-ads-muted bg-white rounded-lg px-2.5 py-1 border border-ads-border/50">レストランのウェイター役</div>
</div>
<!-- Arrow 2: Forward to server -->
<div class="flex items-center justify-center md:w-16 py-1 md:py-0">
<div class="flex flex-col items-center gap-0.5">
<span class="text-[9px] font-medium text-ads-accent tracking-wider">依頼</span>
<i data-lucide="arrow-right" class="w-5 h-5 text-ads-accent hidden md:block"></i>
<i data-lucide="arrow-down" class="w-5 h-5 text-ads-accent md:hidden"></i>
</div>
</div>
<!-- Server -->
<div class="flex flex-col items-center w-36 p-3">
<div class="w-14 h-14 rounded-xl bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center mb-2.5">
<i data-lucide="server" class="w-7 h-7 text-emerald-600"></i>
</div>
<div class="font-bold text-slate-900 text-sm">サービス</div>
<div class="text-[11px] text-emerald-600/70 mt-0.5">処理して結果を返す</div>
</div>
</div>
<!-- Return flow -->
<div class="flex justify-center mb-8">
<div class="flex items-center gap-2 text-xs text-emerald-600 bg-emerald-500/5 border border-emerald-500/15 rounded-full px-4 py-1.5">
<i data-lucide="corner-down-left" class="w-3.5 h-3.5"></i>
結果(レスポンス)があなたのアプリに届く
</div>
</div>
<!-- Divider with label -->
<div class="flex items-center gap-4 mb-6">
<div class="flex-1 border-t border-ads-border/50"></div>
<div class="text-[11px] text-ads-dim font-medium">あなたも毎日使っている</div>
<div class="flex-1 border-t border-ads-border/50"></div>
</div>
<!-- Everyday examples as pills -->
<div class="flex flex-wrap justify-center gap-2 mb-8">
<div class="flex items-center gap-1.5 bg-white border border-ads-border rounded-full px-3.5 py-1.5 text-xs text-slate-700">
<i data-lucide="cloud" class="w-3.5 h-3.5 text-cyan-500"></i>
天気予報
</div>
<div class="flex items-center gap-1.5 bg-white border border-ads-border rounded-full px-3.5 py-1.5 text-xs text-slate-700">
<i data-lucide="log-in" class="w-3.5 h-3.5 text-blue-500"></i>
Googleログイン
</div>
<div class="flex items-center gap-1.5 bg-white border border-ads-border rounded-full px-3.5 py-1.5 text-xs text-slate-700">
<i data-lucide="credit-card" class="w-3.5 h-3.5 text-emerald-500"></i>
オンライン決済
</div>
<div class="flex items-center gap-1.5 bg-white border border-ads-border rounded-full px-3.5 py-1.5 text-xs text-slate-700">
<i data-lucide="map-pin" class="w-3.5 h-3.5 text-red-500"></i>
地図・ナビ
</div>
</div>
</div>
<p class="text-center text-ads-muted mb-16 md:mb-20">
ここから先で、この仕組みをひとつずつ丁寧に解説していきます。
</p>
<!-- ============================================================ -->
<!-- SECTION 1: そもそもAPIって何 -->
<!-- ============================================================ -->
<section class="mb-16 md:mb-20">
<div class="flex items-center gap-3 mb-8">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-blue-500/10 flex-shrink-0">
<i data-lucide="help-circle" class="w-5 h-5 text-blue-600"></i>
</div>
<h2 class="text-xl md:text-2xl font-bold text-slate-900">そもそもAPIって何</h2>
</div>
<p class="mb-6 leading-relaxed">
APIエーピーアイ<strong class="text-slate-900">Application Programming Interface</strong>(アプリケーション・プログラミング・インターフェース)の略称です。正式名称を聞いても「何のこと?」と思いますよね。
</p>
<p class="mb-6 leading-relaxed">
まずは日常のたとえで考えてみましょう。レストランに行った場面を想像してください。
</p>
<p class="mb-8 leading-relaxed">
あなた(お客さん)は、厨房に直接入って料理を作ることはできません。厨房のルールも、調理器具の使い方も知りません。でも、<strong class="text-slate-900">ウェイターに「パスタをください」と注文すれば、厨房で作られた料理があなたのテーブルに届きます。</strong>厨房の中で何が起きているかを知る必要はありません。
</p>
<!-- レストラン比喩フロー図 -->
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 md:p-8 mb-8">
<h3 class="text-lg font-bold text-slate-900 text-center mb-8">レストランで考えるAPIの役割</h3>
<div class="flex flex-col md:flex-row items-center justify-center gap-4 md:gap-0">
<!-- あなた(お客さん) -->
<div class="w-44 bg-blue-500/10 border border-blue-500/20 rounded-xl p-5 text-center">
<div class="w-12 h-12 rounded-full bg-blue-500/20 flex items-center justify-center mx-auto mb-3">
<i data-lucide="user" class="w-6 h-6 text-blue-600"></i>
</div>
<div class="font-bold text-blue-700 mb-1">あなた</div>
<div class="text-xs text-blue-600/70">お客さん</div>
<div class="text-xs text-ads-muted mt-3 bg-slate-100/80 rounded-lg px-3 py-1.5">「パスタください」</div>
</div>
<!-- 矢印 1 -->
<div class="flex items-center justify-center md:w-16 py-2 md:py-0">
<div class="flex flex-col items-center gap-1">
<span class="text-[10px] text-ads-muted">注文</span>
<i data-lucide="arrow-right" class="w-5 h-5 text-ads-accent hidden md:block"></i>
<i data-lucide="arrow-down" class="w-5 h-5 text-ads-accent md:hidden"></i>
</div>
</div>
<!-- APIウェイター -->
<div class="w-44 bg-ads-accent/10 border-2 border-ads-accent/30 rounded-xl p-5 text-center">
<div class="w-12 h-12 rounded-full bg-ads-accent/20 flex items-center justify-center mx-auto mb-3">
<i data-lucide="message-square" class="w-6 h-6 text-ads-accent-light"></i>
</div>
<div class="font-bold text-ads-accent-light mb-1">API</div>
<div class="text-xs text-ads-accent/70">ウェイター</div>
<div class="text-xs text-ads-muted mt-3 bg-slate-100/80 rounded-lg px-3 py-1.5">注文を伝え、料理を届ける</div>
</div>
<!-- 矢印 2 -->
<div class="flex items-center justify-center md:w-16 py-2 md:py-0">
<div class="flex flex-col items-center gap-1">
<span class="text-[10px] text-ads-muted">依頼</span>
<i data-lucide="arrow-right" class="w-5 h-5 text-ads-accent hidden md:block"></i>
<i data-lucide="arrow-down" class="w-5 h-5 text-ads-accent md:hidden"></i>
</div>
</div>
<!-- サーバー(厨房) -->
<div class="w-44 bg-emerald-500/10 border border-emerald-500/20 rounded-xl p-5 text-center">
<div class="w-12 h-12 rounded-full bg-emerald-500/20 flex items-center justify-center mx-auto mb-3">
<i data-lucide="server" class="w-6 h-6 text-emerald-600"></i>
</div>
<div class="font-bold text-emerald-700 mb-1">サーバー</div>
<div class="text-xs text-emerald-600/70">厨房</div>
<div class="text-xs text-ads-muted mt-3 bg-slate-100/80 rounded-lg px-3 py-1.5">パスタを作って渡す</div>
</div>
</div>
<div class="flex justify-center mt-6">
<div class="flex items-center gap-2 text-ads-muted text-sm">
<i data-lucide="corner-down-left" class="w-4 h-4"></i>
料理(レスポンス)があなたのテーブルに届く
</div>
</div>
</div>
<p class="mb-6 leading-relaxed">
この比喩がAPIの本質をほぼ言い当てています。あなたアプリは、厨房サーバーの中で何が起きているかを知る必要がありません。ウェイターAPIに決まった形式で注文を伝えれば、結果が返ってくる。これがAPIです。
</p>
<!-- ポイントボックス -->
<div class="bg-ads-accent/5 border border-ads-accent/20 rounded-xl p-5">
<div class="flex items-start gap-3">
<div class="flex items-center justify-center w-8 h-8 rounded-lg bg-ads-accent/10 flex-shrink-0 mt-0.5">
<i data-lucide="lightbulb" class="w-4 h-4 text-ads-accent-light"></i>
</div>
<div>
<p class="font-bold text-ads-accent-light mb-1">ここがポイント</p>
<p class="text-ads-muted leading-relaxed">
APIは<strong class="text-slate-800">「仲介役」</strong>です。相手の内部構造を知らなくても、<strong class="text-slate-800">決まったルールで話しかければ結果が返ってくる</strong>。これがAPIの本質です。この「決まったルール」のことを、エンジニアは「インターフェースInterface」と呼びます。
</p>
</div>
</div>
</div>
</section>
<!-- ============================================================ -->
<!-- SECTION 2: もう少し正確に言うと -->
<!-- ============================================================ -->
<section class="mb-16 md:mb-20">
<div class="flex items-center gap-3 mb-8">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-purple-500/10 flex-shrink-0">
<i data-lucide="search" class="w-5 h-5 text-purple-600"></i>
</div>
<h2 class="text-xl md:text-2xl font-bold text-slate-900">もう少し正確に言うと</h2>
</div>
<p class="mb-6 leading-relaxed">
レストランのたとえで、ざっくりとしたイメージはつかめましたか? ここからもう少しだけ正確に説明します。
</p>
<p class="mb-8 leading-relaxed">
APIとは、ひとことで言えば<strong class="text-slate-900">「ソフトウェア同士が会話するための窓口」</strong>です。あなたが使っているアプリの裏側で、別のサービスのデータや機能を借りてくるための「取り決め」と考えてください。
</p>
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 mb-8 text-center">
<div class="text-xs text-ads-dim font-medium tracking-widest uppercase mb-3">技術的な定義</div>
<p class="text-lg md:text-xl font-bold text-slate-900 leading-relaxed">
API = あるソフトウェアの機能を、<br class="hidden md:block">
別のソフトウェアから使えるようにする仕組み
</p>
<p class="text-xs text-ads-dim mt-3">出典: <a href="https://developer.mozilla.org/ja/docs/Learn/JavaScript/Client-side_web_APIs/Introduction" class="underline decoration-ads-dim/30 hover:text-ads-accent transition-colors">MDN Web Docs — Web API の紹介</a></p>
</div>
<p class="mb-8 leading-relaxed">
これだけだとまだ抽象的に感じるかもしれません。では、<strong class="text-slate-900">APIがある世界とない世界</strong>を比べてみましょう。
</p>
<!-- Before / After 比較 -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- Before -->
<div class="bg-red-500/5 border border-red-500/20 rounded-xl p-6">
<div class="inline-flex items-center gap-1.5 bg-red-500/10 text-red-600 px-3 py-1 rounded-full text-xs font-bold tracking-wide mb-5">
<i data-lucide="x-circle" class="w-3.5 h-3.5"></i>
BEFORE — APIがない世界
</div>
<ul class="space-y-3">
<li class="flex items-start gap-2.5">
<i data-lucide="x" class="w-4 h-4 text-red-600 mt-1 flex-shrink-0"></i>
<span>天気情報が欲しければ、<strong class="text-red-700">自分で気象観測の仕組み</strong>を構築する</span>
</li>
<li class="flex items-start gap-2.5">
<i data-lucide="x" class="w-4 h-4 text-red-600 mt-1 flex-shrink-0"></i>
<span>決済機能が欲しければ、<strong class="text-red-700">クレジットカード処理を自前で開発</strong>する</span>
</li>
<li class="flex items-start gap-2.5">
<i data-lucide="x" class="w-4 h-4 text-red-600 mt-1 flex-shrink-0"></i>
<span>地図を表示したければ、<strong class="text-red-700">地図データを自分で作成・更新</strong>する</span>
</li>
<li class="flex items-start gap-2.5">
<i data-lucide="x" class="w-4 h-4 text-red-600 mt-1 flex-shrink-0"></i>
<span>ユーザー認証は<strong class="text-red-700">パスワード管理からセキュリティ対策まで全部自前</strong></span>
</li>
</ul>
<div class="mt-5 pt-4 border-t border-red-500/10 text-sm text-red-700/70 flex items-center gap-2">
<i data-lucide="alert-circle" class="w-4 h-4"></i>
膨大な開発コストと時間。バグのリスクも高い。
</div>
</div>
<!-- After -->
<div class="bg-emerald-500/5 border border-emerald-500/20 rounded-xl p-6">
<div class="inline-flex items-center gap-1.5 bg-emerald-500/10 text-emerald-600 px-3 py-1 rounded-full text-xs font-bold tracking-wide mb-5">
<i data-lucide="check-circle" class="w-3.5 h-3.5"></i>
AFTER — APIがある世界
</div>
<ul class="space-y-3">
<li class="flex items-start gap-2.5">
<i data-lucide="check" class="w-4 h-4 text-emerald-600 mt-1 flex-shrink-0"></i>
<span>天気情報は<strong class="text-emerald-700">天気予報APIに問い合わせるだけ</strong>で取得できる</span>
</li>
<li class="flex items-start gap-2.5">
<i data-lucide="check" class="w-4 h-4 text-emerald-600 mt-1 flex-shrink-0"></i>
<span>決済は<strong class="text-emerald-700">Stripe APIに任せれば数行のコード</strong>で完成</span>
</li>
<li class="flex items-start gap-2.5">
<i data-lucide="check" class="w-4 h-4 text-emerald-600 mt-1 flex-shrink-0"></i>
<span>地図は<strong class="text-emerald-700">Google Maps APIで高品質な地図を即表示</strong>できる</span>
</li>
<li class="flex items-start gap-2.5">
<i data-lucide="check" class="w-4 h-4 text-emerald-600 mt-1 flex-shrink-0"></i>
<span>ログインは<strong class="text-emerald-700">GoogleやAppleのAPIで安全に認証</strong>できる</span>
</li>
</ul>
<div class="mt-5 pt-4 border-t border-emerald-500/10 text-sm text-emerald-700/70 flex items-center gap-2">
<i data-lucide="zap" class="w-4 h-4"></i>
「自分が本当に作るべきもの」に集中できる。
</div>
</div>
</div>
</section>
<!-- ============================================================ -->
<!-- SECTION 3: APIの仕組み -->
<!-- ============================================================ -->
<section class="mb-16 md:mb-20">
<div class="flex items-center gap-3 mb-8">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-cyan-500/10 flex-shrink-0">
<i data-lucide="settings" class="w-5 h-5 text-cyan-600"></i>
</div>
<h2 class="text-xl md:text-2xl font-bold text-slate-900">APIの仕組み — リクエストとレスポンス</h2>
</div>
<p class="mb-6 leading-relaxed">
APIでのやり取りは、実はとてもシンプルです。基本は<strong class="text-slate-900">「聞く(リクエスト)」</strong><strong class="text-slate-900">「答える(レスポンス)」</strong>の2つだけ。
</p>
<p class="mb-8 leading-relaxed">
リクエストRequestとは、「こういう情報をください」「この処理をしてください」とAPIに送るメッセージのことです。レスポンスResponseは、APIがその要求に対して返す結果です。この2つのやり取りを分解すると、4つのステップになります。
</p>
<!-- 4ステップフロー図 -->
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 md:p-8 mb-8">
<h3 class="text-lg font-bold text-slate-900 text-center mb-8">APIリクエスト〜レスポンスの流れ</h3>
<div class="flex flex-col md:flex-row items-stretch justify-center gap-3 md:gap-0">
<div class="flex-1 bg-blue-500/10 border border-blue-500/20 rounded-xl p-4 text-center">
<div class="w-8 h-8 rounded-full bg-blue-500 text-white text-sm font-bold flex items-center justify-center mx-auto mb-3">1</div>
<i data-lucide="send" class="w-6 h-6 text-blue-600 mx-auto mb-2"></i>
<div class="font-bold text-blue-700 text-sm mb-1">リクエスト送信</div>
<div class="text-xs text-ads-muted leading-relaxed">あなたのアプリが<br>「こういう情報ください」<br>とAPIに送る</div>
</div>
<div class="flex items-center justify-center md:w-10 py-1 md:py-0">
<i data-lucide="chevron-right" class="w-5 h-5 text-ads-dim hidden md:block"></i>
<i data-lucide="chevron-down" class="w-5 h-5 text-ads-dim md:hidden"></i>
</div>
<div class="flex-1 bg-purple-500/10 border border-purple-500/20 rounded-xl p-4 text-center">
<div class="w-8 h-8 rounded-full bg-purple-500 text-white text-sm font-bold flex items-center justify-center mx-auto mb-3">2</div>
<i data-lucide="shield" class="w-6 h-6 text-purple-600 mx-auto mb-2"></i>
<div class="font-bold text-purple-700 text-sm mb-1">APIが受け取る</div>
<div class="text-xs text-ads-muted leading-relaxed">リクエストの内容を<br>チェック・認証する<br>(門番の役割)</div>
</div>
<div class="flex items-center justify-center md:w-10 py-1 md:py-0">
<i data-lucide="chevron-right" class="w-5 h-5 text-ads-dim hidden md:block"></i>
<i data-lucide="chevron-down" class="w-5 h-5 text-ads-dim md:hidden"></i>
</div>
<div class="flex-1 bg-emerald-500/10 border border-emerald-500/20 rounded-xl p-4 text-center">
<div class="w-8 h-8 rounded-full bg-emerald-500 text-white text-sm font-bold flex items-center justify-center mx-auto mb-3">3</div>
<i data-lucide="database" class="w-6 h-6 text-emerald-600 mx-auto mb-2"></i>
<div class="font-bold text-emerald-700 text-sm mb-1">サーバーが処理</div>
<div class="text-xs text-ads-muted leading-relaxed">データベース検索や<br>計算など、実際の<br>処理を実行する</div>
</div>
<div class="flex items-center justify-center md:w-10 py-1 md:py-0">
<i data-lucide="chevron-right" class="w-5 h-5 text-ads-dim hidden md:block"></i>
<i data-lucide="chevron-down" class="w-5 h-5 text-ads-dim md:hidden"></i>
</div>
<div class="flex-1 bg-amber-500/10 border border-amber-500/20 rounded-xl p-4 text-center">
<div class="w-8 h-8 rounded-full bg-amber-500 text-white text-sm font-bold flex items-center justify-center mx-auto mb-3">4</div>
<i data-lucide="reply" class="w-6 h-6 text-amber-600 mx-auto mb-2"></i>
<div class="font-bold text-amber-700 text-sm mb-1">レスポンス返却</div>
<div class="text-xs text-ads-muted leading-relaxed">処理結果をあなたの<br>アプリに返す<br>(料理が届く瞬間)</div>
</div>
</div>
</div>
<p class="mb-6 leading-relaxed">
言葉だけだとまだピンとこないかもしれません。では、実際のコードで見てみましょう。たとえば、天気予報APIから東京の天気を取得するコードは、たったこれだけです。
</p>
<!-- コード例: JavaScript -->
<div class="mb-6">
<div class="flex items-center gap-2 bg-slate-800 border border-slate-700/50 rounded-t-xl px-4 py-2.5 text-xs text-ads-muted">
<i data-lucide="code" class="w-3.5 h-3.5"></i>
JavaScript — 天気予報APIの呼び出し例
</div>
<pre class="bg-slate-950 border border-slate-700/50 border-t-0 rounded-b-xl p-5 overflow-x-auto text-sm leading-loose"><code><span class="text-slate-500">// 1. APIにリクエストを送る「東京の天気を教えて」と聞く</span>
<span class="text-purple-400">const</span> response <span class="text-slate-400">=</span> <span class="text-purple-400">await</span> <span class="text-blue-400">fetch</span>(<span class="text-emerald-400">"https://api.weather.example.com/current?city=tokyo"</span>);
<span class="text-slate-500">// 2. レスポンスをJSON形式データの構造に変換する</span>
<span class="text-purple-400">const</span> data <span class="text-slate-400">=</span> <span class="text-purple-400">await</span> response.<span class="text-blue-400">json</span>();
<span class="text-slate-500">// 3. 必要なデータを取り出して使う</span>
console.<span class="text-blue-400">log</span>(data.temperature); <span class="text-slate-500">// → "22°C"</span>
console.<span class="text-blue-400">log</span>(data.condition); <span class="text-slate-500">// → "晴れ"</span>
console.<span class="text-blue-400">log</span>(data.humidity); <span class="text-slate-500">// → "65%"</span></code></pre>
</div>
<!-- コード解説 -->
<div class="bg-ads-surface border border-ads-border rounded-xl p-5 mb-8">
<h4 class="text-sm font-bold text-slate-900 mb-4 flex items-center gap-2">
<i data-lucide="file-text" class="w-4 h-4 text-ads-accent"></i>
コードの解説1行ずつ読み解く
</h4>
<div class="space-y-4 text-sm">
<div class="flex items-start gap-3">
<span class="text-xs font-mono bg-blue-500/10 text-blue-600 px-2 py-0.5 rounded flex-shrink-0 mt-0.5">1</span>
<span class="leading-relaxed"><code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">fetch()</code> は「指定したURLに問い合わせる」命令。URLの末尾にある <code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">?city=tokyo</code> が「東京の情報が欲しい」というリクエストの中身です。レストランのたとえで言えば「パスタください」にあたる部分。</span>
</div>
<div class="flex items-start gap-3">
<span class="text-xs font-mono bg-purple-500/10 text-purple-600 px-2 py-0.5 rounded flex-shrink-0 mt-0.5">2</span>
<span class="leading-relaxed">返ってきたデータは機械向けの生データなので、<code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">.json()</code> で人間が読みやすい形JSON = JavaScript Object Notationに変換します。JSONは「名前: 値」の組み合わせでデータを表現する書式で、Web業界で最も広く使われています。</span>
</div>
<div class="flex items-start gap-3">
<span class="text-xs font-mono bg-emerald-500/10 text-emerald-600 px-2 py-0.5 rounded flex-shrink-0 mt-0.5">3</span>
<span class="leading-relaxed">変換したデータから <code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">data.temperature</code> のように、ドット(.)で区切って欲しい情報を名前で取り出します。辞書で単語を引くのに似ています。</span>
</div>
</div>
</div>
<p class="mb-4 leading-relaxed">
ターミナルコマンドを入力する黒い画面からもAPIを試せます。<code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">curl</code>カールというコマンドを使うと、たった1行でAPIにリクエストを送れます。
</p>
<!-- ターミナルUIモックアップ: curl -->
<div class="mb-8 rounded-xl overflow-hidden border border-slate-700/50">
<div class="flex items-center gap-3 bg-slate-800 px-4 py-2.5">
<div class="flex gap-1.5">
<div class="w-3 h-3 rounded-full bg-red-500/80"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500/80"></div>
<div class="w-3 h-3 rounded-full bg-green-500/80"></div>
</div>
<div class="flex items-center gap-1.5 text-xs text-slate-400">
<i data-lucide="terminal" class="w-3.5 h-3.5"></i>
ターミナル — curlコマンドでAPIを叩く
</div>
</div>
<pre class="bg-slate-950 p-5 overflow-x-auto text-sm leading-loose"><code><span class="text-emerald-400">$</span> curl https://api.weather.example.com/current?city=tokyo
<span class="text-slate-500"># 返ってくるレスポンスJSON形式</span>
{
<span class="text-blue-400">"city"</span>: <span class="text-emerald-400">"東京"</span>,
<span class="text-blue-400">"temperature"</span>: <span class="text-amber-400">"22°C"</span>,
<span class="text-blue-400">"condition"</span>: <span class="text-emerald-400">"晴れ"</span>,
<span class="text-blue-400">"humidity"</span>: <span class="text-amber-400">"65%"</span>
}</code></pre>
</div>
<div class="bg-amber-500/5 border border-amber-500/20 rounded-xl p-5">
<div class="flex items-start gap-3">
<div class="flex items-center justify-center w-8 h-8 rounded-lg bg-amber-500/10 flex-shrink-0 mt-0.5">
<i data-lucide="info" class="w-4 h-4 text-amber-600"></i>
</div>
<div>
<p class="font-bold text-amber-700 mb-1">ちょっと補足: URLの構造</p>
<p class="text-ads-muted leading-relaxed text-sm">
<code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">https://api.weather.example.com/current?city=tokyo</code> のURLは、大きく3つの部分に分かれます。<strong class="text-slate-800">api.weather.example.com</strong> がAPIの住所ベースURL<strong class="text-slate-800">/current</strong> が「何を」(現在の天気)、<strong class="text-slate-800">?city=tokyo</strong> が「どこの」(東京)というパラメータです。レストランで例えると「〇〇レストランの(住所)、メインメニューから(何を)、パスタを(詳細)」に対応します。
</p>
</div>
</div>
</div>
<p class="mt-8 mb-6 leading-relaxed">
では、このAPIのレスポンスが実際のアプリではどう表示されるのでしょうか あなたが見ている天気アプリの画面を覗いてみましょう。
</p>
<!-- ブラウザUIモックアップ -->
<div class="rounded-xl overflow-hidden border border-slate-700/50 mb-8">
<div class="flex items-center gap-3 bg-slate-800 px-4 py-2.5">
<div class="flex gap-1.5">
<div class="w-3 h-3 rounded-full bg-red-500/80"></div>
<div class="w-3 h-3 rounded-full bg-yellow-500/80"></div>
<div class="w-3 h-3 rounded-full bg-green-500/80"></div>
</div>
<div class="flex-1 bg-slate-700/50 rounded-lg px-3 py-1 text-xs text-slate-400 flex items-center gap-1.5">
<i data-lucide="lock" class="w-3 h-3 text-emerald-400"></i>
weather-app.example.com
</div>
</div>
<div class="bg-gradient-to-b from-sky-100 to-sky-50 p-6 md:p-8">
<div class="text-center">
<div class="text-xs text-sky-600/70 font-medium mb-1">現在地: 東京</div>
<div class="flex items-center justify-center gap-2 mb-2">
<i data-lucide="sun" class="w-10 h-10 text-amber-500"></i>
<span class="text-4xl font-black text-sky-900">22°C</span>
</div>
<div class="text-sm text-sky-700 font-medium mb-4">晴れ</div>
<div class="flex justify-center gap-6 text-xs text-sky-600/80">
<div class="flex items-center gap-1"><i data-lucide="droplets" class="w-3.5 h-3.5"></i> 65%</div>
<div class="flex items-center gap-1"><i data-lucide="wind" class="w-3.5 h-3.5"></i> 3m/s</div>
</div>
</div>
</div>
</div>
<div class="bg-ads-accent/5 border border-ads-accent/20 rounded-xl p-5">
<div class="flex items-start gap-3">
<div class="flex items-center justify-center w-8 h-8 rounded-lg bg-ads-accent/10 flex-shrink-0 mt-0.5">
<i data-lucide="lightbulb" class="w-4 h-4 text-ads-accent-light"></i>
</div>
<div>
<p class="font-bold text-ads-accent-light mb-1">APIの結果 → アプリの画面</p>
<p class="text-ads-muted leading-relaxed">
上の天気アプリは、裏側で <code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">temperature: "22°C"</code><code class="text-emerald-700 text-xs bg-slate-100 px-1.5 py-0.5 rounded">condition: "晴れ"</code> というAPIレスポンスを受け取り、見やすいデザインに変換して表示しています。<strong class="text-slate-800">あなたが普段見ているきれいな画面の裏側では、こうしたAPIのやり取りが行われている</strong>のです。
</p>
</div>
</div>
</div>
</section>
<!-- ============================================================ -->
<!-- SECTION 4: 身近なAPIの例 -->
<!-- ============================================================ -->
<section class="mb-16 md:mb-20">
<div class="flex items-center gap-3 mb-8">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-amber-500/10 flex-shrink-0">
<i data-lucide="smartphone" class="w-5 h-5 text-amber-600"></i>
</div>
<h2 class="text-xl md:text-2xl font-bold text-slate-900">身近なAPIの例 — 実はあなたも毎日使っている</h2>
</div>
<p class="mb-8 leading-relaxed">
「API」と聞くとプログラマーの専門用語に聞こえるかもしれません。しかし、あなたがスマホで何気なくやっている日常の操作の裏側では、たくさんのAPIが動いています。<strong class="text-slate-900">「あなたが見ている画面」の裏側で、APIが何をしているのか</strong>を図解します。
</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- 天気予報アプリ -->
<div class="bg-ads-surface border border-ads-border rounded-xl overflow-hidden">
<div class="bg-gradient-to-b from-sky-100 to-sky-50 p-5">
<div class="text-center">
<div class="text-[10px] text-sky-600/60 font-medium mb-0.5">東京</div>
<div class="flex items-center justify-center gap-1.5 mb-1">
<i data-lucide="sun" class="w-7 h-7 text-amber-500"></i>
<span class="text-2xl font-black text-sky-900">22°C</span>
</div>
<div class="text-xs text-sky-700 font-medium mb-2">晴れ</div>
<div class="flex justify-center gap-4 text-[10px] text-sky-600/70">
<div class="flex items-center gap-0.5"><i data-lucide="droplets" class="w-3 h-3"></i> 65%</div>
<div class="flex items-center gap-0.5"><i data-lucide="wind" class="w-3 h-3"></i> 3m/s</div>
</div>
</div>
</div>
<div class="p-5 pt-4">
<h3 class="font-bold text-slate-900 text-sm mb-2 flex items-center gap-2">
<i data-lucide="cloud" class="w-4 h-4 text-cyan-600"></i> 天気予報アプリ
</h3>
<div class="text-xs text-cyan-600 font-medium mb-1">裏側でAPIがやっていること</div>
<p class="text-sm text-ads-muted leading-relaxed">気象庁のサーバーに「東京の最新天気データをください」とリクエストを送り、気温・天候・湿度・風速などのデータをJSON形式で受け取っている</p>
</div>
</div>
<!-- Googleログイン -->
<div class="bg-ads-surface border border-ads-border rounded-xl overflow-hidden">
<div class="bg-white p-5 flex flex-col items-center justify-center">
<div class="text-xs text-ads-muted mb-3">アカウントにログイン</div>
<div class="flex items-center gap-2.5 border border-ads-border rounded-lg px-5 py-2.5 bg-white hover:bg-ads-hover transition-colors">
<div class="w-5 h-5 rounded-full bg-gradient-to-br from-blue-500 via-red-500 to-yellow-500 flex items-center justify-center">
<span class="text-[8px] font-black text-white">G</span>
</div>
<span class="text-sm font-medium text-slate-700">Google でログイン</span>
</div>
<div class="flex items-center gap-3 mt-3">
<div class="flex-1 border-t border-ads-border/50"></div>
<span class="text-[10px] text-ads-dim">または</span>
<div class="flex-1 border-t border-ads-border/50"></div>
</div>
<div class="w-full mt-2 bg-ads-surface border border-ads-border/50 rounded-lg px-3 py-1.5 text-xs text-ads-dim">メールアドレスで登録</div>
</div>
<div class="p-5 pt-4">
<h3 class="font-bold text-slate-900 text-sm mb-2 flex items-center gap-2">
<i data-lucide="log-in" class="w-4 h-4 text-blue-600"></i> 「Googleでログイン」ボタン
</h3>
<div class="text-xs text-blue-600 font-medium mb-1">裏側でAPIがやっていること</div>
<p class="text-sm text-ads-muted leading-relaxed">GoogleのOAuth APIオーオース = 認可の仕組み)に「このユーザーの身元を確認してください」と問い合わせ、認証トークン(本人確認済みの証)を受け取っている</p>
</div>
</div>
<!-- オンライン決済 -->
<div class="bg-ads-surface border border-ads-border rounded-xl overflow-hidden">
<div class="bg-gradient-to-b from-emerald-50 to-white p-5 text-center">
<div class="w-10 h-10 rounded-full bg-emerald-500/15 flex items-center justify-center mx-auto mb-2">
<i data-lucide="check" class="w-6 h-6 text-emerald-600"></i>
</div>
<div class="text-sm font-bold text-emerald-700 mb-1">お支払い完了</div>
<div class="text-xl font-black text-slate-900 mb-1">&#165;1,980</div>
<div class="text-[10px] text-ads-dim">VISA **** 4242</div>
</div>
<div class="p-5 pt-4">
<h3 class="font-bold text-slate-900 text-sm mb-2 flex items-center gap-2">
<i data-lucide="credit-card" class="w-4 h-4 text-emerald-600"></i> オンライン決済
</h3>
<div class="text-xs text-emerald-600 font-medium mb-1">裏側でAPIがやっていること</div>
<p class="text-sm text-ads-muted leading-relaxed">Stripe等の決済APIが、クレジットカード会社のサーバーと暗号化通信を行い、与信確認この人は支払える→ 決済処理 → 結果通知を実行している</p>
<p class="text-[10px] text-ads-dim mt-2">出典: <a href="https://docs.stripe.com/api" class="underline decoration-ads-dim/30 hover:text-ads-accent transition-colors">Stripe API 公式ドキュメント</a></p>
</div>
</div>
<!-- 地図・ナビ -->
<div class="bg-ads-surface border border-ads-border rounded-xl overflow-hidden">
<div class="bg-emerald-50/50 p-5">
<div class="relative bg-emerald-100/80 rounded-lg p-4 h-28 flex flex-col justify-between">
<div class="flex items-center gap-1.5">
<div class="w-4 h-4 rounded-full bg-blue-500 border-2 border-white flex items-center justify-center">
<div class="w-1.5 h-1.5 bg-white rounded-full"></div>
</div>
<span class="text-[10px] text-blue-700 font-medium">現在地</span>
</div>
<div class="border-l-2 border-dashed border-blue-400/60 ml-2 h-6"></div>
<div class="flex items-center justify-between">
<div class="flex items-center gap-1.5">
<i data-lucide="map-pin" class="w-4 h-4 text-red-500"></i>
<span class="text-[10px] text-red-700 font-medium">東京駅</span>
</div>
<div class="bg-white rounded-full px-2 py-0.5 text-[10px] font-bold text-blue-700 border border-blue-200">12分</div>
</div>
</div>
</div>
<div class="p-5 pt-4">
<h3 class="font-bold text-slate-900 text-sm mb-2 flex items-center gap-2">
<i data-lucide="map-pin" class="w-4 h-4 text-red-600"></i> 地図・ナビアプリ
</h3>
<div class="text-xs text-red-600 font-medium mb-1">裏側でAPIがやっていること</div>
<p class="text-sm text-ads-muted leading-relaxed">Google Maps APIが地図画像の取得、現在の交通情報の取得、経路計算をそれぞれ別のAPIに問い合わせ、統合して表示している</p>
</div>
</div>
</div>
<div class="mt-8 bg-ads-accent/5 border border-ads-accent/20 rounded-xl p-5">
<div class="flex items-start gap-3">
<div class="flex items-center justify-center w-8 h-8 rounded-lg bg-ads-accent/10 flex-shrink-0 mt-0.5">
<i data-lucide="lightbulb" class="w-4 h-4 text-ads-accent-light"></i>
</div>
<div>
<p class="font-bold text-ads-accent-light mb-1">気づきましたか?</p>
<p class="text-ads-muted leading-relaxed text-sm">
上の4つの例に共通しているのは、<strong class="text-slate-800">あなたがAPIの存在を意識していない</strong>ということです。天気を確認するとき「今からAPIを呼ぶぞ」とは思いませんよね。優れたAPIは、ユーザーにその存在を感じさせません。まるで空気のように、裏側で静かに仕事をしているのです。
</p>
</div>
</div>
</div>
</section>
<!-- ============================================================ -->
<!-- SECTION 5: APIを使うとどう嬉しいか -->
<!-- ============================================================ -->
<section class="mb-16 md:mb-20">
<div class="flex items-center gap-3 mb-8">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-emerald-500/10 flex-shrink-0">
<i data-lucide="trending-up" class="w-5 h-5 text-emerald-600"></i>
</div>
<h2 class="text-xl md:text-2xl font-bold text-slate-900">APIを使うとどう嬉しいか</h2>
</div>
<p class="mb-8 leading-relaxed">
ここまで読んで「APIは便利そうだ」と感じてもらえたと思います。では、開発者の視点から見たとき、APIを使うことで<strong class="text-slate-900">具体的にどのくらいの効果</strong>があるのか。数字と一緒に見てみましょう。
</p>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-10">
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 text-center">
<div class="text-3xl md:text-4xl font-black text-ads-accent leading-tight mb-2">50回+</div>
<div class="text-sm text-ads-muted">あなたが1日に<br>APIを使っている回数</div>
</div>
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 text-center">
<div class="text-3xl md:text-4xl font-black text-emerald-600 leading-tight mb-2">24,000+</div>
<div class="text-sm text-ads-muted">世界で公開されている<br>APIの数</div>
<p class="text-[10px] text-ads-dim mt-2">出典: <a href="https://www.programmableweb.com/" class="underline decoration-ads-dim/30 hover:text-ads-accent transition-colors">ProgrammableWeb</a></p>
</div>
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 text-center">
<div class="text-3xl md:text-4xl font-black text-amber-600 leading-tight mb-2">0.2秒</div>
<div class="text-sm text-ads-muted">多くのAPIの<br>平均応答時間</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="flex gap-4 bg-ads-surface border border-ads-border rounded-xl p-5">
<div class="w-10 h-10 rounded-lg bg-amber-500/10 flex items-center justify-center flex-shrink-0">
<i data-lucide="zap" class="w-5 h-5 text-amber-600"></i>
</div>
<div>
<h3 class="font-bold text-slate-900 mb-2">開発スピードが上がる</h3>
<p class="text-sm text-ads-muted leading-relaxed">決済、認証、地図、翻訳...。これらをゼロから作ると何ヶ月もかかりますが、APIを使えば数日〜数時間で実装できます。車を作りたいとき、エンジンから設計する必要はないのです。</p>
</div>
</div>
<div class="flex gap-4 bg-ads-surface border border-ads-border rounded-xl p-5">
<div class="w-10 h-10 rounded-lg bg-blue-500/10 flex items-center justify-center flex-shrink-0">
<i data-lucide="shield" class="w-5 h-5 text-blue-600"></i>
</div>
<div>
<h3 class="font-bold text-slate-900 mb-2">品質が担保される</h3>
<p class="text-sm text-ads-muted leading-relaxed">Google Maps、Stripe、AWSなど、各分野の専門企業が何千人体制で開発・運用しているAPIの品質は、個人や小さなチームで再現できるレベルではありません。その品質を「借りる」ことができます。</p>
</div>
</div>
<div class="flex gap-4 bg-ads-surface border border-ads-border rounded-xl p-5">
<div class="w-10 h-10 rounded-lg bg-purple-500/10 flex items-center justify-center flex-shrink-0">
<i data-lucide="refresh-cw" class="w-5 h-5 text-purple-600"></i>
</div>
<div>
<h3 class="font-bold text-slate-900 mb-2">保守の手間が減る</h3>
<p class="text-sm text-ads-muted leading-relaxed">API提供元がバグ修正・機能改善・セキュリティ更新を継続的に行ってくれます。あなたはAPIを「使うだけ」。自分でゼロから作った機能は、自分でずっと面倒を見続ける必要があります。</p>
</div>
</div>
<div class="flex gap-4 bg-ads-surface border border-ads-border rounded-xl p-5">
<div class="w-10 h-10 rounded-lg bg-emerald-500/10 flex items-center justify-center flex-shrink-0">
<i data-lucide="layers" class="w-5 h-5 text-emerald-600"></i>
</div>
<div>
<h3 class="font-bold text-slate-900 mb-2">レゴのように拡張できる</h3>
<p class="text-sm text-ads-muted leading-relaxed">APIはレゴブロックのように組み合わせられます。たとえば「翻訳API + 音声合成API」を組み合わせれば、多言語音声読み上げ機能が作れます。1つのAPIだけでは実現できない価値が、組み合わせで生まれるのです。</p>
</div>
</div>
</div>
</section>
<!-- ============================================================ -->
<!-- SECTION 6: よくある誤解 -->
<!-- ============================================================ -->
<section class="mb-16 md:mb-20">
<div class="flex items-center gap-3 mb-8">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-red-500/10 flex-shrink-0">
<i data-lucide="alert-circle" class="w-5 h-5 text-red-600"></i>
</div>
<h2 class="text-xl md:text-2xl font-bold text-slate-900">よくある誤解</h2>
</div>
<p class="mb-8 leading-relaxed">
APIについて学び始めると、多くの人が同じところでつまずきます。ここでは、初学者が陥りがちな3つの誤解を取り上げて、正しい理解に修正します。
</p>
<div class="space-y-4">
<div class="bg-ads-surface border border-ads-border rounded-xl overflow-hidden">
<div class="flex items-center gap-3 px-6 py-4 bg-red-500/5 border-b border-ads-border/50">
<div class="w-6 h-6 rounded-full bg-red-500/10 flex items-center justify-center flex-shrink-0">
<i data-lucide="x" class="w-3.5 h-3.5 text-red-600"></i>
</div>
<h3 class="font-bold text-red-700 text-sm">誤解: 「APIはプログラマーだけが使うもの」</h3>
</div>
<div class="px-6 py-5">
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded-full bg-emerald-500/10 flex items-center justify-center flex-shrink-0 mt-0.5">
<i data-lucide="check" class="w-3.5 h-3.5 text-emerald-600"></i>
</div>
<div>
<p class="text-sm font-bold text-emerald-700 mb-2">実際は:</p>
<p class="text-sm text-ads-muted leading-relaxed">
あなたも毎日APIを使っています。朝、天気アプリを開く。SNSにログインする。電子マネーで買い物する。これらの操作はすべて、裏側でAPIが動いています。プログラマーが「APIを使う」のは、この仕組みのコードを書いている側にいるだけの話。<strong class="text-slate-800">気づかないうちにAPIの恩恵を毎日受けている</strong>のです。
</p>
</div>
</div>
</div>
</div>
<div class="bg-ads-surface border border-ads-border rounded-xl overflow-hidden">
<div class="flex items-center gap-3 px-6 py-4 bg-red-500/5 border-b border-ads-border/50">
<div class="w-6 h-6 rounded-full bg-red-500/10 flex items-center justify-center flex-shrink-0">
<i data-lucide="x" class="w-3.5 h-3.5 text-red-600"></i>
</div>
<h3 class="font-bold text-red-700 text-sm">誤解: 「APIって難しい技術でしょ</h3>
</div>
<div class="px-6 py-5">
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded-full bg-emerald-500/10 flex items-center justify-center flex-shrink-0 mt-0.5">
<i data-lucide="check" class="w-3.5 h-3.5 text-emerald-600"></i>
</div>
<div>
<p class="text-sm font-bold text-emerald-700 mb-2">実際は:</p>
<p class="text-sm text-ads-muted leading-relaxed">
APIの概念自体は「注文して結果を受け取る」というシンプルな仕組みです。レストランで注文できるなら、APIの概念は理解できます。先ほどのコード例のように、実際のプログラムも数行で書けることがほとんどです。難しいのはAPIそのものではなく、<strong class="text-slate-800">「APIで何を作るか」を考える部分</strong>。道具はシンプル、使いこなすセンスが問われるということです。
</p>
</div>
</div>
</div>
</div>
<div class="bg-ads-surface border border-ads-border rounded-xl overflow-hidden">
<div class="flex items-center gap-3 px-6 py-4 bg-red-500/5 border-b border-ads-border/50">
<div class="w-6 h-6 rounded-full bg-red-500/10 flex items-center justify-center flex-shrink-0">
<i data-lucide="x" class="w-3.5 h-3.5 text-red-600"></i>
</div>
<h3 class="font-bold text-red-700 text-sm">誤解: 「APIを使うと個人情報が漏れそうで怖い」</h3>
</div>
<div class="px-6 py-5">
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded-full bg-emerald-500/10 flex items-center justify-center flex-shrink-0 mt-0.5">
<i data-lucide="check" class="w-3.5 h-3.5 text-emerald-600"></i>
</div>
<div>
<p class="text-sm font-bold text-emerald-700 mb-2">実際は:</p>
<p class="text-sm text-ads-muted leading-relaxed">
適切に設計されたAPIは、<strong class="text-slate-800">必要最小限の情報だけ</strong>をやり取りします。たとえば銀行のAPIが口座残高を返す際、パスワードや暗証番号は一切含まれません。APIはデータの「窓口」であり、<strong class="text-slate-800">「何の情報を公開し、何を隠すか」を厳密に制御</strong>できます。むしろ、データベースに直接触るよりもAPIを介した方が安全なのです。レストランのたとえで言えば、お客さんが直接厨房に入るより、ウェイターを通した方が厨房の秩序が保たれるのと同じです。
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============================================================ -->
<!-- SECTION 7: まとめ -->
<!-- ============================================================ -->
<section>
<div class="flex items-center gap-3 mb-8">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-ads-accent/10 flex-shrink-0">
<i data-lucide="check-circle" class="w-5 h-5 text-ads-accent-light"></i>
</div>
<h2 class="text-xl md:text-2xl font-bold text-slate-900">まとめ — 覚えておきたい3つのこと</h2>
</div>
<p class="mb-8 leading-relaxed">
長い図解を読んでいただきありがとうございます。最後に、この記事で伝えたかったことを3つに絞ってまとめます。
</p>
<div class="space-y-4 mb-10">
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 border-l-4 border-l-blue-500">
<div class="flex items-start gap-4">
<div class="text-2xl font-black text-blue-500 leading-none flex-shrink-0 mt-1">01</div>
<div>
<h3 class="font-bold text-slate-900 mb-2">APIは「ソフトウェアの窓口」</h3>
<p class="text-sm text-ads-muted leading-relaxed">
レストランのウェイターのように、あなた(アプリ)とサーバーの間を取り持つ仲介役。相手の内部構造を知らなくても、決まったルール(インターフェース)で話しかければ結果が返ってきます。
</p>
</div>
</div>
</div>
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 border-l-4 border-l-emerald-500">
<div class="flex items-start gap-4">
<div class="text-2xl font-black text-emerald-500 leading-none flex-shrink-0 mt-1">02</div>
<div>
<h3 class="font-bold text-slate-900 mb-2">あなたはすでにAPIユーザー</h3>
<p class="text-sm text-ads-muted leading-relaxed">
天気予報、SNSログイン、地図検索、オンライン決済。気づかないうちに、あなたの日常はAPIに支えられています。APIは特別な人だけのものではなく、全員の生活を支える仕組みです。
</p>
</div>
</div>
</div>
<div class="bg-ads-surface border border-ads-border rounded-xl p-6 border-l-4 border-l-amber-500">
<div class="flex items-start gap-4">
<div class="text-2xl font-black text-amber-500 leading-none flex-shrink-0 mt-1">03</div>
<div>
<h3 class="font-bold text-slate-900 mb-2">APIで「車輪の再発明」がなくなる</h3>
<p class="text-sm text-ads-muted leading-relaxed">
すでにある優れた機能をAPIで借りることで、自分は「自分にしか作れない部分」に集中できます。開発スピードが上がり、品質も上がり、保守の手間も減る。これがAPIの最大の恩恵です。
</p>
</div>
</div>
</div>
</div>
<div class="text-center bg-gradient-to-b from-ads-accent/5 to-transparent border border-ads-accent/10 rounded-xl p-8 md:p-10">
<i data-lucide="globe" class="w-8 h-8 text-ads-accent mx-auto mb-4"></i>
<p class="text-lg font-bold text-slate-900 mb-3">APIは「知っている」だけで世界が広がる概念です。</p>
<p class="text-ads-muted max-w-lg mx-auto leading-relaxed">
次にアプリを使うとき、「この裏側でどんなAPIが動いているんだろう」と想像してみてください。天気予報の数字も、ログインボタンも、決済完了の画面も、すべてAPIが繋いでいます。テクロジーの見え方が、少しだけ変わるはずです。
</p>
</div>
</section>
<!-- CONTENT_END -->
</main>
<footer class="max-w-3xl mx-auto px-5 pb-10 pt-6 border-t border-ads-border/30">
<p class="text-xs text-ads-dim text-center">AI-Driven School の図解ツールで作成</p>
</footer>
<script src="https://unpkg.com/lucide@latest"></script>
<script>lucide.createIcons();</script>
</body>
</html>

View File

@ -0,0 +1,68 @@
# Node.js インストールガイド
SKILL.md の Step 5 で Node.js が未インストールだった場合に参照する。
## 説明と許可
以下をユーザーに伝え、インストールの許可を求める:
> 図解の作成は完了しました。`output/` フォルダ内の HTML ファイルをブラウザにドラッグ&ドロップすれば、今すぐ確認できます。
>
> URLで公開するには「Node.js」のインストールが必要です。
> Node.js は、パソコン上でプログラムを動かすための土台で、世界中で使われている安全な道具です。
> **README にも記載の通り、AI-Driven School 運営が確認済みですので安心してください。**
>
> 今からインストールしてもよいですか?
ユーザーが許可しなかった場合 → ファイルの確認方法(生成された HTML ファイルをブラウザで開く)を伝えて終了。
## macOS の場合
インストーラーをダウンロードする:
```bash
PKG_NAME=$(curl -sL https://nodejs.org/dist/latest-lts/ | grep -o 'node-v[0-9.]*\.pkg' | head -1) && curl -fsSL "https://nodejs.org/dist/latest-lts/${PKG_NAME}" -o /tmp/node-install.pkg && echo "ダウンロード完了: ${PKG_NAME}"
```
ダウンロード完了後、インストールを実行する**前に**以下を伝える:
> インストールのために、パソコンのパスワードの入力が必要です。
> これはパソコンにログインするときに使っているパスワードです。
> 画面下のターミナル欄にパスワードを入力して Enter を押してください。
> 入力中の文字は画面に表示されませんが、正常な動作です。
```bash
sudo installer -pkg /tmp/node-install.pkg -target / && rm /tmp/node-install.pkg
```
## Windows の場合
インストールを実行する**前に**以下を伝える:
> インストール中に「このアプリがデバイスに変更を加えることを許可しますか?」という確認画面が表示されることがあります。
> 「はい」を押してください。
```powershell
winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements
```
インストール完了後、現在のターミナルで Node.js を使えるようにする:
```powershell
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
```
winget が使えない場合「winget は認識されていません」と表示された場合):
```powershell
$msi = (Invoke-WebRequest -Uri "https://nodejs.org/dist/latest-lts/" -UseBasicParsing).Links.href | Where-Object { $_ -match "x64\.msi$" } | Select-Object -First 1; Invoke-WebRequest -Uri "https://nodejs.org/dist/latest-lts/$msi" -OutFile "$env:TEMP\node-install.msi" -UseBasicParsing; Start-Process msiexec.exe -ArgumentList "/i `"$env:TEMP\node-install.msi`"" -Verb RunAs -Wait; Remove-Item "$env:TEMP\node-install.msi"
```
## インストール完了の確認
```bash
node --version
```
バージョン番号が表示された → インストール成功。
エラーが出た → Cursor を再起動してからもう一度試すよう案内する。

View File

@ -0,0 +1,58 @@
#!/bin/bash
set -e
HTML_FILE="${1:?使い方: deploy-diagram.sh <HTMLファイル> [スラッグ]}"
SLUG="${2:-}"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
if ! command -v node &>/dev/null; then
echo -e "${RED}エラー: Node.js がインストールされていません${NC}" >&2
echo "Node.js をインストールしてから、もう一度試してください。" >&2
exit 1
fi
if [ ! -f "$HTML_FILE" ]; then
echo -e "${RED}エラー: $HTML_FILE が見つかりません${NC}" >&2
echo "先に図解を生成してください。" >&2
exit 1
fi
if [ -n "$SLUG" ]; then
DOMAIN="diagram-${SLUG}.surge.sh"
else
DOMAIN="diagram-$(date +%y%m%d%H%M).surge.sh"
fi
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "$TEMP_DIR"' EXIT
cp "$HTML_FILE" "$TEMP_DIR/index.html"
printf "User-agent: *\nDisallow: /\n" > "$TEMP_DIR/robots.txt"
echo -e "${YELLOW}公開中...${NC}"
npx --yes surge "$TEMP_DIR" --domain "$DOMAIN"
touch deploy-history.log
echo "$(date '+%Y-%m-%d %H:%M:%S') | https://${DOMAIN}" >> deploy-history.log
echo ""
echo -e "${GREEN}完了!${NC}"
echo "URL: https://${DOMAIN}"
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "https://${DOMAIN}" | pbcopy
echo -e "${GREEN}URLをクリップボードにコピーしました${NC}"
open "https://${DOMAIN}"
elif command -v clip.exe &>/dev/null; then
echo -n "https://${DOMAIN}" | clip.exe
echo -e "${GREEN}URLをクリップボードにコピーしました${NC}"
start "https://${DOMAIN}" 2>/dev/null || true
elif command -v xdg-open &>/dev/null; then
xdg-open "https://${DOMAIN}"
fi
echo -e "${YELLOW}削除するとき: npx surge teardown ${DOMAIN}${NC}"

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
output/*.html
deploy-history.log

74
README.md Normal file
View File

@ -0,0 +1,74 @@
# パーソナル図解
自分の仕事に最適化された「パーソナル図解スキル」を作るためのツールキットです。
配布済みの図解ツールは汎用ツールですが、パーソナル図解スキルは違います。**あなたの仕事・あなたの読者に合わせた、あなた専用の図解ツール**です。
## フォルダの中身
```
パーソナル図解/
├── .claude/skills/
│ ├── creating-skills/ ← スキルの作り方ガイド
│ └── creating-visual-explainers/ ← 図解を生成するスキル(配布済みの図解ツールと同じもの)
├── sample/
│ └── majiai-diagram/ ← 模範解答本気AIの図解スキル
│ ├── .claude/skills/diagram-maji/ ← スキル本体
│ └── docs/charactor-images/ ← キャラクター画像
├── output/ ← 図解の保存先
├── .gitignore
└── README.md ← この説明書
```
| フォルダ | 説明 |
|---------|------|
| `.claude/skills/creating-skills/` | スキルの作り方ガイド。設計原則・パターン集・チェックリストが入っています |
| `.claude/skills/creating-visual-explainers/` | 図解HTMLを生成するスキル。配布済みの図解ツールと同じものです |
| `sample/majiai-diagram/` | 模範解答です。本気AIが実際に使っている図解スキルの構造がわかります |
| `output/` | 生成した図解の保存先 |
## まず模範解答を見てみる
`sample/majiai-diagram/.claude/skills/diagram-maji/` の中にある SKILL.md と references/ フォルダを開いて読んでみてください。
- **SKILL.md** — スキルの全体設計(どんな順番で何をするかのワークフロー)
- **references/** — デザインガイド、用語辞書、キャラクター設定など
- **docs/charactor-images/** — 図解に使うキャラクター画像
「スキルの中身はこうなっているんだ」と全体像をつかんでおくと、自分のスキルを作るときにスムーズです。
## パーソナル図解スキルの作り方
詳しい手順はポータルの課題ページに書かれています。ざっくりした流れは以下の通りです。
```
① ヒアリングシートを埋める
「誰のどんな問題を解決するか」を言語化する
② AIにスキルを作ってもらう
ヒアリングシートをCursorに貼り付けて依頼する
③ 生成されたスキルを確認・修正する
模範解答と見比べて、足りない部分を追加する
④ 図解を作って試す
「○○を図解して」と依頼して、出力を確認する
```
## 図解を作る
パーソナル図解スキルが完成したら、チャット欄で「○○を図解して」と依頼するだけです。
生成された図解は `output/` フォルダに保存されます。
## 図解を共有する
PDF での共有方法や URL での公開方法は、配布済みの図解ツールと同じです。
図解ツールの README を参照してください。
## 困ったとき
何が起きても、まずはチャット欄で AI に状況を伝えてください。
AI がエラーの内容を読み取り、次にやるべきことを教えてくれます。
解決しない場合は、ポータルの課題ページにあるトラブルシューティングを確認してください。

0
output/.gitkeep Normal file
View File

View File

@ -0,0 +1,195 @@
---
name: diagram-maji
description: 技術ドキュメントを「技術に詳しくない一般の人」向けにわかりやすく図解するスキル。「わかりやすく図解して」「マジ図解して」「図解を作って」と依頼された際に使用します。マジくんとマスターの対話形式で、本気AIブランドに準拠したHTMLを生成し、surge.shにデプロイします。
---
# Diagram Maji
技術ドキュメントを**技術に詳しくない一般の人**でも直感的に理解できるHTMLに変換する。
## 依存
- `docs/design/design-guideline.md` - ブランドカラー、トーン&マナー
- `docs/design/charactor-images/square/512px/` - キャラクター画像
- `contents/docs/方針・キャラ設定/キャラ設定.md` - キャラ設定
---
## ワークフロー
### Phase 0: リサーチ(サブエージェント)
**exploreサブエージェント**を起動して、対象技術を徹底調査する。
```
Task({
subagent_type: "explore",
description: "技術ドキュメントの調査",
prompt: `
以下の技術について徹底的に調査してください:
【対象】{URL or トピック名}
調査項目:
1. この技術は何を解決するものかWhy
2. 主要な概念・用語の一覧
3. 典型的なユースケース3つ以上
4. 初心者がつまずきやすいポイント
5. 関連する公式ドキュメントのURL
結果は箇条書きで整理して返してください。
`
})
```
### Phase 1: ソース読み込み
1. URLなら `WebFetch` で取得
2. ドキュメントなら内容を分析
3. **情報の全体像を把握**(漏れなく)
4. **Phase 0のリサーチ結果と照合**して抜け漏れを確認
### Phase 2: 用語翻訳表を作成
技術用語を洗い出し、やさしい言葉に変換する。
| 技術用語 | やさしい言葉 | たとえ |
|---------|------------|--------|
| コールバック関数 | チェック係 | 「何かあったら呼んでね」と登録しておく処理 |
| フック | 割り込みポイント | 会社のセキュリティゲート |
| API | 窓口 | 銀行の窓口のように、決まった手続きで依頼する場所 |
**詳細** → [references/term-dictionary.md](references/term-dictionary.md)
### Phase 3: たとえ話を3つ以上考える
| 種類 | 例 |
|-----|-----|
| 身近な例 | 会社のセキュリティゲート、郵便配達 |
| デジタルな例 | スマホの権限ダイアログ |
| 視覚的な例 | 信号機、地図、フローチャート |
### Phase 4: 情報を絞り込む
- 「まず覚える3つ」を決定
- 全体の中の位置づけを示す
- 優先度の低い情報は後半に配置
### Phase 5: キャラクター対話を設計
| キャラクター | 役割 | 表情の使い分け |
|------------|------|--------------|
| マジくん | 読者の疑問を代弁(マーケティング職) | 驚き、疑っている、調子に乗ってる |
| マスター | 本質を説明する導き手 | 標準、諭す、思考・分析 |
**詳細** → [references/character-usage.md](references/character-usage.md)
### Phase 6: HTML生成
1. Tailwind CSS CDN使用
2. **Lucide icon**を使用(絵文字禁止)
3. 本気AIブランドカラー適用
4. 用語解説ボックス配置
5. コード例の前に日本語解説
**詳細** → [references/html-structure.md](references/html-structure.md)
### Phase 7: 批判的レビュー(サブエージェント)
**リテラシーが低いユーザー視点**で、忖度なくレビューする。
```
Task({
subagent_type: "generalPurpose",
description: "図解の批判的レビュー",
readonly: true,
prompt: `
あなたは「ITに詳しくない40代の事務職」です。
プログラミング経験はゼロ、スマホは使えるがアプリの仕組みは知りません。
以下のHTML図解を読んで、**忖度なく**批判してください:
【HTMLファイルパス】{path}
## レビュー観点
1. **わからない言葉**: 説明されていても難しい言葉はどれか
2. **たとえ話の違和感**: ピンとこない、逆に混乱するたとえはないか
3. **情報過多**: 読むのが辛くなる部分、スキップしたくなる部分
4. **キャラクターの不自然さ**: セリフが専門家っぽすぎないか
5. **結局何がわかったか**: 読み終わって説明できる自信があるか
## 出力形式
### 致命的な問題(これがあると読めない)
- ...
### 改善すべき点(直せばもっと良くなる)
- ...
### 良かった点(このまま残すべき)
- ...
### 総評
5段階評価: ⭐⭐⭐☆☆3/5のように
一言: 「○○だから△△な人には難しい」のように
`
})
```
### Phase 8: ブラッシュアップ
Phase 7のレビュー結果を踏まえてHTMLを修正する。
**優先度**:
1. 致命的な問題 → 必ず修正
2. 改善すべき点 → 可能な限り対応
3. 良かった点 → 維持
**よくある修正パターン**:
- 用語解説ボックスの追加
- たとえ話の差し替え・追加
- 長いセクションの分割
- キャラクターのセリフをより素朴に
### Phase 9: デプロイ
```bash
# 1. 一時ディレクトリ作成
DEPLOY_DIR=$(mktemp -d)
# 2. HTMLファイル作成
# index.html を $DEPLOY_DIR に書き込む
# 3. キャラクター画像をコピー
mkdir -p "$DEPLOY_DIR/images"
cp docs/design/charactor-images/square/512px/マジくん-*.png "$DEPLOY_DIR/images/"
cp docs/design/charactor-images/square/512px/マスター-*.png "$DEPLOY_DIR/images/"
# 4. surge.shにデプロイ
cd "$DEPLOY_DIR" && surge . --domain {ドメイン名}.surge.sh
```
---
## 品質チェックリスト
### 必須
- [ ] 技術用語には必ず「用語解説ボックス」がある
- [ ] たとえ話が3つ以上ある
- [ ] キャラクター対話が導入・中間・まとめにある
- [ ] 「まず覚える3つ」のような絞り込みがある
- [ ] コード例の前に「このコードがやること」がある
### デザイン
- [ ] Lucide iconを使用絵文字禁止
- [ ] 本気AIブランドカラーが適用されている
- [ ] キャラクター画像が正しく配置されている
- [ ] スマホでも読みやすいレスポンシブ対応
---
## 模範解答
具体的なHTML構造と成功パターン → [references/exemplar.md](references/exemplar.md)

View File

@ -0,0 +1,166 @@
# キャラクター利用ガイド
## キャラクターの役割
| キャラクター | 役割 | 職業 |
|------------|------|------|
| **マジくん** | 読者の代弁者。技術に詳しくない視点で疑問を投げかける | マーケティングアシスタント(非エンジニア) |
| **マスター** | 導き手。本質を平易に説明する | 喫茶店マスター兼AI活用のプロ |
---
## 表情の使い分け
### マジくん10種類
| 表情 | ファイル名 | 使用シーン |
|-----|----------|----------|
| 標準 | `マジくん-標準-512×512-透過.png` | 通常の発言 |
| 驚き | `マジくん-驚き-512×512-透過.png` | 新しい発見、「マジ?」 |
| マジ? | `マジくん-マジ?-512×512-透過.png` | 心底驚いたとき |
| 調子に乗ってる | `マジくん-調子に乗ってる-512×512-透過.png` | 理解した気になっている |
| 疑っている | `マジくん-疑っている-512×512-透過.png` | 半信半疑、ケチをつける |
| 強く反発する | `マジくん-強く反発する-512×512-透過.png` | 納得いかない |
| 焦り | `マジくん-焦り-512×512-透過.png` | 困っている |
| ひどく慌てている | `マジくん-ひどく慌てている-512×512-透過.png` | パニック |
| 涙ぐむ | `マジくん-涙ぐむ-512×512-透過.png` | 落ち込み、感動 |
| 自信がない、落ち込んでいる | `マジくん-自信がない、落ち込んでいる-512×512-透過.png` | 失敗、挫折 |
### マスター4種類
| 表情 | ファイル名 | 使用シーン |
|-----|----------|----------|
| 標準 | `マスター-標準-512×512-透過.png` | 通常の説明 |
| 諭す | `マスター-諭す-512×512-透過.png` | 重要なポイント、本質を伝える |
| 思考、分析 | `マスター-思考、分析-512×512-透過.png` | 考え中、深い話 |
| 真顔 | `マスター-真顔-512×512-透過.png` | 厳しい指摘 |
---
## 対話パターン
### 1. 導入パターン(疑問→答え)
```html
<!-- マジくん: 疑問を投げかける -->
<div class="flex items-start gap-4 mb-6">
<img src="./images/マジくん-疑っている-512×512-透過.png"
alt="マジくん" class="w-20 h-20 object-contain flex-shrink-0">
<div class="char-bubble maji-bubble flex-1">
<p class="text-lg">
<span class="font-bold text-amber-700">マジくん:</span><br>
「フック」って何ですか?プログラムに釣り針でも刺すんですか?
</p>
</div>
</div>
<!-- マスター: 本質を説明 -->
<div class="flex items-start gap-4 mb-6">
<img src="./images/マスター-諭す-512×512-透過.png"
alt="マスター" class="w-20 h-20 object-contain flex-shrink-0">
<div class="char-bubble master-bubble flex-1">
<p class="text-lg">
<span class="font-bold text-blue-700">マスター:</span><br>
良い質問ですね。フックとは「割り込みポイント」のこと。
会社のセキュリティゲートを想像してください。
</p>
</div>
</div>
```
### 2. 驚きパターン(発見の瞬間)
```html
<div class="flex items-start gap-4 mb-6">
<img src="./images/マジくん-驚き-512×512-透過.png"
alt="マジくん" class="w-20 h-20 object-contain flex-shrink-0">
<div class="char-bubble maji-bubble flex-1">
<p class="text-lg">
<span class="font-bold text-amber-700">マジくん:</span><br>
マジ?<br>
つまり、AIが何かする前に「ちょっと待って」って止められるんですね
</p>
</div>
</div>
```
### 3. まとめパターン(理解の確認)
```html
<div class="flex items-start gap-4 mb-6">
<img src="./images/マスター-標準-512×512-透過.png"
alt="マスター" class="w-20 h-20 object-contain flex-shrink-0">
<div class="char-bubble master-bubble flex-1">
<p class="text-lg">
<span class="font-bold text-blue-700">マスター:</span><br>
その通りです。整理すると、フックには3つの役割があります。
</p>
</div>
</div>
<div class="flex items-start gap-4 mb-6">
<img src="./images/マジくん-調子に乗ってる-512×512-透過.png"
alt="マジくん" class="w-20 h-20 object-contain flex-shrink-0">
<div class="char-bubble maji-bubble flex-1">
<p class="text-lg">
<span class="font-bold text-amber-700">マジくん:</span><br>
これでボクも次期OpenAIのCEO候補ですね
</p>
</div>
</div>
```
---
## セリフの書き方
### マジくんの特徴
- **一人称**: 「ボク」
- **基本**: 丁寧語(「〜です」「〜ます」)
- **反発時**: やや格式高い表現
- **驚き**: 「マジ?」(心底驚いた時のみ単独で使用)
- **大袈裟な比喩**: 感情的になると誇張表現
```
❌ 悪い例: 「すごいね!」「わかった!」
✅ 良い例: 「これは人類の転換点かもしれません!」「ボクのキャリアに光が差しました!」
```
### マスターの特徴
- **一人称**: 「私」
- **口調**: 常に丁寧語、タメ口は使わない
- **説明**: たとえ話を必ず使う
- **名前呼び**: 「マジさん」
```
❌ 悪い例: 「それは違う」「こうだ」
✅ 良い例: 「その発言は、マジさんがまだ本質を理解できていない証拠ですね」
```
---
## 配置ルール
1. **対話シーンでは左右固定しない**: 上から順に配置
2. **画像サイズ**: `w-20 h-20`80pxが基本
3. **吹き出しの向き**: 画像側に尖端
4. **余白**: `gap-4`、`mb-6` で統一
---
## 画像パス
HTML内での参照パス:
```html
./images/マジくん-{表情}-512×512-透過.png
./images/マスター-{表情}-512×512-透過.png
```
デプロイ時にコピー元:
```
docs/design/charactor-images/square/512px/
```

View File

@ -0,0 +1,230 @@
# 模範解答パターン
## 成功する図解の構造
```
1. ヘッダー(グラデーション背景)
└─ タイトル + サブタイトル
2. 導入(キャラクター対話)
└─ マジくん: 「〇〇って何ですか?」
└─ マスター: たとえ話で概要説明
3. 用語解説ボックス
└─ 最初に出てくる技術用語を全て解説
4. まず覚える3つ
└─ 絞り込んだ最重要ポイント
└─ 重要度バッジ(必須/推奨/任意)
5. 各セクション詳細
└─ セクションカード形式
└─ Lucide iconでビジュアル化
└─ たとえ話で補足
└─ コード例の前に日本語解説
6. まとめ(キャラクター対話)
└─ マスター: 要点を3つで整理
└─ マジくん: 理解の確認
7. 目次(フローティング)
└─ デスクトップのみ表示
```
---
## 「まず覚える3つ」の書き方
```html
<div class="section-card">
<div class="flex items-center gap-3 mb-6">
<div class="w-12 h-12 bg-gradient-to-br from-rose-500 to-pink-500 rounded-xl flex items-center justify-center">
<i data-lucide="star" class="w-6 h-6 text-white"></i>
</div>
<div>
<h2 class="text-2xl font-bold text-gray-800">まず覚える3つ</h2>
<p class="text-gray-500">最初はこれだけでOK</p>
</div>
</div>
<div class="grid gap-4">
<!-- 1つ目 -->
<div class="flex items-start gap-4 p-4 bg-gradient-to-r from-red-50 to-red-100 rounded-xl border-l-4 border-red-500">
<div class="w-10 h-10 bg-red-500 text-white rounded-full flex items-center justify-center font-bold text-lg flex-shrink-0">1</div>
<div>
<div class="flex items-center gap-2 mb-1">
<span class="font-bold text-lg text-gray-800">PreToolUse</span>
<span class="badge-essential">必須</span>
</div>
<p class="text-gray-600">ツールが実行される<strong></strong>にチェック。「本当にやっていい?」と確認する門番。</p>
</div>
</div>
<!-- 2つ目 -->
<div class="flex items-start gap-4 p-4 bg-gradient-to-r from-blue-50 to-blue-100 rounded-xl border-l-4 border-blue-500">
<div class="w-10 h-10 bg-blue-500 text-white rounded-full flex items-center justify-center font-bold text-lg flex-shrink-0">2</div>
<div>
<div class="flex items-center gap-2 mb-1">
<span class="font-bold text-lg text-gray-800">PostToolUse</span>
<span class="badge-recommended">推奨</span>
</div>
<p class="text-gray-600">ツールが実行された<strong></strong>に確認。結果をログに残したり、通知を送ったり。</p>
</div>
</div>
<!-- 3つ目 -->
<div class="flex items-start gap-4 p-4 bg-gradient-to-r from-green-50 to-green-100 rounded-xl border-l-4 border-green-500">
<div class="w-10 h-10 bg-green-500 text-white rounded-full flex items-center justify-center font-bold text-lg flex-shrink-0">3</div>
<div>
<div class="flex items-center gap-2 mb-1">
<span class="font-bold text-lg text-gray-800">Stop</span>
<span class="badge-optional">任意</span>
</div>
<p class="text-gray-600">AIが作業を終えるとき。「お疲れ様、次はこれをやってね」とフォローアップを追加。</p>
</div>
</div>
</div>
</div>
```
---
## たとえ話の展開パターン
### パターン1: 会社のセキュリティゲート
```html
<div class="bg-gradient-to-r from-amber-50 to-orange-50 p-6 rounded-xl border border-amber-200 my-6">
<div class="flex items-center gap-2 mb-3">
<i data-lucide="building-2" class="w-6 h-6 text-amber-600"></i>
<span class="font-bold text-amber-800">たとえ話:会社のセキュリティゲート</span>
</div>
<div class="space-y-3 text-gray-700">
<p>あなたが会社に出勤するとき、入口にはセキュリティゲートがありますよね。</p>
<ul class="list-disc list-inside space-y-1 ml-2">
<li><strong>社員証をかざす</strong> → 本人確認PreToolUse</li>
<li><strong>ゲートが開く</strong> → 許可された行動が実行される</li>
<li><strong>入館記録が残る</strong> → ログ記録PostToolUse</li>
</ul>
<p>フックは、この<strong>セキュリティゲートのような役割</strong>をプログラムの中で果たします。</p>
</div>
</div>
```
### パターン2: スマホの権限ダイアログ
```html
<div class="bg-gradient-to-r from-blue-50 to-indigo-50 p-6 rounded-xl border border-blue-200 my-6">
<div class="flex items-center gap-2 mb-3">
<i data-lucide="smartphone" class="w-6 h-6 text-blue-600"></i>
<span class="font-bold text-blue-800">たとえ話:スマホの権限ダイアログ</span>
</div>
<div class="space-y-3 text-gray-700">
<p>スマホでアプリを使うとき、こんな画面を見たことありませんか?</p>
<div class="bg-white p-4 rounded-lg border text-center my-3">
「カメラへのアクセスを許可しますか?」<br>
<span class="text-blue-600">[許可する]</span> / <span class="text-gray-500">[許可しない]</span>
</div>
<p>これがまさに<strong>PreToolUse</strong>の動き!</p>
<ul class="list-disc list-inside space-y-1 ml-2">
<li><strong>許可する</strong> → allow実行OK</li>
<li><strong>許可しない</strong> → deny実行NG</li>
<li><strong>毎回確認する</strong> → askユーザーに聞く</li>
</ul>
</div>
</div>
```
---
## 詳細セクションの書き方
```html
<div class="section-card" id="pretooluse">
<!-- セクションヘッダー -->
<div class="flex items-center gap-3 mb-6">
<div class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center">
<i data-lucide="shield-check" class="w-6 h-6 text-blue-600"></i>
</div>
<div>
<h2 class="text-2xl font-bold text-gray-800">PreToolUse</h2>
<p class="text-gray-500">ツール実行前のチェックポイント</p>
</div>
</div>
<!-- キャラクター対話 -->
<div class="flex items-start gap-4 mb-6">
<img src="./images/マジくん-疑っている-512×512-透過.png"
alt="マジくん" class="w-16 h-16 object-contain flex-shrink-0">
<div class="char-bubble maji-bubble flex-1">
<p>「Pre」って「前」という意味ですよねつまり、ツールを使う前に何かするってことですか</p>
</div>
</div>
<div class="flex items-start gap-4 mb-6">
<img src="./images/マスター-諭す-512×512-透過.png"
alt="マスター" class="w-16 h-16 object-contain flex-shrink-0">
<div class="char-bubble master-bubble flex-1">
<p>その通りです。AIが何かツールを使おうとしたとき、<strong>実行する前に「ちょっと待って」と割り込める</strong>ポイントです。</p>
</div>
</div>
<!-- 本文 -->
<div class="space-y-4">
<h3 class="text-xl font-bold text-gray-700 flex items-center gap-2">
<i data-lucide="target" class="w-5 h-5 text-blue-500"></i>
何ができるの?
</h3>
<ul class="space-y-2">
<li class="flex items-start gap-2">
<i data-lucide="check" class="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5"></i>
<span>特定のツールの使用を<strong>禁止</strong>できる</span>
</li>
<li class="flex items-start gap-2">
<i data-lucide="check" class="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5"></i>
<span>ツールに渡す<strong>入力内容を変更</strong>できる</span>
</li>
<li class="flex items-start gap-2">
<i data-lucide="check" class="w-5 h-5 text-green-500 flex-shrink-0 mt-0.5"></i>
<span>ユーザーに<strong>確認を求める</strong>ことができる</span>
</li>
</ul>
</div>
<!-- コード例 -->
<div class="mt-6">
<div class="flex items-center gap-2 mb-2">
<i data-lucide="code" class="w-5 h-5 text-purple-500"></i>
<span class="font-bold text-gray-700">このコードがやること</span>
</div>
<p class="text-gray-600 mb-3">
「Writeツールファイルを書き込む道具」が使われそうになったら、
<span class="font-bold text-red-600">許可しない</span>というルールを設定しています。
</p>
<div class="code-block">
<pre><code>hook.onPreToolUse((event) => {
if (event.toolName === 'Write') {
return { permissionDecision: 'deny' };
}
});</code></pre>
</div>
</div>
</div>
```
---
## 品質チェックリスト
作成後、以下を確認:
- [ ] 全ての技術用語に用語解説ボックスがある
- [ ] たとえ話が3つ以上ある
- [ ] 導入・中間・まとめにキャラクター対話がある
- [ ] 「まず覚える3つ」がある
- [ ] コード例の前に「このコードがやること」がある
- [ ] Lucide iconのみ使用絵文字なし
- [ ] 本気AIブランドカラーが適用されている
- [ ] キャラクター画像のパスが正しい
- [ ] スマホで読みやすい(レスポンシブ)
- [ ] 目次がフローティング表示される(デスクトップ)

View File

@ -0,0 +1,280 @@
# HTML構造ガイド
## 基本テンプレート
```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>【図解タイトル】- 本気AI</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
/* 本気AIブランドカラー */
:root {
--majiai-primary: hsl(343, 85%, 45%);
--majiai-secondary: hsl(213, 63%, 38%);
--majiai-gradient: linear-gradient(90deg, #24609E, #D60C52);
}
body {
font-family: 'Noto Sans JP', 'Inter', sans-serif;
}
/* ヘッダーグラデーション */
.header-gradient {
background: var(--majiai-gradient);
}
/* セクションカード */
.section-card {
background: white;
border-radius: 1rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
padding: 2rem;
margin-bottom: 2rem;
}
/* 用語解説ボックス */
.term-explain {
background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 100%);
border-left: 4px solid #9333ea;
padding: 1.5rem;
border-radius: 0.75rem;
margin: 1.5rem 0;
}
/* キャラクター吹き出し */
.char-bubble {
position: relative;
padding: 1.5rem;
border-radius: 1rem;
margin-left: 1rem;
}
.char-bubble::before {
content: '';
position: absolute;
left: -10px;
top: 20px;
border-width: 10px;
border-style: solid;
}
.maji-bubble {
background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
border: 2px solid #f59e0b;
}
.maji-bubble::before {
border-color: transparent #f59e0b transparent transparent;
}
.master-bubble {
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
border: 2px solid #3b82f6;
}
.master-bubble::before {
border-color: transparent #3b82f6 transparent transparent;
}
/* 重要度バッジ */
.badge-essential {
background: linear-gradient(135deg, #dc2626 0%, #ef4444 100%);
color: white;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.875rem;
font-weight: 600;
}
.badge-recommended {
background: linear-gradient(135deg, #2563eb 0%, #3b82f6 100%);
color: white;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.875rem;
font-weight: 600;
}
.badge-optional {
background: linear-gradient(135deg, #6b7280 0%, #9ca3af 100%);
color: white;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.875rem;
font-weight: 600;
}
/* コードブロック */
.code-block {
background: #1e293b;
color: #e2e8f0;
padding: 1.5rem;
border-radius: 0.75rem;
overflow-x: auto;
font-family: 'Fira Code', monospace;
font-size: 0.875rem;
line-height: 1.7;
}
/* 目次 */
.toc {
position: fixed;
right: 2rem;
top: 50%;
transform: translateY(-50%);
background: white;
padding: 1rem;
border-radius: 0.75rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
max-height: 80vh;
overflow-y: auto;
z-index: 50;
}
@media (max-width: 1280px) {
.toc { display: none; }
}
</style>
</head>
<body class="bg-gray-50">
<!-- ヘッダー -->
<header class="header-gradient text-white py-8">
<div class="max-w-4xl mx-auto px-4">
<h1 class="text-3xl md:text-4xl font-bold">【タイトル】</h1>
<p class="mt-2 text-lg opacity-90">サブタイトル</p>
</div>
</header>
<!-- メインコンテンツ -->
<main class="max-w-4xl mx-auto px-4 py-8">
<!-- セクション例 -->
</main>
<!-- Lucide初期化 -->
<script>
lucide.createIcons();
</script>
</body>
</html>
```
---
## Lucide Icon の使い方
### 基本構文
```html
<i data-lucide="icon-name" class="w-6 h-6"></i>
```
### よく使うアイコン
| 用途 | アイコン名 | コード |
|-----|----------|--------|
| 重要 | `alert-circle` | `<i data-lucide="alert-circle" class="w-6 h-6 text-red-500"></i>` |
| ヒント | `lightbulb` | `<i data-lucide="lightbulb" class="w-6 h-6 text-yellow-500"></i>` |
| チェック | `check-circle` | `<i data-lucide="check-circle" class="w-6 h-6 text-green-500"></i>` |
| 情報 | `info` | `<i data-lucide="info" class="w-6 h-6 text-blue-500"></i>` |
| 警告 | `triangle-alert` | `<i data-lucide="triangle-alert" class="w-6 h-6 text-orange-500"></i>` |
| 設定 | `settings` | `<i data-lucide="settings" class="w-6 h-6 text-gray-500"></i>` |
| コード | `code` | `<i data-lucide="code" class="w-6 h-6 text-purple-500"></i>` |
| ファイル | `file-text` | `<i data-lucide="file-text" class="w-6 h-6 text-blue-500"></i>` |
| フォルダ | `folder` | `<i data-lucide="folder" class="w-6 h-6 text-yellow-600"></i>` |
| 矢印 | `arrow-right` | `<i data-lucide="arrow-right" class="w-6 h-6"></i>` |
| ユーザー | `user` | `<i data-lucide="user" class="w-6 h-6"></i>` |
| ロック | `lock` | `<i data-lucide="lock" class="w-6 h-6 text-gray-600"></i>` |
| 鍵 | `key` | `<i data-lucide="key" class="w-6 h-6 text-yellow-500"></i>` |
| 許可 | `shield-check` | `<i data-lucide="shield-check" class="w-6 h-6 text-green-500"></i>` |
| 禁止 | `shield-x` | `<i data-lucide="shield-x" class="w-6 h-6 text-red-500"></i>` |
| 質問 | `help-circle` | `<i data-lucide="help-circle" class="w-6 h-6 text-blue-500"></i>` |
| 本 | `book-open` | `<i data-lucide="book-open" class="w-6 h-6 text-indigo-500"></i>` |
| 学習 | `graduation-cap` | `<i data-lucide="graduation-cap" class="w-6 h-6 text-purple-500"></i>` |
| ツール | `wrench` | `<i data-lucide="wrench" class="w-6 h-6 text-gray-600"></i>` |
| プレイ | `play` | `<i data-lucide="play" class="w-6 h-6 text-green-500"></i>` |
| 停止 | `square` | `<i data-lucide="square" class="w-6 h-6 text-red-500"></i>` |
### セクションヘッダーでの使用例
```html
<div class="section-card">
<div class="flex items-center gap-3 mb-6">
<div class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center">
<i data-lucide="shield-check" class="w-6 h-6 text-blue-600"></i>
</div>
<div>
<h2 class="text-2xl font-bold text-gray-800">セクションタイトル</h2>
<p class="text-gray-500">サブタイトル</p>
</div>
</div>
<!-- コンテンツ -->
</div>
```
---
## コード例の前の日本語解説
コードを見せる前に、必ず「このコードが何をするのか」を日本語で説明する。
### ❌ 悪い例
```html
<div class="code-block">
<pre><code>
hook.onPreToolUse((event) => {
if (event.toolName === 'Write') {
return { permissionDecision: 'deny' };
}
});
</code></pre>
</div>
```
### ✅ 良い例
```html
<div class="mb-4">
<div class="flex items-center gap-2 mb-2">
<i data-lucide="code" class="w-5 h-5 text-purple-500"></i>
<span class="font-bold text-gray-700">このコードがやること</span>
</div>
<p class="text-gray-600 ml-7">
「Writeツールファイルを書き込む道具が使われそうになったら、
<span class="font-bold text-red-600">許可しない</span>」というルールを設定しています。
</p>
</div>
<div class="code-block">
<pre><code>
hook.onPreToolUse((event) => {
if (event.toolName === 'Write') {
return { permissionDecision: 'deny' };
}
});
</code></pre>
</div>
```
---
## フローチャートの表現
```html
<div class="flex flex-col md:flex-row items-center justify-center gap-4 my-8">
<div class="bg-blue-100 px-6 py-4 rounded-xl text-center">
<i data-lucide="play" class="w-8 h-8 text-blue-600 mx-auto mb-2"></i>
<div class="font-bold">開始</div>
</div>
<i data-lucide="arrow-right" class="w-8 h-8 text-gray-400 hidden md:block"></i>
<i data-lucide="arrow-down" class="w-8 h-8 text-gray-400 md:hidden"></i>
<div class="bg-yellow-100 px-6 py-4 rounded-xl text-center">
<i data-lucide="shield-check" class="w-8 h-8 text-yellow-600 mx-auto mb-2"></i>
<div class="font-bold">チェック</div>
</div>
<i data-lucide="arrow-right" class="w-8 h-8 text-gray-400 hidden md:block"></i>
<i data-lucide="arrow-down" class="w-8 h-8 text-gray-400 md:hidden"></i>
<div class="bg-green-100 px-6 py-4 rounded-xl text-center">
<i data-lucide="check-circle" class="w-8 h-8 text-green-600 mx-auto mb-2"></i>
<div class="font-bold">完了</div>
</div>
</div>
```

View File

@ -0,0 +1,100 @@
# 技術用語→やさしい言葉 変換辞書
## 変換の原則
1. **機能で命名する**: 「何をするものか」で名前をつける
2. **身近な比喩を添える**: 日常生活での類似物を示す
3. **初出時に解説ボックス**: 最初に出てきたとき必ず説明
---
## よく使う変換表
### プログラミング基礎
| 技術用語 | やさしい言葉 | たとえ |
|---------|------------|--------|
| コールバック関数 | チェック係 | 「何かあったら呼んでね」と登録しておく処理。電話の折り返しと同じ |
| API | 窓口 | 銀行の窓口。決まった書類を出すと、決まったサービスを受けられる |
| インターフェース | 約束事 | 「この形式で頼めば対応します」というルール |
| パラメータ | 指示内容 | 注文票に書く内容 |
| 引数 | 渡す情報 | 窓口に提出する書類 |
| 戻り値 | 受け取る結果 | 窓口から返ってくる書類 |
| 変数 | 名前付きの箱 | ラベルを貼った引き出し |
| 関数 | 処理の塊 | 自動販売機(入れると出てくる) |
### 非同期・イベント
| 技術用語 | やさしい言葉 | たとえ |
|---------|------------|--------|
| 非同期処理 | 待たずに進む処理 | レストランで注文後、席で待つ。厨房の前で立ち尽くさない |
| イベント | きっかけ | ドアベルが鳴る、ボタンを押す |
| リスナー | 見張り役 | インターホンの前で待機している人 |
| トリガー | 発動条件 | 「このボタンを押したら」という条件 |
| フック | 割り込みポイント | 会社のセキュリティゲート |
| ハンドラ | 対応係 | イベントが起きたとき対応する担当者 |
### データ・構造
| 技術用語 | やさしい言葉 | たとえ |
|---------|------------|--------|
| JSON | データの書き方 | 住所録の書式 |
| オブジェクト | 情報のまとまり | 名刺1枚名前、電話番号、住所がセット |
| 配列 | 順番付きリスト | 番号札のついた待合室の椅子 |
| スキーマ | 設計図 | 入力フォームの項目一覧 |
| バリデーション | 入力チェック | 書類の不備確認 |
### セキュリティ・権限
| 技術用語 | やさしい言葉 | たとえ |
|---------|------------|--------|
| 認証 | 本人確認 | パスポートを見せる |
| 認可 | 許可 | 「この部屋に入っていいですよ」というOK |
| トークン | 入場券 | 映画のチケット |
| セッション | 接続状態 | 電話がつながっている間 |
| パーミッション | 権限 | 「閲覧OK、編集NG」のような許可レベル |
### AI・エージェント
| 技術用語 | やさしい言葉 | たとえ |
|---------|------------|--------|
| プロンプト | 指示文 | AIへの依頼書 |
| ストリーミング | 逐次表示 | 手紙を1文字ずつ読み上げる |
| コンテキスト | 文脈・前提情報 | 会話の流れ、今までの話 |
| エージェント | 自動で動くAI | 自分で判断して動く秘書 |
| ツール | AIが使える道具 | 秘書が使えるファイル、電話、パソコン |
---
## 用語解説ボックスの書き方
```html
<div class="term-explain">
<div class="flex items-start gap-4">
<i data-lucide="lightbulb" class="w-8 h-8 text-purple-500"></i>
<div>
<div class="term-word text-xl font-bold">「コールバック関数」とは?</div>
<div class="term-meaning text-lg mt-2">
難しそうな名前ですが、要は<span class="font-bold text-purple-600">「呼び出されたときに実行される処理」</span>のこと。<br>
電話の「コールバック(折り返し電話)」と同じで、「何かあったら呼んでね」と登録しておく処理です。<br>
<span class="font-bold">この図解では「チェック係」と呼びます。</span>
</div>
</div>
</div>
</div>
```
### CSS
```css
.term-explain {
background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 100%);
border-left: 4px solid #9333ea;
padding: 1.5rem;
border-radius: 0.75rem;
margin: 1.5rem 0;
}
.term-word {
color: #7c3aed;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB