create-svg
MDX記事に埋め込むSVG図版を作成する。モバイル視認性を最優先にした デザイントークン・レイアウトパターン・viewBox制約を適用。 Use when user asks to [SVGを作成, 図を作成, フロー図を作成, /create-svg].
SKILL.md.claude/skills/authoring/create-svg/SKILL.md
GitHub用途
MDX 記事に埋め込む SVG 図版(フロー図・比較図・マトリクス・カード等)を作成する。モバイル(375px 幅)での視認性を最優先に設計する。
事前チェック(省略禁止)
既存記事で raw <img> を見ても真似しない。既存の <img> は移行未完了の遺物であり、新規追加では必ず <ArticleImage> を使う。理由:
- MDX パイプラインは raw
<img>のstyle/width/height/className属性をすべて剥がす(sanitizer 仕様) - SVG ファイル内部の
style="width:100%"も<img src>経由では効かない(ブラウザの replaced element 扱い) <ArticleImage>は SVG 用にw-full max-w-2xl mx-autoコンテナとmax-width:100%;height:autoinline style を自動付与しレスポンシブ表示する
コミット前に /check-mdx --rules svg を必ず走らせる。Step 3.5 で詳細。過去事例: raw <img> + style="width:100%"(max-width:{viewBox}px 欠落)で commit 後、ブラウザで SVG が固定サイズ表示される問題が発生し再リライト(PR #43)。スキルに書いてあったルールを守っていれば起きなかった。
図と文章の役割分担(必読)
SVG は全体の流れ・構造を一目で把握させるためのもの。詳細な説明は本文(H2/H3 + 箇条書き)に任せる。
- 図に入れるもの: 要素の名称、フェーズ名、期間、到達目標の1行要約
- 図に入れないもの: 具体的なタスク・手順・箇条書き・補足説明
- 判断基準: 直下の本文と情報が重複するなら、図から削る
- SVG が不要なケース: 分岐構造が見出し(H3)で十分に表現できている場合はSVGを作らない(例: 不合格要因別の対策は見出しで分岐すれば足りる)
引数
/create-svg <対象記事のパス> <図の内容の説明>
| 引数 | 必須 | 説明 |
|---|---|---|
| 対象記事のパス | 任意 | SVG を配置する記事の MDX パス。省略時はカレントディレクトリ |
| 図の内容の説明 | 任意 | 何を図にするかの自然言語説明。省略時は対話で確認 |
モバイル視認性ルール(必須)
viewBox 制約
[!important] 記事+SNS 両用の図(
figure-N.svg)は固定キャンバス必須 SNS(記事・Instagram)にも使う図は viewBox を400 500(4:5・feed)に固定する(高さ可変は不可)。 YouTube 用の横長は別ファイルfigure-N--wide.svg(viewBox640 360・16:9・記事非埋込)として作る。 真実源 → figure-canvas-policy.md /config/figure-canvas.json。 ガードnpm run check-figure-canvasが逸脱を pre-commit で止める。縦の余白は要素拡大・サマリー・凡例で埋めて使い切る。Stories / Reels 流用: 4:5(400×500)で作った figure-*.svg は、9:16 キャンバス中央に配置するだけで IG Stories / Reels の静止画スライドとして使える(SVG 修正不要)。配置ルール → sns-image-policy.md §13。
以下の「横幅 ≤400・高さ可変」ルールは SNS に使わない記事専用の図にのみ適用する。
- 横幅: 400px 以下(モバイル 375px での縮小率 93% を確保)
- 縦幅: 制限なし(縦スクロールは自然)
- 横長レイアウトが不可避な場合のみ 500px まで許容(理由をコメントで明記)
最大表示幅の固定(PC でのテキスト巨大化防止・必須)
SVG ルート要素に style="max-width:{viewBox の横幅}px;width:100%" を必ず付与する。
<svg viewBox="0 0 380 520" style="max-width:380px;width:100%" ...>
理由: <ArticleImage> ラッパーは max-w-2xl(約 672px)のコンテナに SVG を配置し width:100% で表示する。max-width 指定がないと viewBox 幅より大きくレンダリングされ、テキスト・図形がPC 上で 1.5〜1.8 倍に拡大されて巨大化する(モバイルでは同問題は起きない)。
設計の前提: viewBox の寸法 = 画面上の最大表示寸法。SVG 内で font-size="13px" と書けば、PC では 13px として表示され、モバイルでは自然縮小(例: 375/380 ≈ 0.99×)で 12.9px になる。最小表示サイズはこの縮小後の値を基準に、下記「フォントサイズ」の最小値を守ればよい。
フォントサイズ
| 用途 | 最小値 | 推奨値 |
|---|---|---|
| 見出し・タイトル | 14px | 15-16px |
| 本文テキスト | 13px | 13-14px |
| 補足・キャプション | 11px | 11-12px |
| ラベル(STEP 等) | 11px | 11px |
最小値はモバイル縮小後(viewBox=400、画面幅=375 → 縮小率 0.94)の画面上 px を基準とする。viewBox 幅を 400px 以下に保ち、max-width を viewBox と同値に固定していれば、最大表示サイズは SVG 内 font-size と一致する。
レイアウト原則
- 横並びは 最大 2 カラム(3 カラム以上は縦に積む)
- 3 要素以上のフローは 縦積み
- 矩形の最小幅は 160px、最小高さは 50px
- 要素間の余白は 最低 15px
デザイントークン
カラーパレット(UI・SVG 共通の単一真実源)
サイト全体のセマンティックカラートークンは src/styles/globals.css の CSS 変数と Tailwind の brand / ink / positive / warn / danger に統一されている。SVG でも同じ値を使うことで UI と図版のブランド一貫性を保つ。
| セマンティック | 意味 | 背景(fill) | ストローク | テキスト |
|---|---|---|---|---|
brand(青系) |
情報・基本 | #e8f0fe |
#2e6da4 |
#1a3a5c |
positive(緑系) |
完了・成功・肯定 | #d0e8d0 |
#3a7d44 |
#1a3a5c |
warn(黄系) |
注意・強調 | #fff3cd |
#d4a017 |
#1a3a5c |
danger(赤系) |
警告・重要・否定 | #f8d7da |
#b22234 |
#1a3a5c |
| 用途 | 値 | Tailwind トークン |
|---|---|---|
| 本線・見出し | #222 |
ink-strong |
| 本文・補助線 | #555 |
ink-body |
| ラベル・注釈・弱い補助 | #8a8a8a |
ink-muted |
| 区切り線・枠線 | #d7d7d7 |
token-border |
| 弱背景 | #f5f5f5 |
surface |
SVG ファイル内の色指定ルール:
- 上記のリテラル hex を使う(
<img src>配信のため CSS 変数は効かない) - 必ずコメントで対応する semantic トークン名を併記する:
<rect fill="#e8f0fe" stroke="#2e6da4" /> <!-- brand-fill / brand --> <text fill="#222">見出し</text> <!-- ink-strong --> - サイトの特色を出すため、パレット外の色は使わない(既存 197 色のドリフトを再発させない)
- 原典画像の色を再現するより、セマンティックに最も近いトークンを選ぶ(赤が安全を示すなら
danger、工程完了ならpositive)
コントラスト比(WCAG 2.1 AA 準拠)
.claude/knowledge/design-system/design-system.md に従い、テキストと背景のコントラスト比は 4.5:1 以上を必須とする。
- 濃色背景は使用しない。すべてのボックスは上記の淡色 fill(
brand-fill/positive-fill/warn-fill/danger-fill)を使う - テキストは
#1a3a5c(見出し)または#555(本文) ink-muted(#8a8a8a)は背景が白または淡色の場合のみ使用可
タイポグラフィ
font-family は必ず明示指定する(未指定だとブラウザのデフォルト serif に落ちて本文と不整合になる)。本文は Inter + Noto Sans JP のため、SVG も同じチェーンを揃える:
<style>
text { font-family: Inter, "Noto Sans JP", "Hiragino Kaku Gothic ProN", sans-serif; fill: #222; }
</style>
- font-weight: bold(見出し・ボックスタイトル)、normal(本文・補足)
- font-size: 本文 13px、ラベル 12px、見出し 14px、補足 11px(最小)
推奨テンプレート(defs + class 方式)
インラインで色を書くと保守が難しい。<defs><style> に class を定義し、<rect class="..."> で参照する:
<svg width="400" height="260" viewBox="0 0 400 260"
xmlns="http://www.w3.org/2000/svg"
style="max-width:400px;width:100%"
role="img"
aria-label="[図の目的を 40-80 字で]">
<defs>
<style>
text { font-family: Inter, "Noto Sans JP", "Hiragino Kaku Gothic ProN", sans-serif; }
.t-title { font-size: 14px; font-weight: bold; fill: #222; } /* ink-strong */
.t-label { font-size: 12px; fill: #555; } /* ink-body */
.t-text { font-size: 13px; fill: #222; } /* ink-strong */
.box-brand { fill: #e8f0fe; stroke: #2e6da4; stroke-width: 1.5; }
.box-positive { fill: #d0e8d0; stroke: #3a7d44; stroke-width: 1.5; }
.box-warn { fill: #fff3cd; stroke: #d4a017; stroke-width: 1.5; }
.box-danger { fill: #f8d7da; stroke: #b22234; stroke-width: 1.5; }
.box-surface { fill: #f5f5f5; stroke: #d7d7d7; stroke-width: 1.5; }
</style>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
<polygon points="0,0 8,3 0,6" fill="#2e6da4"/>
</marker>
</defs>
<!-- 本体 -->
<rect class="box-brand" x="20" y="20" width="180" height="60" rx="6"/>
<text class="t-title" x="110" y="55" text-anchor="middle">見出し</text>
</svg>
禁止事項
- 濃色背景 + 白/薄色文字の組合せ(例:
<rect fill="#444"/><text fill="white">)はdesign-system.md §8違反。淡色 bg(box-brand等)+ 濃色文字(t-title/t-text)を使う - svg-tokens.json の colorsAllowList 外の hex 使用禁止(サイト特色の維持)
- font-family 未指定禁止(ブラウザデフォルト serif で描画され本文と不整合)
形状
- 角丸矩形:
rx="8"(メインボックス)、rx="6"(サブボックス) - ストローク幅:
1.5(標準)、1(区切り線) - 矢印マーカー定義:
<defs>
<marker id="arrow" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
<polygon points="0,0 8,3 0,6" fill="#2e6da4"/>
</marker>
</defs>
必須属性
- SVG ルート要素に
role="img"+aria-label="..."を付与 - SVG ルート要素に
style="max-width:{viewBox width}px;width:100%"を付与(PC で viewBox 幅を超えた拡大表示を防ぐ。詳細は「最大表示幅の固定」節) <style>ブロックでフォント定義を共通化
レイアウトパターン
パターン 1: 縦フロー(3 要素以上のプロセス)
viewBox="0 0 380 N"(N = 要素数 × 110 + 余白 40)
要素を縦に並べ、矢印で接続。各要素は幅 350px、左右余白 15px。 適用例: ワークフロー、手順、PDCA サイクル。
パターン 2: 横 2 カラム比較
viewBox="0 0 400 N"
左右に 2 つのボックスを並べて比較。各カラム幅 180px、間隔 20px、左右余白 10px。 適用例: 一般部門 vs 総監、Before/After。
パターン 3: マトリクス・表
viewBox="0 0 400 N"
セル幅は均等分割。ヘッダー行は濃色背景 + 白文字。 適用例: トレードオフマトリクス、評価表。
パターン 4: カード縦並び(フェーズ・ステップ)
viewBox="0 0 380 N"(N = カード数 × 200 + 余白)
カードを縦に積み、各カードにヘッダー帯(色付き)+ 本文 + 到達目標を含む。 カード間に矢印を配置。 適用例: 学習計画、プロジェクトフェーズ。
実行手順
Step 1: 要件の確認
- 対象記事のパスと図の目的を確認
- 図に含める情報を整理(テキスト量が多すぎないか確認)
- レイアウトパターン(上記 4 種)のどれが適切か判断
- 同じ記事の
img/に既存 SVG があれば命名規則(figure-{N}.svg)を確認
Step 2: SVG 作成
- viewBox を 400px 以下で設定
- デザイントークンを適用(カラー・フォント・形状)
- モバイル視認性ルールを遵守
content/site/{slug}/img/にfigure-{N}.svgとして保存
Step 3: 目視チェック(機械が判定できないものだけ)
寸法・属性・フォント・はみ出しは Step 3.5 の audit.mjs が機械判定する(viewBox 幅・style="max-width"・font-size 下限・role/aria-label・font-family・テキストクリップ・重なり)。ここで目視するのは機械に見えない意味の問題だけ:
- 濃色背景を使用していない(淡色背景のみ。IG 用の navy 帯とは別基準)
- 制作メモを SVG 内に書かない — 「※ 原図を概念図として再構成」「※ 本図はイメージです」等のメタコメントは不要。説明は alt 属性・本文で行う。SVG はコンテンツそのものに徹する
- 原典の図番号参照(図 N.N)を SVG 内に書かない — SVG 内のタイトルや補足に「図 7.6」のような PDF 表記を残さない(目次・SEO を汚染しない)
- 横並び要素 ≤ 2 カラム(情報密度の判断)
Step 3.5: 自動監査(必須・pre-commit で機械的に強制)
pre-commit フック(scripts/pre-commit-mdx.mjs)が staged の content/site/**/img/*.svg に対して auditSvgFile を自動実行し、HIGH 検出でコミットをブロックする。MEDIUM/LOW は warning として表示(ブロックしない)。
手動で事前確認したい場合:
# 単一ファイル(fail-on=HIGH で exit 1)
node .claude/skills/quality/check-mdx/scripts/rules/svg/audit.mjs --file=<作成した .svg> --fail-on=HIGH
# プロジェクト全体
node .claude/skills/quality/check-mdx/scripts/rules/svg/audit.mjs --severity=HIGH
検出対象: 文字クリップ(P1)・必須属性欠落(P3: role / aria-label / max-width)・viewBox 超過(P5)・フォント過小(P4)等。詳細は /check-mdx --rules svg(.claude/skills/quality/check-mdx/SKILL.md)を参照。
Step 4: MDX への配置
<ArticleImage
src="/posts/{slug}/img/figure-{N}.svg"
alt="図の説明"
/>
caption 属性は使用しない。 .claude/knowledge/reference/content-principles.md 「<ArticleImage> の caption は使わない」ルールに従い、alt のみ設定する。図の内容は本文で説明する。
Step 5: コミット
記事への埋込と図版の監査後に npm run build-svg-catalog を実行し、.claude/state/svg-catalog.json も差分へ含める。追加した図の embedded と fitStatus を確認する。カタログは SNS へ再利用する図を探すための派生台帳なので、本文だけを更新して古い一覧を残さない。
作成完了後、即座にコミットする(CLAUDE.md「コンテンツ編集時のコミット運用」に準拠)。
参照
.claude/knowledge/design-system/design-system.md— デザイン原則(コントラスト比 4.5:1 の根拠).claude/knowledge/design-system/design-system.md §8— 禁止パターン(純黒禁止・ライトグレー禁止等).claude/knowledge/reference/content-authoring.md— MDX コンポーネント・画像配信規約.claude/knowledge/reference/content-principles.md— コンテンツ品質ルールの真実源