Ahmed UI Craft は何をしますか?
言語モデルはウェブの統計的平均へとドリフトします。Inter、紫色のグラデーション、3枚の同一の角丸カード、機能ごとの絵文字。その出力は一目でそれとわかり、ユーザーに「誰も決断しなかった」ことを伝えます。このスキルは、決断を強制し、トークンとして書き留め、何かを引き渡す前にチェックすることを求めます。
ワークフローは順番に従って実行してください。各ステップには、それをスキップすると凡庸なUIになるからこそ存在する理由があります。
ステップ0 - デザインする前にプロジェクトを読む
発明する前に、まず見てください。以下の順序で確認します。
- フレームワーク:
package.json(next, react, vue, svelte, astro)、またはプレーンな.html。 - スタイリング:
tailwind.config.*または@import "tailwindcss"/@theme(Tailwind v4)、*.module.css、styled-components、またはプレーンなCSS。 - 既存のトークン:
--color-、--space-、@theme、theme.extendをgrep。 - コンポーネントライブラリ:
components/ui/+components.json(shadcn/ui)、@mui/material、Radix、Headless UI、Vuetify。
理由: プロジェクトの既存のトークンやライブラリを無視した美しいコンポーネントは、改善ではなく退行です。プロジェクトにすでにデザインシステムがある場合は、その内部で作業します。トークンを拡張し、プリミティブを再スタイルします(shadcn/uiの場合は、globals.cssとコンポーネントファイルのCSS変数を編集し、ラップしないでください)。拡張するシステムがない場合にのみ、assets/tokens.cssを持ち込みます。
何も存在しない場合、デフォルトは次の通りです: セマンティックHTML + assets/tokens.cssからのCSSカスタムプロパティ、Tailwindが存在する場合はTailwindにマッピング。
ステップ1 - デザイン思考(コードの前に)
頭の中で、または返信の中で、4行の短い文章を書きます。
- 目的: この画面はどのような役割を果たすのか?(例:「チームリーダーにトライアルを開始するよう説得する」)
- オーディエンス: 誰が、どのデバイスで、どのような気分で見ているのか?(例:「運用エンジニア、デスクトップ、素早くスキャンしている」)
- トーン: 形容詞3つ。(例:「正確、落ち着いている、密度が高い」)
- 差別化要因: タブを閉じた後でも誰かが覚えているであろう、たった一つのこと。
差別化要因は具体的で目に見えるものでなければならず、「クリーンでモダン」ではありません。良い例:「価格は端から端まで続く巨大な凝縮された数字で設定されている」、「すべてのカードにはヘアラインルールと、スペックシートのようなモノのインデックス番号がある」、「ヒーローヘッドラインは、オフホワイトの紙テクスチャの上にセリフ斜体で設定されている」。
理由: 差別化要因を名付けることができなければ、出力は平均的なものになります。なぜなら、モデルを引き離す何もなければ、モデルは平均的なものを生成するからです。
ユーザーがブランド、スクリーンショット、または既存のサイトを提供した場合、トーンはそれらから導き出されます。確立されたブランドに新しい方向性を押し付けてはいけません。
ステップ2 - 1つの美的方向性にコミットする
1つの方向性を選び、それをタイプ、カラー、半径、シャドウ、モーション、画像、そしてコピーのリズムのすべてに適用します。方向性が混在すると、優柔不断に見えます。
| 方向性 | タイプ | カラー | 形状と奥行き | モーション |
|---|---|---|---|---|
| エディトリアル | セリフのディスプレイ、ヒューマニストのボディ | 紙のオフホワイト、インク、一つの強いアクセント | ヘアラインルール、ほぼゼロ半径、シャドウなし | スローフェード、スクロール時はなし |
| ブルータリスト | 太めのグロテスクまたはモノ、巨大サイズ | 生の黒/白 + 一つの派手な色 | 0半径、太い境界線、ハードオフセットシャドウ | 瞬間的、スナッピー |
| ソフト / オーガニック | ラウンドまたはソフトセリフディスプレイ | 暖かみのあるニュートラル、落ち着いたアーシーなアクセント | コンテナのみ大きめの半径、拡散シャドウ | 弾力性があり、優しい |
| インタストリアル / テクニカル | 凝縮またはグロテスク + モノ | ダークニュートラル、シグナルアクセント(アンバー、ライム、シアン) | 小さな半径、1px境界線、グリッドラインが見える | 高速、リニアに近い |
| ラグジュアリー | ハイコントラストセリフ、ワイドトラッキングキャップス | ほぼ黒、クリーム、メタリックまたは深いジュエルトーンのアクセント | 広々としたホワイトスペース、細い境界線 | スロー、ロングイーズ |
| プレイフル | ずんぐりしたディスプレイ、フレンドリーなサンセリフ | 意図的にぶつかる2つの彩度の高い色 | ステッカーシェイプ、オフセットシャドウ | 弾むオーバーシュート |
各行には、assets/directions/ に既成のプリセット(フォント、コントラストチェック済みのライト/ダークパレット、半径、シャドウ、モーション)と、references/directions.md にシグネチャームーブのリストがあります。tokens.css の後にプリセットをロードし、そのシグネチャームーブのうち少なくとも2つを使用し、色相をブランドに向けてシフトします。スイスミニマルが7番目のプリセットです。
選択のルール:
- 習慣ではなく、ステップ1から導き出します。SRE向けのダッシュボードは「ラグジュアリー」ではありません。
- 返信でその名前を書きます(「方向性: インタストリアル / テクニカル」)。これにより、ユーザーは早期に方向転換できます。
- ユーザーが退屈なもの(「シンプルでクリーン」)を要求した場合でも、選択します。「スイスミニマル」は方向性です(厳格なグリッド、一つのグロテスク、黒 + 一つの色、装飾はゼロ)。
ステップ3 - まずトークンを定義する
1つのコンポーネントも書く前に、以下のトークンを定義します: カラー、タイプ、スペーシング、半径、シャドウ、モーション、z-index。assets/tokens.css から始めます: 名前はそのままに、値を置き換えます。
開始値(Fraunces + Instrument Sans、ペーパーニュートラル、バーミリオンアクセント)はプレースホルダーであり、スタイルではありません。コンポーネントを書く前に、少なくともフォントペア(references/typography.md から、方向性に合わせて)、アクセント色相、およびニュートラルが着色される色相を変更します。理由: テストでは、変更されていない開始トークンにより、無関係な製品のログインフォームと価格ページが同一に見えました。これは新しいデフォルトであり、このスキルが修正しようとしている問題です。方向性が本当に赤オレンジのアクセントを持つ暖かいエディトリアルである場合にのみ、それらを維持します。
新しいアクセシブルなパレットへの最速の方法: 生成し、それをブロック2のカラートークンに貼り付けます。
node scripts/palette.mjs --hue 250 --accent 130 --dark-first # スレートニュートラル、ライムアクセント
--hue はニュートラルを着色します(ブランドの色相を使用)、--accent はアクセント色相です。すべてのテキスト/背景ペアは、出力前にライトとダークの両方でWCAG AAに合格するように解決されています。
ダークファーストの方向性(モニタリングダッシュボード、開発者ツール、ラグジュアリーナイトテーマ)の場合、:root { color-scheme: dark; } を設定して、ダークをデフォルトにし、ライトをオプトインにします。
理由: トークンにより方向性が強制可能になります。コンポーネントにハードコードされた #6366f1 や 13px は、孤立した決断であり、そのような決断が20個あるとUIはドリフトします。トークンがあれば、ダークモード、テーマ設定、および後での再スタイルは1ファイルの変更で済みます。
ルール:
- 2つのレイヤー: 生のパレット(
--ink-900、--clay-500)とセマンティックトークン(--color-text、--color-accent、--color-surface)。コンポーネントはセマンティックトークンのみを使用します。 - コンポーネント内にマジックナンバーはありません。すべての色、サイズ、ギャップ、半径、シャドウ、期間、z-indexはトークンから取得されます。例外:
0、1pxヘアライン、100%、1fr。 - ダークモード: すべてのセマンティックカラーは
light-dark(LIGHT, DARK)であり、両方のテーマが1つの宣言に存在し、コンポーネントは決して変更されません。references/color-and-theming.mdを参照してください。
Tailwind: トークンをテーマにします。これにより、bg-surface、text-text-muted、font-display、rounded-md が存在し、bg-indigo-500 は存在しなくなります。
- v4:
assets/tokens.cssの2番目のブロックは、すでにTailwindの名前空間(--color-*、--font-*、--text-*、--radius-*、--shadow-*、--ease-*)を使用しています。そのブロックの:rootを@themeに変更し、最初の行として--color-*: initial;を追加してデフォルトのパレットを削除します。ブロック3(color-scheme)はプレーンなCSSとして保持します。ユーティリティは、テーマごとにlight-dark()を解決します。これはvar(--color-*)を参照するためです。@theme inline { --color-x: var(--color-x) }と書かないでください。自身の名前を参照する変数は循環参照であり、何も解決しません。 - v3:
tailwind.configで、theme.colors(extendではない)を{ surface: "var(--color-surface)", ... }に設定し、fontFamily、borderRadius、boxShadowも同じように拡張します。
ステップ4 - モバイルファーストですべての状態を含めて構築する
360pxビューポート用のベーススタイルを作成し、その後 min-width メディアクエリまたはコンテナクエリを追加します。理由: スペースを追加するのは簡単ですが、取り除くのは難しく、ほとんどのレイアウトバグ(水平スクロール、つぶれたテーブル)は小さな幅でのみ発生します。
すべてのインタラクティブ要素は、そのすべての状態とともに提供されます。状態の欠落は、UIが未完成に感じられる最も一般的な理由です。
| 状態 | 表示するもの |
|---|---|
| default | 静止時のデザイン |
| hover | 微妙な変化(色またはシャドウ)、@media (hover: hover) 内のみ |
| focus-visible | 明確に見えるリング、決して削除しない |
| active | 押下時のフィードバック(暗くする、または translateY(1px)) |
| disabled | 低コントラスト + cursor: not-allowed、そして実際の disabled 属性 |
| loading | スピナーまたはスケルトン、aria-busy="true"、幅が変わらない |
| error | フィールドの近くにメッセージテキスト、赤い境界線だけではない |
| empty | 実際のメッセージと次のアクション、空白のボックスは決して使わない |
まずセマンティックHTMLを使用します: アクションには <button>、ナビゲーションには <a href>、すべての入力には <label for>、モーダルには <dialog>、表形式データには <table>、ランドマーク(<header> <nav> <main> <footer>)。ネイティブなHTMLに相当するものがない場合にのみARIAを追加します。理由: ネイティブ要素はキーボード操作とスクリーンリーダーのセマンティクスを無料で提供します。ARIAは、後で実装する必要がある約束です。
実際のコピーを書きましょう。プレースホルダーテキスト(「Lorem ipsum」、「Feature 1」、「John Doe」)はレイアウトの問題を隠し、結果をテンプレートのように見せます。ステップ1の目的に合った、具体的で妥当なコンテンツを使用します。
ステップ5 - 納品前に監査する
scripts/audit.md を実行します: bash scripts/audit.sh <changed files>(パターンチェックとトークンコントラスト)、その後、Playwrightが利用可能であるかユーザーがインストールに同意した場合、node scripts/browser-check.mjs <page> を実行し、保存されたスクリーンショットを確認します。失敗したものを修正します。コメントに書かれた比率は主張であり、測定値ではありません。計算します。既知の失敗がある状態で作業を完了として報告しないでください。修正できないものがある場合(例えば、コントラストに失敗するブランドカラー)、その旨を明示的に述べてください。
マルチエージェントモード(サブエージェントツールが利用可能な場合)
メインのエージェントは常にステップ0〜4を自身で実行します。思考と構築には同じコンテキストが必要であり、それらを分割するとステップ0で見つけたものが失われます。以下の2つのポイントでのみサブエージェントを使用します。
-
方向性の提案(ステップ2、未確定のブリーフの場合のみ)。ブランド、スクリーンショット、または既存のデザインシステムがない場合は、2〜3のサブエージェントを並行して起動します。それぞれにステップ1のラインを与え、それぞれにテーブルから異なる方向性を割り当てます。各エージェントに、最初に
references/directions.mdとreferences/typography.mdの自分のセクションを読むように指示し、他のエージェントの方向性を伝えてそれらを避けるように指示します。各エージェントは以下だけを返します: 方向性、フォントペア、アクセント+ニュートラル色相、差別化要因、2つのシグネチャームーブ。他のエージェントのフォントペア、アクセント色相、または差別化要因を再利用する提案、またはtokens.cssの開始値を保持する提案は却下します。一つを選択するか(またはユーザーにオプションを表示し)、その後単独で続行します。 理由: 1つのエージェントは平均に収束します。強制的に異なる開始点を与えることでそれを回避します。ブランドがすでに方向性を設定している場合は、これをスキップします。 -
独立したレビュー(ステップ5、新しいページや画面の場合常に)。自身の監査が合格した後、コードを書いていない新しいサブエージェントを1つ起動します。変更されたファイル、ステップ1のライン、選択された方向性を与え、以下を行うように依頼します:
references/anti-patterns.mdを読み、scripts/audit.shを実行し、UIが凡庸に見える箇所、状態が欠落している箇所、または方向性を破っている箇所をすべてリストアップします。各発見を blocker / major / minor にランク付けし、編集は行いません。すべての blocker と major を修正し、scripts/audit.shを再実行し、未修正の minor を返信にリストします。レビューパスは1回、ループなし。 理由: ビルダーは、画面上にあるものではなく、自分が作ろうとしたものによって結果を判断します。
サブエージェントツールがない場合: 両方のパスを自分で、順番に実行します。レビューの際には、ファイルを他の誰かが書いたかのように読み直します。
品質ルール(とその理由)
タイポグラフィ
- ディスプレイテキストにInter、Roboto、Arial、Helvetica、またはsystem-uiをデフォルトにしないでください。また、新しいAIのデフォルトであるPoppins、Montserrat、Space Grotesk、DM Sansも避けてください。 理由: これらはすべての生成されたページが使用するフォントであり、「生成された」という印象を与えます。
- 構造的にコントラストのあるディスプレイフェースとボディフェースをペアにします(セリフ + サンセリフ、凝縮 + ワイド、グロテスク + モノ)。最大2ファミリー、オプションでモノを追加できます。
- 流体サイズ(
clamp())を持つモジュラースケールを使用し、最大の見出しをボディテキストよりも劇的に大きくします。控えめな階層(16pxに対して32px)は未完成に見えます。 - ボディテキスト: 最低16px、行間1.5〜1.7、1行あたり60〜75文字。密度の高いダッシュボードでは、メタデータやテーブルセルに12〜14pxを使用してもかまいませんが、段落や入力には決して使用しないでください。
カラー
- 1つの支配的な色がブランドを表現し、1つのシャープなアクセントが主要なアクションとキーデータのために予約されます。ニュートラルがほとんどの作業を行います。おおよそ60/30/10。 理由: 均等に分布した5色のパレットには焦点がなく、何も重要に見えません。
- 純粋なグレーを使用する代わりに、ニュートラルをブランドの色相に着色します。
- ブランドが本当にパープルでない限り、パープルからブルー、またはパープルオンホワイトのグラデーションは使用しないでください。
- テキストのコントラストは少なくとも4.5:1(24px+または18.66px+の太字テキスト、およびUIコンポーネントの境界とフォーカスリングの場合は3:1)。
レイアウトと形状
- 同じ3つまたは4つのカードグリッドを避けてください。サイズと強調を変えます: 2列にまたがる1つのフィーチャーアイテム、大きなビジュアルの横のリスト、非対称の分割。
- 半径は方向性に従い、レベルごとに一貫性を持たせます。すべてに
rounded-2xlを設定しないでください。小さなコントロールは小さな半径、またはなし。 - 320pxで水平スクロールしないようにします。flex/gridの子には
min-width: 0、長い文字列にはoverflow-wrap: anywhere、幅の広いテーブルにはスクロールコンテナを使用します。 - タッチターゲットは少なくとも44x44px(パディングも含む)。
アイコンと画像
- アイコンとして絵文字を使用しないでください。1つのアイコンセット(Lucide、Phosphor、Heroicons、Tabler)を1つのストローク幅で使用するか、インラインSVGを使用します。理由: 絵文字はOSごとにレンダリングが異なり、トークンで色付けできず、スクリーンリーダーによってアナウンスされます(「ロケット」)。
- 装飾的なアイコンには
aria-hidden="true"を設定します。アイコンのみのボタンにはaria-labelを設定します。
モーション
transformとopacity(さらに控えめにfilter)のみをアニメーション化します。理由: 他のプロパティはフレームごとにレイアウトまたはペイントをトリガーし、ローエンドの電話でカクつきます。- トークンからの持続時間: UIフィードバックは120〜200ms、要素の出現は250〜400ms。
prefers-reduced-motionを尊重します: 動きを削除し、フェードは短くするか即座にします。
アクセシビリティ
[翻訳中、省略]