linear-design について
linear-designは、UIの構築とレビュー向けのデザイン仕様です。抑制された配色、キーボード操作、情報密度、操作状態を扱い、監査結果の分類形式も定めています。
主な機能
- 01派生色とサーフェス階層
- 02モーションとレイアウトのパターン
- 03キーボード優先の操作
- 04段階的な情報開示
- 05コンポーネントと状態の指針
- 06分類別の監査出力
活用シーン
- 01ツール型アプリのUI構築
- 02配色と間隔の統一
- 03キーボード操作と状態の確認
- 04設計上の問題を分類して整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ blink-new/ claude --skill linear-designインストール後、Claude Code で/linear-designを入力して読み込まれたか確認します。
詳細
Linear-Quality デザインシステム
Linear、Vercel、Resendのようなこだわりを持ってUIを構築します。優れたUIとは、何かを加えることではなく、抑制することです。 最高のディテールは目に見えず、見てわかるのではなく、感じられるものです。
カラーシステム
ハードコードされた値のパレットではなく、派生カラーシステムを設計します。
- 基盤となる変数を3つ定義します:ベースカラー、アクセントカラー、コントラストレベル。
- これらを不透明度の操作に使い、すべてのサーフェス、テキスト、アイコン、ボーダーを派生させます。
- 色相が同じ明度であれば、同じように明るく見えるよう、知覚的に均一な色空間(LCH/OKLCH)を使用します。
- 色相ではなく、不透明度とウェイトで階層を表現します。まずはモノクロームを基本にします。
- 色は意味を表す場合にのみ使用します:エラー(赤)、成功(緑)、アクティブ/選択状態、ブランドアクセント。
- 装飾目的の色は使いません。慣習的に色付きのアイコンを使わず、
muted-foregroundにします。 - ブランドカラーがUIの枠組みに漏れ出すのを抑えます。枠組みはニュートラルで、時代に左右されない印象にします。
- 16進数をハードコードしません。CSS変数/デザイントークンのみを使用します。
サーフェスとエレベーション
濃いシャドウではなく、背景をわずかに変化させてサーフェスを重ねます。
- 明確なエレベーション階層を定義します:
background→card/raised→popover→dialog/modal。 - 各レベルの違いは、異なる色ではなく、(ベースカラーへの不透明度の適用による)わずかな色調の変化にします。
- ダークモード:シャドウは控えめなボーダーやグローにします。
shadow-mdをborder border-border/50に置き換えます。 - ボーダー:不透明度を低くした半透明のもの(
border-border/40)を使い、不透明な単色の線は使いません。 - 背景ぼかし:オーバーレイ、ポップオーバー、コマンドパレットなどのフローティング要素に
backdrop-blur-smを適用します。 - コントラスト変数でハイコントラストモードに対応し、アクセシビリティをシステムに組み込みます。
- 全体に
-webkit-font-smoothing: antialiasedを適用します。
モーションとアニメーション
高級感のあるUIがそう感じられる理由の約30%はモーションです。最低限、transition-colors duration-150を使用します。
- マイクロトランジション:色/不透明度の変化には
duration-150 ease-outを使用します。 - レイアウトのトランジション:パネル、ドロワー、サイドバーには
duration-200 ease-in-outを使用します。 - 表示アニメーション:モーダル/ダイアログには、わずかにオーバーシュートしてから落ち着く、スプリングベースのイージングを使用します。
Framer Motion:
type: "spring", stiffness: 400, damping: 30。CSS:cubic-bezier(0.34, 1.56, 0.64, 1)。 - リストのスタガー:リストに追加される項目は、項目ごとに30~50msずらしてアニメーション表示します。
- スケルトンのシマー:静的なグレーのボックスではなく、コンテンツの形状に合わせたアニメーション付きのグラデーションを走らせます。
- トースト:一貫した位置(右下)からスライドインし、閉じるときにスライドアウトします。
- 数値のアニメーション:カウンターは値の間をアニメーションし、瞬時に切り替わらないようにします。
- 終了アニメーション:消える要素は突然消さず、(不透明度の変化とわずかな移動で)アニメーションしながら退出させます。
- 人為的な遅延は加えません。モーションは遅くならず、即時でありながら滑らかに感じられるようにします。
レイアウトアーキテクチャ
アプリをウェブサイトではなく、ツールのように感じさせる構造パターンです。
- 3カラムレイアウト:折りたたみ可能なサイドバー(240~280px)+メインコンテンツ+任意の詳細パネル。
- サイズ変更可能なパネル:カラム間にドラッグハンドルを配置します。ホバー時にハンドルを表示し、幅の設定を保存します。
- スティッキーヘッダー:スクロールに合わせて縮小または変形させます。ヘッダーと本文でコンテンツを重複させません。
- シート/ドロワーとモーダルの使い分け:コンテキストに応じた詳細(現在の操作フローを維持)にはシートを、集中して行うタスク(現在の操作フローをブロック)にはモーダルを使います。 シートは右からスライドインし、モーダルは背景を伴って中央に表示します。
- コマンドパレット:レイアウトの上に浮かぶ
Cmd+Kオーバーレイを使用します。あいまい検索、カテゴリ別の結果、最近使った項目、キーボード操作に対応します。これはパワーユーザーにとって主要なナビゲーションです。 - 分割ビュー:比較や、リストと詳細の並列表示には、コンテンツを左右に並べます。
キーボードファースト設計
Linear 品質のアプリは、マウスよりキーボードを使うほうが高速です。
- コマンドパレット(
Cmd+K):コマンドの検索、移動、アクションの実行に使います。必須です。 - 単一キーのショートカット:作成は
C、ステータスはSなど。ツールチップやコンテキストメニューに表示します。 - リストのナビゲーション:
j/kまたは矢印キーで項目間を移動し、Enterで開きます。 - 複数選択:
Shift+Clickで範囲選択、Cmd+Clickで個別に選択を切り替えます。 - フォーカス管理:ダイアログを閉じた後は、フォーカスを起動元に戻します。作成後は、新しい項目にフォーカスします。
- UI 内のショートカット:ツールチップ、コンテキストメニュー、コマンドパレットの検索結果にキーボードショートカットのヒントを表示します。これにより、ユーザーは自然にショートカットを覚えられます。
- Escape で閉じる:すべてのオーバーレイ、モーダル、ポップオーバー、コマンドパレットは
Escapeで閉じます。
プログレッシブディスクロージャー
通常時は最小限の表示にし、操作に応じて詳細を表示します。
- 行のアクション:編集、削除、オプションメニューは、行の
:hover時のみ表示します。 - メタデータ:タイムスタンプや補助的なバッジなど、通常時に不要な情報はホバー時に表示します。
- ツールバー:一括操作バーは常時表示せず、選択時に表示します。
- コンテキストメニュー:右クリックで、すべてのアクションを表示します。メニュー項目にはキーボードショートカットを含めます。
- サブメニューのセーフエリア:カーソルとサブメニューの間に三角形のヒットエリアを設け、マウスを斜めに動かしてもメニューが閉じないようにします(Linear のパターンです。約 40 行のコードで実現でき、ユーザーには見えませんが、滑らかな操作感として伝わります)。
- 主要なコンテンツやアクションでないものは、通常時に表示しないでください。
情報密度
高密度でありながら、すっきりとした表示にします。UI の枠組みは控えめに、コンテンツは高密度にします。
- リストやテーブルの行間を詰める(Tailwind のデフォルトの 1.5 ではなく、1.25~1.4)。
- コンパクトなインラインメタデータ:ステータスドット、アバター、優先度アイコン、ラベルをすべて 1 行にまとめます。
- 表形式の数字:すべての数値列に
font-variant-numeric: tabular-numsを指定し、桁を揃えます。 - 等幅フォント:ID、ブランチ名、コード、技術的な文字列には
font-mono text-xsを使用します。 - 数値列は右揃えにします。
- 密度のトレードオフ:コンテンツに余裕を持たせるため、UI の枠組みの余白(サイドバーのパディング、ヘッダーの高さ)を減らします。コンテンツ領域は高密度にできますが、ナビゲーションの枠組みには余裕を持たせます。
ボタンとアクション
- ページ、モーダル、カードごとに、
variant="default"(プライマリ)ボタンは最大 1 つにします。 - その他のアクションには、セカンダリ、アウトライン、ゴーストのいずれかを使い、視覚的な強さに応じて選びます。
- 破壊的なアクションには
variant="destructive"を使い、実行前に確認ダイアログを表示します。 - コンテキストごとにボタンの高さを統一します。同じビュー内で異なるサイズを混在させないでください。
- クリック可能な要素にはすべて、カーソル
pointerを設定します。
インタラクションとマイクロインタラクション
- クリック可能な要素にはすべて、明確な
hover:状態(色や不透明度)とactive:状態(押下中)を設定します。 - 視覚的なホバー反応のない
<div onClick>は使いません。 - フォーカス可能な要素には
focus-visible:ring-2 ring-ringを設定します。 - ドラッグハンドル:通常時は非表示にし、ホバー時に表示します。
- クリップボードへのコピー:「コピーしました!」という短いフィードバックを表示します(ツールチップまたはインラインテキストの切り替えで、1.5s)。
- 楽観的な更新:アクションと同時に UI を変更し、サーバー側の更新は非同期で反映させます。
- スマートなメニュー配置:メニューは画面内に収め、端に近い場合は表示方向を反転します。
- 入力のデバウンス:検索やフィルターの入力には 200~300ms のデバウンスを設定し、控えめな読み込みインジケーターを表示します。
タイポグラフィ
- 各ビューには、際立つ見出しを 1 つ、視線を集める要素を 1 つだけ設けます。視覚的な強さを競わせないでください。
- UI の枠組みを控えめにし、コンテンツを前面に出します。落ち着いた枠組みに対してテキストに高いコントラストを付けます。
- デザインシステムのトークンのみを使います。任意のフォントサイズやウェイトは使いません。
- 見出しにはディスプレイフォントを使用します(例:Inter Display、Geist)。本文にはレギュラーウェイトを使います。
- 文字間隔:大きな見出しではやや詰め(
tracking-tight)、本文ではデフォルトにします。
省略表示
- 1 行の場合:
truncateを指定し、親の flex 要素と span にmin-w-0を設定します。 - 複数行の場合:上限を意識して
line-clamp-{n}を設定します。 - テキストがはみ出さないようにします。すべての文字列に上限を設けます。
break-allは使いません。
状態
- 読み込み中:実際のレイアウト形状に合わせた
<Skeleton>とシマーアニメーションを使用します。コンテンツ内にスピナーは使用しません。 - 空の状態:タイトル+1行の説明+単一のCTAを表示します。空白のままにはしません。
- エラー:人が理解しやすいメッセージと、次に行うことを表示します。
- 無効:
opacity-50 cursor-not-allowedを使用します。要素を削除してはいけません。
テーブルとデータ表示
- 行にカーソルを合わせたとき、行全体をハイライトします(背景色を控えめに変更)。
- 数値は右揃え、テキストは左揃えにします。
- 列を並べ替えられるようにし、控えめなインジケーター(シェブロンアイコン)を表示します。
- 横スクロールに対応し、はみ出した場合は最初の列を固定します。
- 行のアクションはカーソルを合わせたときに表示します(段階的な開示)。
- 行の背景色を交互に変えます(不透明度は非常に低くします。任意、
even:bg-muted/30)。
コンポーネント
- shadcn/uiのみを使用します。Dialog、Tooltip、Dropdown、Select、Tabs、Badge、Card、Skeletonを再実装してはいけません。
- Lucideアイコンのみを使用します。絵文字は禁止です。装飾的なAIアイコン(きらめき、杖、星)は使用しません。
- アイコンのみのボタンは、必ず短いラベルを付けた
<Tooltip>で囲みます。例外はありません。 - 密度に応じてアイコンサイズを統一します(高密度では16px、標準では18~20px)。恣意的に混在させないでください。
- 全体を通して境界線の角丸を統一し、システムの角丸から逸脱してはいけません。
間隔
- 4pxを基準スケールにします。任意の値は禁止です(
mt-[13px]は違反です)。 - 孤立した要素を作らないでください。すべてをレイアウトグリッドに配置します。
- 間隔だけで置き換えられる境界線や区切り線は削除します。
- 余白を十分に確保します。空白もデザインの一部です。
仕上げ
- UIコンポーネントに
console.logを残さないでください。 z-[9999]は使用せず、定義済みのz-indexスケールを使用します。!importantによる上書きは禁止です。- 色をハードコードせず、すべてCSS変数を使用します。
- すべてのオーバーレイを
Escapeキーで閉じられるようにします。 - 共有できるように、タブやセクションの切り替えに合わせてURLを更新します。
- レスポンシブ対応:モバイルではサイドバーをアイコンのみ、またはドロワーにします。パネルは縦に積み重ねます。
監査結果の形式
問題ごとに、次の内容を記載します。
- ファイルパス+行番号
- 問題点(1文)
- 修正内容
次の順にグループ分けします。色/サーフェス → 動き → レイアウト → キーボード → 段階的な開示 → 密度 → インタラクティブ性 → タイポグラフィ → 状態 → テーブル → 仕上げ
優先順位:操作の破損 > キーボードサポートの不足 > 状態の不足 > 動きの不足 > 視覚的一貫性の欠如 > 仕上げ
最後に、コードだけでは解決できず、人によるデザイン判断が引き続き必要な点を記載します。