zenn-audit
doboku-note の記事ページ(globals.css / page.tsx / tailwind.config.js)を Zenn 本番 CSS と比較し、タイポグラフィとレイアウトの drift を Critical / Warning / Matches / Intentional の 4 段階で報告する半年〜1年スパンの監査用途。日常レビュー(/review)とは独立した稀な dri
SKILL.md.claude/skills/dev/zenn-audit/SKILL.md
GitHub/zenn-audit — Zenn準拠監査(タイポグラフィ + レイアウト)
概要
doboku-note の記事本文スタイル(src/styles/globals.css)と記事ページレイアウト(src/app/docs/[...slug]/page.tsx + tailwind.config.js)を Zenn 本番CSSの最新値 と比較し、差分を Critical / Warning / Matches / Intentional の4段階で報告するスキル。
doboku-note は記事ページを Zenn 準拠としている。Zenn の CSS は時々更新され、doboku-note の globals.css / page.tsx / tailwind.config.js も時々触るため、半年〜1年スパンで drift が累積する。本スキルは手動比較(毎回60分以上)を自動化し、任意タイミングで確実に差分を検出できるようにする。
監査対象:
- Typography: globals.css
.prose-blog系ルール - Layout: page.tsx のコンテナ/main/article/aside クラス、tailwind.config.js の screens
使い方
/zenn-audit
オプションなし。全カテゴリ(typography + layout)を比較する。
実行手順
Step 1: Zenn の最新CSSをダウンロード
Zenn は Next.js アプリでハッシュ付きCSSバンドルを配信している。ハッシュは内容変更で変わるため、記事ページのHTMLから動的に抽出する。
# Zenn の代表記事から CSS リンクを抽出
curl -sL -A "Mozilla/5.0" "https://zenn.dev/zenn/articles/markdown-guide" -o /tmp/zenn.html
grep -oE 'href="https://static\.zenn\.studio/_next/static/css/[^"]+\.css"' /tmp/zenn.html \
| head -10 | sed 's/href="//;s/"$//' > /tmp/zenn_css_urls.txt
# 各 CSS を取得
for url in $(cat /tmp/zenn_css_urls.txt); do
curl -sL "$url" -o "/tmp/zenn_$(basename $url)"
done
# .znc(typography)を含む CSS と View_/Container_(layout)を含む CSS を特定
for f in /tmp/zenn_*.css; do
if grep -q '\.znc' "$f"; then cp "$f" /tmp/zenn_typography.css; fi
if grep -q 'View_columnsContainer\|Container_wide' "$f"; then cp "$f" /tmp/zenn_layout.css; fi
done
Section A: Typography Audit
Step 2: Zenn の重要値を抽出(タイポグラフィ)
以下の CSS プロパティを .znc 系ルールから /tmp/zenn_typography.css で抽出する。
| カテゴリ | セレクタ | プロパティ |
|---|---|---|
| Body | .znc |
line-height |
| 段落 | .znc p + p |
margin-top |
| リスト | .znc ul, .znc ol |
margin, line-height, padding-left |
| リスト項目 | .znc li |
margin |
| ネストリスト | .znc ul ul, .znc ul ol |
margin |
| 見出し直後 | .znc h1+p 〜 .znc h6+p |
margin-top |
| blockquote | .znc blockquote |
font-size, margin, border-left, padding |
| table | .znc table |
font-size, line-height, margin |
| code | .znc code |
font-size, padding |
| hr | .znc hr |
margin |
| link | .znc a, .znc a:hover |
color, text-decoration |
抽出コマンド例:
grep -oE '\.znc\{[^}]*\}' /tmp/zenn_typography.css
grep -oE '\.znc p\+p\{[^}]*\}' /tmp/zenn_typography.css
grep -oE '\.znc ul[^{]*\{[^}]*\}|\.znc ol[^{]*\{[^}]*\}' /tmp/zenn_typography.css
grep -oE '\.znc h[1-6]\+p[^{]*\{[^}]*\}' /tmp/zenn_typography.css
grep -oE '\.znc blockquote\{[^}]*\}' /tmp/zenn_typography.css
Step 3: doboku-note の現在値を抽出(タイポグラフィ)
src/styles/globals.css を Read し、.prose-blog 系ルールを読み取る。Tailwind の @apply ディレクティブは以下の換算表で px / rem に変換して比較する。
| Tailwind | 実値 |
|---|---|
mb-1 / mt-1 |
0.25rem (4px) |
mb-2 / mt-2 |
0.5rem (8px) |
mb-3 / mt-3 |
0.75rem (12px) |
mb-4 / mt-4 |
1rem (16px) |
mb-5 / mt-5 |
1.25rem (20px) |
mb-6 / mt-6 |
1.5rem (24px) |
mb-8 / mt-8 |
2rem (32px) |
mb-10 / mt-10 |
2.5rem (40px) |
mb-12 / mt-12 |
3rem (48px) |
mb-16 / mt-16 |
4rem (64px) |
Section B: Layout Audit
Step 4: Zenn の重要値を抽出(レイアウト)
/tmp/zenn_layout.css から以下のレイアウトルールを抽出する。
| カテゴリ | セレクタ | プロパティ |
|---|---|---|
| コンテナ幅 | .Container_wide |
max-width |
| コンテナpadding | .Container_common + 全 @media |
padding |
| カラム構造 | .View_columnsContainer + @media |
display, justify-content |
| メインカラム幅 | .View_content + @media |
width |
| サイドバー幅 | .View_sidebarContainer + @media |
width, display |
| 記事カード | .View_main + @media |
border, border-radius, box-shadow, padding |
| 記事タイトル | .ArticleHeader_title |
max-width, margin |
| サイドバーsticky | .ArticleSidebar_sticky |
position, top |
| html font-size | html + @media |
font-size |
| ページbg padding | .View_container |
padding-bottom, border-top |
抽出コマンド例:
grep -oE '\.Container_wide[^{]*\{[^}]*\}' /tmp/zenn_layout.css
grep -oE '\.Container_common[^{]*\{[^}]*\}' /tmp/zenn_layout.css
grep -oE '\.View_sidebarContainer[^{]*\{[^}]*\}' /tmp/zenn_layout.css
grep -oE '\.View_main[a-zA-Z_]*__[a-zA-Z0-9]+[^{]*\{[^}]*\}' /tmp/zenn_layout.css
# 全 media queries 内の Container_common / View_main / html
python -c "
import re
with open('/tmp/zenn_layout.css') as f:
css = f.read()
for m in re.finditer(r'@media[^{]+\{(?:[^{}]|\{[^{}]*\})*\}', css):
block = m.group(0)
if 'Container_common' in block or 'View_main' in block or 'View_sidebarContainer' in block or 'html{' in block:
print(block[:400])
print()
"
Step 5: doboku-note の現在値を抽出(レイアウト)
複数ファイルから値を抜き取る:
src/components/layout/TwoColumnShell.tsx(2カラムレイアウト値の真実源)を Read:max-w-\[(\d+)px\]→ コンテナ max-width<aside>の幅ユーティリティ(現行w-[316px]=316px) → サイドバー幅gap-(\d+)またはgap-\[(\d+)px\](現行gap-10=40px) → カラム間ギャップzenn-desktop:block→ サイドバー可視化境界(≥993px)
src/app/docs/[...slug]/page.tsxを Read:<article>のrounded-,shadow-,py-,px-,zenn-desktop:px-,max-zenn-*:*→ カードデザイン(現行px-10/zenn-desktop:px-11/max-zenn-sp:px-[var(--article-gutter-sp)])pb-(\d+)onflex-grow→ ページ下部余白
tailwind.config.jsを Read:extend.screens→ Zenn ブレイクポイント確認(zenn-tiny401,zenn-sp577,zenn-tablet769,zenn-desktop993)
src/styles/globals.cssを Read:.prose-blog h1→max-width値--article-gutter-sp→ モバイル記事カード横 gutter(現行 16px・details のフルブリード相殺と連動)
Step 6: レイアウト差分を分類
🔴 Critical: 読みやすさ・UXに直結
- container max-width ずれ
- sidebar visibility breakpoint ずれ
- card padding が極端にずれる
- mobile full-bleed 設定なし
🟡 Warning: 整合性
- sidebar width 10px以上ずれ
- gap ずれ
- container padding の段階ずれ
- card border-radius ずれ
✅ Matches: 値が一致
⚪ Intentional: intentional-deviations.yml に登録された項目
Step 7: レポート出力
出力フォーマット
# Zenn Audit Report
**実行日時**: {ISO timestamp}
**Zenn CSS source**: {url}
**doboku-note sources**:
- src/styles/globals.css
- src/app/docs/[...slug]/page.tsx
- tailwind.config.js
## サマリー
- 🔴 Critical: {n}
- 🟡 Warning: {n}
- ✅ Matches: {n}
- ⚪ Intentional: {n}
## Typography セクション
### 🔴 Critical Deviations (must fix)
(なければ「なし」)
### 🟡 Warning (consider fixing)
(なければ「なし」)
### ✅ Matches
- body line-height: 1.9
- p+p margin-top: 1.5em
- h*+p margin-top: 0.3em
- ul/ol line-height: 1.7
- li margin: 0.4rem 0
- ul padding-left: 1.8em
- ol padding-left: 1.7em
- link style: hover underline only
### ⚪ Intentional (allowlisted)
- font-size body: 17px (zenn 16px) — 日本語可読性優先
- h1/h2/h3/h4 margin-top, style: 左アクセントバー設計のため
- blockquote: callout風デザイン
- table: modern design
- code: ピンク文字+ボーダー
## Layout セクション
### 🔴 Critical Deviations (must fix)
(なければ「なし」)
### 🟡 Warning (consider fixing)
(なければ「なし」)
### ✅ Matches
- container max-width: 1200px
- sidebar width: 288px (w-72)
- sidebar visibility: ≥993px (zenn-desktop)
- gap: 30px
- card border-radius: 4px
- card border: 1px
- card shadow: none
- card padding: py-10 px-10 (40px)
- mobile full-bleed at ≤576px (max-zenn-sp)
- mobile card padding: 35px vertical / 16px horizontal (--article-gutter-sp, ≤576px 統一)
- container responsive padding: 14/20/25/40px at Zenn breakpoints
- H1 max-width: 780px
- page bottom padding: pb-16 (64px ≒ 4rem)
### ⚪ Intentional (allowlisted)
- H1 border-bottom: 2px blue (zenn 1px gray) — ブランドアイデンティティ
- html font-size: 17px fixed (zenn 16/15 responsive)
- text-autospace: 未採用
## 次のアクション
Critical が 1件以上ある場合:
1. 修正案を該当ファイルに適用するか確認
2. Edit ツールで修正
3. `npm run dev` で主要ページを確認し回帰がないかチェック
Critical が 0 件の場合: 監査完了
Step 8: 修正の提案
- Critical が 1 件以上: 具体的な diff を提示し、適用するかユーザーに確認
- Warning のみ: 報告のみ。自動修正しない
- 全て Matches/Intentional: 「監査完了、差分なし」と報告
重要: 自動で globals.css / page.tsx / tailwind.config.js を修正しない。必ずユーザー確認を経る。
意図的逸脱の管理
intentional-deviations.yml に登録された項目は比較から除外される。新しく意図的逸脱を追加したい場合はこのファイルを更新する。
ファイル形式:
- key: "項目名"
doboku: "doboku-noteの値"
zenn: "Zennの値"
reason: "逸脱する理由"
doboku-note 固有の注意点
- Zenn CSS バンドルのファイル名は変更される(ハッシュベース)ため、ハッシュをハードコードしない
- Zenn CSS には複数ファイルある。Typography は
.zncを含むファイル、Layout はView_columnsContainer/Container_wideを含むファイルに分離 - doboku-note は
@tailwindcss/typographyプラグインを使っており、@applyされていないプロパティも prose プラグイン由来で適用されている可能性がある - Zenn の
html { font-size: 15px }は@media (max-width: 400px)でのみ発動 - doboku-note は
zenn-tiny/zenn-sp/zenn-tablet/zenn-desktopカスタムブレイクポイント をtailwind.config.jsのextend.screensで追加している(Zenn の 401/577/769/993 と一致) - Layout 比較では
xl:/lg:などの Tailwind デフォルトブレイクポイントと Zenn の実ブレイクポイント(max-width 992px 等)の関係に注意。doboku-note はzenn-desktop:(993px) を使うことで pixel-perfect な一致を実現している
実行タイミング
- 定期: 半年に1回(Q1, Q3 など)
- CSS/レイアウト変更時:
src/styles/globals.css/src/app/docs/[...slug]/page.tsx/tailwind.config.jsを大きく触ったあと - 記事フィードバック時: 読みにくさやレイアウト崩れの指摘を受けたとき
- Zenn 仕様の追従: Zenn のデザイン変更情報が流れてきたとき
関連
- Plan file:
C:\Users\m004195\.claude\plans\graceful-percolating-gray.md(2026-04-13 の初回整備・旧 Windows 環境の履歴。現存しない可能性あり) - Typography source:
src/styles/globals.cssL17-213 - Layout source:
src/app/docs/[...slug]/page.tsxL213-315 - Breakpoint source:
tailwind.config.jsextend.screens - Zenn OSS 参考: https://github.com/zenn-dev/zenn-editor/tree/canary/packages/zenn-content-css/src
- Zenn 本番CSS URL:
https://static.zenn.studio/_next/static/css/{hash}.css(ハッシュは動的取得)