mcpField
P
pencilplaybook

pencilplaybook

github.com/stevembarclayデザイン・UI5361 回インストール31 週間前に更新
リポジトリ

pencilplaybook について

pencilplaybookは、セットアップ手順と再利用可能なレイアウトのひな形で、Pencilの画面設計を支援するスキルです。アプリやマーケティングページを設計する人向けで、キャンバス寸法の確認、デザインガイドライン、ブランド変数の手順を備えています。

主な機能

  1. 01セットアップと導入手順
  2. 02再利用可能な9種のレイアウトひな形
  3. 03キャンバス寸法の確認
  4. 04デザインガイドラインとトークンの手順

活用シーン

  1. 01アプリのダッシュボードやデータ表の作成
  2. 02390×844pxのモバイル画面の設計
  3. 03マーケティングページを作成し390px幅で確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/stevembarclay/pencilplaybook --skill pencilplaybook

インストール後、Claude Code で/pencilplaybookを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

.gitignore
CHANGELOG.md
LICENSE
onboarding.md
README.md
setup.md
.claude/skills/best-in-world-strategy/references/
question-bank.md
.claude/skills/skill-creator/
LICENSE.txt
.claude/skills/skill-creator/scripts/
init_skill.py
quick_validate.py
package_skill.py
presets/
grove.json
ember.json
material.json
midnight.json
bloom.json
volt.json
minimal.json
references/
tool-reference.md

詳細

Pencil Pro

主な解決ルール

このスキルは初回使用前に設定する必要があります。

ユーザーが「run the PencilPlaybook setup wizard」と言った場合、または PencilPlaybook のセットアップや設定を依頼した場合: → .claude/skills/pencilplaybook/setup.md を読み、そこに記載された指示に正確に従ってください。

ユーザーが「build my first screen with PencilPlaybook」と言った場合、またはデザインの開始を依頼した場合: → .claude/skills/pencilplaybook/onboarding.md を読み、そこに記載された指示に正確に従ってください。

設定済みの解像度:(設定するにはセットアップを実行してください)

既存の .pen ファイル内の画面ルートが設定済みの解像度と一致しない場合は、編集前にその旨を伝えてください。サイズの誤ったキャンバス上で、その差異を指摘せずに作業を進めないでください。

よくある例外 — マーケティングページ: アプリの解像度にかかわらず、1440px でデザインしてください。マーケティングページはさまざまなブラウザー幅で閲覧されるため、1440px でデザインし、390px で確認してください。


セッション開始時(Pencil セッションごと)

1. get_editor_state()                           — check active document and selection
2. open_document("path/to/your-file.pen")       — open target file
3. get_guidelines(topic="web-app")              — load design guidelines
4. set_variables(<token map below>)             — inject brand tokens
5. get_variables()                              — confirm tokens stored
6. snapshot_layout()                            — verify canvas dimensions

トークンマップ — 毎回のセッション開始時に、このオブジェクトを使って set_variables を実行してください。変数は Claude Code のセッション間で保持されない場合があります。

{
  "color-primary":        "YOUR_HEX",
  "color-primary-dark":   "YOUR_HEX",
  "color-accent":         "YOUR_HEX",
  "color-background":     "YOUR_HEX",
  "color-surface":        "YOUR_HEX",
  "color-border":         "YOUR_HEX",
  "color-text":           "YOUR_HEX",
  "color-text-muted":     "YOUR_HEX",
  "color-success":        "YOUR_HEX",
  "color-warning":        "YOUR_HEX",
  "color-error":          "YOUR_HEX",
  "font-sans":            "YOUR_FONT",
  "font-mono":            "YOUR_FONT",
  "font-serif":           "YOUR_FONT",
  "spacing-card":         "24",
  "spacing-gap-sm":       "8",
  "spacing-gap-md":       "16",
  "spacing-gap-lg":       "24",
  "spacing-gap-xl":       "32",
  "content-max-width":    "YOUR_VALUE",
  "sidebar-width":        "YOUR_VALUE"
}

set_variables の後、get_variables() を呼び出して、すべてのトークンが保存されていることを確認してください。


スキャフォールドスクリプト

よく使われるレイアウトのアーキタイプを網羅した、9 つのスキャフォールドスクリプトがあります。使用前にセットアップウィザードを実行して、以下のサイズと色の値を入力してください。


スキャフォールド A — アプリダッシュボード

メトリクス、KPI、アクティビティフィード、モニタリング

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG", display:"flex", flexDirection:"column"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:32})
statsBar=I("pageArea", {name:"StatsBar", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:80, bg:"STATS_BG", display:"flex", alignItems:"center", gap:24, px:32})
contentWrap=I("pageArea", {name:"ContentWrap", y:144, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_A, display:"flex", justifyContent:"center", p:32})
contentInner=I("contentWrap", {name:"ContentInner", width:SCAFFOLD_CONTENT_MAX, display:"flex", flexDirection:"column", gap:24})

スキャフォールドの実行後:snapshot_layout() — pageArea.width と contentInner.width が正しいことを確認してください。


スキャフォールド B — アプリのリスト/キュー

テーブル、アセットライブラリ、キュー、ユーザー管理

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:32})
commandStrip=I("pageArea", {name:"CommandStrip", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:52, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", gap:16, px:32})
tableWrap=I("pageArea", {name:"TableWrap", y:116, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_B, display:"flex", justifyContent:"center", px:32, pt:24})
tableInner=I("tableWrap", {name:"TableInner", width:SCAFFOLD_CONTENT_MAX, display:"flex", flexDirection:"column", gap:0})
tableHeader=I("tableInner", {name:"TableHeader", width:SCAFFOLD_CONTENT_MAX, height:40, bg:"TABLE_HEADER_BG", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center"})

スキャフォールド C — アプリの詳細/レビュー

2 パネルの詳細ビュー、レビューのワークフロー、左右並列のレイアウト

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR"})
actionBar=I("pageArea", {name:"ActionBar", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:56, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR"})
contentWrap=I("pageArea", {name:"ContentWrap", y:120, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_C, display:"flex", justifyContent:"center"})
contentInner=I("contentWrap", {name:"ContentInner", width:SCAFFOLD_CONTENT_MAX, height:SCAFFOLD_CONTENT_HEIGHT_C, display:"flex", gap:0})
leftPanel=I("contentInner", {name:"LeftPanel", width:SCAFFOLD_LEFT_PANEL, height:SCAFFOLD_CONTENT_HEIGHT_C, bg:"SURFACE_COLOR", borderRight:"1px solid BORDER_COLOR"})
rightPanel=I("contentInner", {name:"RightPanel", width:SCAFFOLD_RIGHT_PANEL, height:SCAFFOLD_CONTENT_HEIGHT_C, bg:"PAGE_BG", p:24, display:"flex", flexDirection:"column", gap:20})

注:左右の分割比率はデフォルトで約 40/60 です。機能に合わせて調整してください。よく使われる分割比率は 40/60、38/62、50/50 です。


スキャフォールド D — マーケティングページ

ランディングページ、製品ページ — アプリのキャンバスにかかわらず、常に幅 1440px

navbar=I("root", {name:"Navbar", width:1440, height:72, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:80})
heroSection=I("root", {name:"HeroSection", y:72, width:1440, height:600, bg:"HERO_BG", display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center"})
heroContent=I("heroSection", {name:"HeroContent", width:SCAFFOLD_MARKETING_CONTENT_MAX, display:"flex", flexDirection:"column", alignItems:"center", gap:24})
section1=I("root", {name:"Section1", y:672, width:1440, height:480, bg:"SURFACE_COLOR", display:"flex", flexDirection:"column", alignItems:"center", py:80})
section1Content=I("section1", {name:"Section1Content", width:SCAFFOLD_MARKETING_CONTENT_MAX})

マーケティングページはモバイルファーストです。1440px でデザインし、引き渡し前に幅 390px でレイアウトを確認してください。


スキャフォールド E — モーダル/ダイアログ

確認、破壊的な操作、クイック編集フォーム、サイドピークパネル

まずスキャフォールド A、B、または C を実行してください。その後、このモーダルを pageArea 上に重ねて追加します。ルート内には挿入しないでください。

backdrop=I("pageArea", {name:"ModalBackdrop", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"rgba(0,0,0,0.48)", display:"flex", alignItems:"center", justifyContent:"center"})
modal=I("backdrop", {name:"Modal", width:480, bg:"SURFACE_COLOR", borderRadius:8, border:"1px solid BORDER_COLOR", display:"flex", flexDirection:"column", overflow:"hidden"})
modalHeader=I("modal", {name:"ModalHeader", height:56, px:24, display:"flex", alignItems:"center", justifyContent:"space-between", borderBottom:"1px solid BORDER_COLOR"})
modalBody=I("modal", {name:"ModalBody", px:24, py:20, display:"flex", flexDirection:"column", gap:16})
modalFooter=I("modal", {name:"ModalFooter", height:60, px:24, display:"flex", alignItems:"center", justifyContent:"flex-end", gap:12, borderTop:"1px solid BORDER_COLOR"})

スキャフォールドの実行後:snapshot_layout() — モーダルが表示され、中央に配置されていることを確認してください。用途に応じてモーダルの幅を調整してください:380px(コンパクトな確認)、480px(標準フォーム)、600px(幅広フォーム)、720px(詳細/プレビュー)。


スキャフォールド F — ウィザード/ステッパー

複数ステップのフォーム、オンボーディングフロー、セットアップ手順、チェックアウト

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:32})
stepperBar=I("pageArea", {name:"StepperBar", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:60, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"center"})
contentWrap=I("pageArea", {name:"ContentWrap", y:124, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_F, display:"flex", justifyContent:"center", px:32, pt:32})
contentInner=I("contentWrap", {name:"ContentInner", width:640, display:"flex", flexDirection:"column", gap:24})
actionFooter=I("pageArea", {name:"ActionFooter", y:SCAFFOLD_WIZARD_FOOTER_Y, width:SCAFFOLD_PAGE_AREA_WIDTH, height:72, bg:"SURFACE_COLOR", borderTop:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"space-between", px:32})

注:ContentInner の幅はデフォルトで 640px です。入力に集中できる単一カラムのフォームです。戻るボタンは左側、次へ/送信ボタンは ActionFooter 内の右側に配置します(justifyContent:"space-between")。


スキャフォールド G — モバイル画面

390×844px(iPhone 14 標準)。すべてのモバイル画面に使用します — 値はハードコードされており、セットアップ値は不要です。

statusBar=I("root", {name:"StatusBar", width:390, height:44, bg:"PAGE_BG"})
navBar=I("root", {name:"NavBar", y:44, width:390, height:56, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", px:16})
scrollContent=I("root", {name:"ScrollContent", y:100, width:390, height:688, bg:"PAGE_BG", display:"flex", flexDirection:"column", overflow:"hidden"})
contentPad=I("scrollContent", {name:"ContentPad", width:390, display:"flex", flexDirection:"column", gap:16, px:16, pt:16})
bottomNav=I("root", {name:"BottomNav", y:788, width:390, height:56, bg:"SURFACE_COLOR", borderTop:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"space-around"})

注:システムのクロームを表示しない場合は、statusBar を削除し、navBar.y=0 に設定してください。タブナビゲーションのないアプリでは bottomNav を削除してください。このスキャフォールド内のタッチターゲットは 44×44px 以上にしてください。


スキャフォールド H — フォーム/データ入力

設定ページ、プロフィール編集、大量のデータ入力 — 中央揃えの単一カラムフォーム

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"space-between", px:32})
formWrap=I("pageArea", {name:"FormWrap", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_H, display:"flex", justifyContent:"center", px:32, pt:32})
formInner=I("formWrap", {name:"FormInner", width:600, display:"flex", flexDirection:"column", gap:28})
formSection=I("formInner", {name:"FormSection1", display:"flex", flexDirection:"column", gap:16})
formActions=I("formInner", {name:"FormActions", display:"flex", gap:12, justifyContent:"flex-end"})

注:FormInner の幅はデフォルトで 600px です。シンプルなフローでは 480px、幅広の 2 カラムレイアウトでは 800px を使用してください。関連するフィールドをまとめるには、formInner 内に FormSection ノードを追加します。


スキャフォールド I — 空の状態/オンボーディングのステップ

データがないときのビュー、初回使用時のプロンプト、機能の紹介、空白状態の画面

sidebar=I("root", {name:"Sidebar", width:SCAFFOLD_SIDEBAR_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, bg:"SIDEBAR_BG"})
pageArea=I("root", {name:"PageArea", width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CANVAS_HEIGHT, x:SCAFFOLD_SIDEBAR_WIDTH, bg:"PAGE_BG"})
pageHeader=I("pageArea", {name:"PageHeader", width:SCAFFOLD_PAGE_AREA_WIDTH, height:64, bg:"SURFACE_COLOR", borderBottom:"1px solid BORDER_COLOR"})
emptyCenter=I("pageArea", {name:"EmptyCenter", y:64, width:SCAFFOLD_PAGE_AREA_WIDTH, height:SCAFFOLD_CONTENT_HEIGHT_H, display:"flex", alignItems:"center", justifyContent:"center"})
emptyContent=I("emptyCenter", {name:"EmptyContent", width:400, display:"flex", flexDirection:"column", alignItems:"center", gap:20})
illustrationArea=I("emptyContent", {name:"IllustrationArea", width:200, height:160, borderRadius:12, bg:"SURFACE_COLOR", border:"1px solid BORDER_COLOR", display:"flex", alignItems:"center", justifyContent:"center"})
textStack=I("emptyContent", {name:"TextStack", width:400, display:"flex", flexDirection:"column", alignItems:"center", gap:8})
emptyActions=I("emptyContent", {name:"EmptyActions", display:"flex", gap:12})

注:イラストを生成するには、IllustrationArea を G("illustrationArea", "ai", "your prompt") に置き換えてください。空の状態のコピーは短くまとめてください:見出しを 1 つ(16~18px)、補足文を 1 行(14px、ミュートカラー)、主要な CTA を 1 つ。


主要なワークフロー

ワークフロー 1:キャンバスの調査

使用する場面:「この .pen ファイルには何がある?」と確認するとき、またはしばらく作業していなかったファイルを編集する前。

1. open_document("path/to/file.pen")
2. get_editor_state()                         — get root node IDs
3. batch_get(patterns=["*"])                  — read full node tree
4. snapshot_layout()                          — see computed dimensions

batch_get の出力を読み、どの画面があり、どのような寸法で、どのトークンが使われていて、何に明確な名前が付いているか、付いていないかを把握します。変更を加える前に、全体像を頭に入れておきます。

キャンバスの寸法を確認: 設定済みの解像度と一致しない画面は、レガシーキャンバスか、別の対象向けに作られたものです。記録しておきます。再設計する場合は、上記のスキャフォールドを使って対象の解像度で作り直します。


ワークフロー 2:デザイントークンの反映

使用する場面:ブランドカラーやフォントが変更され、既存の .pen ファイル全体に反映する必要があるとき。

ステップ 1 — 現在の値を監査:

search_all_unique_properties(parentIds=["root"])

古いトークン値が使われている箇所をすべて探します。

ステップ 2 — 置換:

replace_all_matching_properties(
  parentIds=["root"],
  matchProperty="bg",
  matchValue="#OLD_VALUE",
  newValue="#NEW_VALUE"
)

変更されたトークンを使っているプロパティタイプ(bg、color、borderColor など)ごとに 1 回実行します。

ステップ 3 — スクリーンショットで確認:

get_screenshot(nodeId="[root or key screen id]")

トークン反映の一般的なケース:

  • 色の変更:bg、color、borderColor、fill を個別に置換します
  • フォントの変更:すべてのテキストノードの fontFamily を置換します
  • 余白の変更:特定の gap、p、px、py の値を置換します。異なる構造上の理由で多数の要素が同じ数値を共有している場合があるため、注意してください

ワークフロー 3:キャンバスの空間管理

使用する場面:既存の .pen ファイルに新しい画面を追加するとき。

find_empty_space_on_canvas(
  direction="right",
  desiredWidth=SCAFFOLD_CANVAS_WIDTH,
  desiredHeight=SCAFFOLD_CANVAS_HEIGHT
)

返された x/y 座標を、新しい画面のルートフレームの位置として使用します。

複数画面の .pen ファイルにおける規則:

  • 画面は左から右へ並べ、1 列につき 1 画面にします
  • 画面間は横方向に約 120px 空けます
  • 同じ画面の関連する状態は、縦方向に約 80px 空けて積み重ねます
  • 画面には "Screen N — [Name] ([state])" の形式で名前を付けます。例:"Screen 2 — User Profile (edit mode)"

ワークフロー 4:スタイルガイドの取得(新しいページタイプ)

アプリでこれまで設計したことのないページタイプを作るときに使用します。

1. get_style_guide_tags()
2. get_style_guide(tags=["enterprise", "dashboard", "minimal", "professional"])

スタイルガイドはインスピレーションを得るためのものです。スタイル上の競合があれば、デザインシステムを優先します。取り入れるもの:構成上の規律、余白のパターン、データ密度の工夫。取り入れないもの:確立済みのビジュアル言語と矛盾するもの。


ワークフロー 5:プロパティの一括検査

使用する場面:一貫性を保つために .pen ファイルを監査するとき、またはトークンの置換を準備するとき。

search_all_unique_properties(
  parentIds=["root"],
  propertyNames=["bg", "color", "fontFamily", "fontSize", "gap"]
)

トークン化すべきハードコードされた 16 進数値、規則から外れたフォントサイズ、グリッドを崩す余白値の検出に使用します。


ワークフロー 6:バージョンスナップショット(作業の保護)

使用する場面:大規模な再設計やリファクタリングの前、またはファイルを切り替えるとき。

プロンプトテンプレート:

Using PencilPlaybook, create a version snapshot comment at the top of the
current canvas. Include: current date/time, list of all screens, active
design tokens summary, and a short note of what is about to change.

これは簡易的な取り消し用チェックポイントとして機能し、複数の .pen ファイル間の一貫性を保つのに役立ちます。次の作業の前に実行します。

  • 大規模なファイル全体へのトークン反映
  • 構造的なリファクタリング(レイアウトの変更、パネルの分割)
  • 別のセッションや共同作業者への引き継ぎ

ツールリファレンス

クイックリファレンス — パラメーターの詳細は references/tool-reference.md を参照してください。

ツール使用する場面
get_editor_state毎セッションの開始時
open_document.pen ファイルを開くとき、または空のキャンバスとして "new" を指定するとき
get_guidelinesデザインルールを読み込むとき(アプリ画面には topic="web-app" を指定)
get_style_guide_tags利用可能なインスピレーションタグを確認するとき
get_style_guide新しいページタイプのインスピレーションを取得するとき
batch_getノードツリーを読み取るとき — 調査に使用
batch_designノードの作成、更新、コピー、移動、削除
snapshot_layout各スキャフォールドの後に計算済みの寸法を確認
get_screenshot主要な作業手順ごとにビジュアルを確認
get_variables現在のトークン状態を確認
set_variablesブランドトークンを注入
find_empty_space_on_canvas重なりを避けて新しい画面を配置
search_all_unique_propertiesトークン置換の前にすべての値を監査
replace_all_matching_propertiesトークンを一括置換
export_nodes開発者に引き継ぐ前に PNG/PDF としてエクスポート

画面の命名とバージョン管理

ファイル内の命名:

  • "Screen N — [Feature] ([state])"
  • "Screen 1 — Dashboard (empty)" / "Screen 1 — Dashboard (populated)"
  • イテレーション:接尾辞 [v2 post-feedback] を追加してください。新しいファイルは作成しないでください

イテレーションごとに新しい .pen ファイルを作成しないでください。 バージョン付きの画面は同じファイルに追加してください。

ファイルの命名:

mockups/<feature>-v1.pen        — initial design
mockups/<feature>-redesign.pen  — full redesign (significant divergence)

ステークホルダーとの共有後に .pen ファイルの名前を変更するのは避けてください。引き継ぎドキュメントの参照が壊れます。


知覚に基づくデザインのデフォルト

Pencil でコンポーネントを構築するためのクイックリファレンステーブルです。科学的根拠に基づくデフォルト値です。デザインシステムで別途指定されていない限り、これらを使用してください。

タイポグラフィ
プロパティサイズ範囲デフォルト値根拠
文字間隔56px以上(ディスプレイ)−0.03em大きなサイズではカウンターにゆとりが生まれます
文字間隔32–48px(見出し)−0.015em適度に詰めます
文字間隔14–18px(本文)0(標準)書体はこの範囲に最適化されています
文字間隔10–12px(キャプション)+0.015em小さなサイズではカウンターが詰まります
行の高さ本文最低1.5×WCAG SC 1.4.12
行の高さ見出し1.1–1.2×視覚的な密度を高めるため、狭めにします
行の長さ本文45–75文字(65chが最適)Baymard Institute
最小フォントサイズすべてのテキスト10px10px未満は画面上で判読できません
色
プロパティデフォルト値根拠
無効時の不透明度40%50%ではゴーストのような表示になり、目を引きます。40%なら十分に目立たなくなります。(MD3、Workday)
ホバー時の明度差最低8%8%未満の変化は、ほとんどのモニターで知覚できません。(NNGroup)
ダークサーフェス上の本文色#E2E8F0 or #F1F5F9非常に暗い背景に純白を使うとハレーションが起きます。見出しには白を使用できます。(APCA)
テキスト以外のコントラスト最低3:1アイコン、境界線、フォームコントロールと隣接する色との比率です。(WCAG 2.2 SC 1.4.11)
テキストのコントラスト最低4.5:1本文の場合です。大きなテキスト(24px以上、または太字18.66px以上)は3:1です。(WCAG AA)
モーション
プロパティデフォルト値根拠
最短時間100msこれより短いモーションは知覚できないため、代わりに瞬時に切り替えます
標準時間200–300msほとんどの UI トランジションに適しています
最長時間400ms複雑な演出に限ります。500msを超えないでください。
入場イージングcubic-bezier(0, 0, 0.2, 1)減速させます。表示される要素が落ち着きます
退場イージングcubic-bezier(0.4, 0, 1, 1)加速させます。退場する要素がすばやく消えます
標準イージングcubic-bezier(0.4, 0, 0.2, 1)画面内での位置変更に使用します
スペーシング
プロパティデフォルト値根拠
タッチターゲット(モバイル)44×44pxApple HIG のエンジニアリング目標
タッチターゲット(デスクトップの最小値)24×24pxWCAG 2.2 SC 2.5.8 の下限
ボタンの高さ(プライマリ)40–44pxクリックしやすいサイズです
ボタンの高さ(コンパクト)32px高密度 UI やセカンダリアクション向けです
角丸(カード)最大8px8pxを超えると、消費者向け・カジュアルな印象になります
角丸(ボタン)6px外側が8pxのカードに2pxのオフセットを加えた内側の角丸と合います
フォーカスリングのオフセット2pxリングの半径 = コンポーネントの半径 + 2px(WCAG 2.2 SC 2.4.13)
アイコン
プロパティデフォルト値根拠
最小サイズ16×16px16px未満では、密度1xでアイコンの明瞭さが失われます
線の太さ1.5px(標準)、2px(強調)テキストのウェイト階層に合わせます
視覚的な位置合わせ円形アイコンを1px下にずらします円形は四角形の境界に対して浮いて見えます
タッチターゲットのパディング透明なヒット領域を使い、44×44pxまで広げます見た目のアイコンは20pxでも、タップ領域は44pxにできます

よくある間違い

間違い修正方法
SKILL.md が未設定初回使用前に run the PencilPlaybook setup wizard を実行します
間違った解像度で作成する足場を作成するたびに snapshot_layout() を確認します
トークンではなく16進数の値をハードコードする毎回のセッションで、最初に set_variables を実行します
すべての画面を1つの巨大なフレームにまとめる画面ごとにフレームを分けます。配置には find_empty_space_on_canvas を使います
目視でトークンを置換するsearch_all_unique_properties + replace_all_matching_properties を使います
.pen ファイルの内容を記憶だけで説明するまず batch_get を実行します。ファイルの内容を決めつけないでください
足場作成後に snapshot_layout を省略する壊れた構造の上に作業を進める前に、寸法が0pxの箇所を検出できます
1回の batch_design 呼び出しで25件を超える操作を行う大規模な作成は複数回の呼び出しに分割します

エッジケース

Claude がトークンを無視する場合

デザイン上の判断が設定済みのトークンマップと一致しない場合(色が違う、任意のフォントサイズ、意図しない16進数の値など):

  1. 「その色はトークンマップにありません。セッション開始時に設定した変数の color-primary を使ってください。」 と明確に伝えます。
  2. get_variables() を実行し、トークンが実際に設定されていることを確認します。マップが空の場合は、set_variables が省略されています。セッション開始時の手順をもう一度実行します。
  3. search_all_unique_properties(parentIds=["root"], propertyNames=["bg","color"]) を実行して、紛れ込んだハードコード値を洗い出し、一括置換します。

Claude が値を作り続ける場合は、いったん止めて、プロンプト内で 「PencilPlaybook を使って、[指示]」 と述べながら SKILL.md を読み直し、スキルのコンテキストを再確認させます。


壊れた足場からの復旧

症状:snapshot_layout() に width: 0 または height: 0 のノードが表示されます。

原因:ほとんどの場合、次のいずれかです。

  • 明示的なサイズがなく、展開を促す子もないフレックスコンテナー
  • 明示的な幅のない親の中にある、width:"fill_container" の子
  • 絶対配置のノードにおける、競合している、または欠けている x/y 座標

修正手順:

1. snapshot_layout()                          — identify the 0px node
2. batch_get(nodeIds=["[broken-node-id]"])    — inspect its properties
3. U("[broken-node-id]", {width: N, height: N}) — add explicit dimensions
4. snapshot_layout()                          — confirm fixed before continuing

足場の破損がひどく、修正できない場合は、ルートフレーム(D("frame-id"))を削除し、get_editor_state() で状態がクリーンであることを確認してから、最初から足場を作り直します。


複数キャンバスのプロジェクト

同じセッションで複数の .pen ファイルを扱う場合:

  • トークンはファイル間で保持されません。 open_document を呼び出すたびに、新たに set_variables を実行する必要があります。トークンマップを SKILL.md に保存し、毎回貼り付けてください。
  • 編集前に、すべてのファイルで Canvas Archaeology を実行します。 ファイルの構造を記憶で決めつけず、必ず最初に batch_get(patterns=["*"]) を実行します。
  • 作業は1ファイルずつ行います。 2つのファイルを開いたまま、batch_design の呼び出しを交互に行わないでください。ファイルAの作業を終えてから、ファイルBを開きます。
  • ファイル間の一貫性を保ちます。 コンポーネントが複数のファイルに登場する場合は、ノード名を同一にします。名前が一致しないと、トークンの伝播や監査スクリプトの信頼性が損なわれます。

コメント