Communitygithub.com

stevembarclay/pencilplaybook

PencilPlaybook は Pencil.dev + Claude Code 向けの UI スキル/テイストスキルです。実際の知覚心理学とシニアレベルのガードレールを Claude に与え、平均的な AI スロップを生成しないようにするデザインプレイブックです。

pencilplaybook とは?

PencilPlaybook は、Pencil.dev と Claude Code を組み合わせて使用するためのデザインスキル(テイストスキル)です。このスキルは、Claude がプロダクトデザインにおいて、単なる「平均的な AI スロップ」ではなく、知覚心理学とシニアレベルのガードレールに基づいた高品質な UI を生成できるように設計されています。主に Pencil.dev のエディタ上で動作し、ブランドトークンの注入やセッションの初期化、9 種類のスキャフォールド(アプリダッシュボード、リスト、詳細ビュー、マーケティングページ、モーダル、ウィザード、モバイル画面、フォーム、空状態)を提供します。各スキャフォールドは、setup.md を使用した初期設定が必要で、resolution やカラートークンを定義することで、一貫性のあるデザインアウトプットを実現します。また、スナップショットによるレイアウト検証や、レスポンシブデザインのためのマーケティングページの幅固定(1440px)とモバイル検証など、実践的なワークフローも含まれています。

対応✓Claude Code~Codex CLI~Cursor
npx skills add stevembarclay/pencilplaybook

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Pencil Pro

一次解決ルール

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

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

ユーザーが「PencilPlaybook で最初の画面を作成」と言った場合、またはデザインの開始を依頼した場合: → .claude/skills/pencilplaybook/onboarding.md を読み、そこに書かれている指示に正確に従ってください。

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

既存の .pen ファイル内の画面ルートが設定された解像度と一致しない場合は、編集前にそれを指摘してください。サイズが間違ったキャンバス上に、その逸脱を通知せずに構築しないでください。

一般的な例外 — マーケティングページ: アプリの解像度に関わらず 1440px でデザインしてください。マーケティングページは可変のブラウザ幅で表示されるため、1440px でデザインし、390px で確認してください。


セッション起動(すべての Pencil セッション)

1. get_editor_state()                           — アクティブなドキュメントと選択状態を確認
2. open_document("path/to/your-file.pen")       — 対象ファイルを開く
3. get_guidelines(topic="web-app")              — デザインガイドラインを読み込む
4. set_variables(<下記のトークンマップ>)         — ブランドトークンを注入
5. get_variables()                              — トークンが保存されたことを確認
6. snapshot_layout()                            — キャンバス寸法を確認

トークンマップ — 各セッションの開始時にこのオブジェクトを 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 にオーバーレイとして追加します — root には挿入しないでください。

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、ミュート)、1 つのプライマリ CTA。


コアワークフロー

ワークフロー 1: キャンバスアーキオロジー

使用時: 「このファイルの中身は?」

...

関連スキル