Web UI Codegen — プレミアムUIコードジェネレーター
DribbbleやBehanceのトップ作品のように見えるUIコードを生成します。一般的なAI出力ではありません。目標は、トップスタジオのシニアプロダクトデザイナーの仕事と見分けがつかないコードを生成することです。
このスキルが解決する中核的な問題
AIが生成するUIは、通常「技術的には正しいが、魂がこもっていない」という状態になります。
- 平坦で生命感のないレイアウト
- リズムや余白のない機械的なグリッド
- 雰囲気を創り出さない凡庸な色使い
- 奥行き、光、立体感の欠如
- 注意を引かず、ただ「そこにあるだけ」のテキスト
このスキルは出力をデザイングレードの視覚体験に変えます。
使用時
このスキルは以下の場合に必ず呼び出される必要があります。
- 任意のWebページ、アプリ、またはランディングページを構築する場合
- 洗練されたUIコンポーネントを作成する場合
- ユーザーが美しくモダンなデザイン出力を期待している場合
- 視覚的な品質が期待されるHTML/CSS/JS、React、またはVueのタスク
デザインシステム
1. 背景:拡散グラデーションの雰囲気
決してフラットな単色を使用しないでください。背景は雰囲気と感情を創り出さなければなりません。
テクニック:レイヤード拡散グラデーション
/* 背景レイヤー1: ベースグラデーション */
body {
background: #0a0a0f;
background-image:
radial-gradient(ellipse 80% 50% at 50% -20%, rgba(120, 119, 198, 0.15) 0%, transparent 60%),
radial-gradient(ellipse 60% 40% at 80% 50%, rgba(255, 107, 107, 0.08) 0%, transparent 50%),
radial-gradient(ellipse 50% 50% at 20% 80%, rgba(78, 205, 196, 0.06) 0%, transparent 50%);
}
/* ライトテーマバージョン: */
body.light {
background: #f8f6f4;
background-image:
radial-gradient(ellipse 80% 60% at 50% 0%, rgba(167, 139, 250, 0.12) 0%, transparent 50%),
radial-gradient(ellipse 60% 40% at 90% 60%, rgba(251, 191, 146, 0.1) 0%, transparent 40%),
radial-gradient(ellipse 50% 50% at 10% 90%, rgba(147, 197, 253, 0.08) 0%, transparent 40%);
}
ルール:
- 異なる位置と色で2〜4つの
radial-gradientレイヤーを使用する - 不透明度は低く保つ(ダークで0.06〜0.15、ライトで0.08〜0.15)
- 色は補色または類似色にする。ランダムにしてはならない。
- グラデーションは中央ではなく端や中心からずらして配置し、自然な印象にする
circleではなくellipseシェイプを使用する。より有機的。
背景のカラームードパレット:
- Calm/Tech: パープルブルー + ティール (rgba(120,119,198) + rgba(78,205,196))
- Warm/Creative: オレンジピンク + ゴールド (rgba(255,107,107) + rgba(255,193,68))
- Fresh/Nature: グリーン + ブルー (rgba(52,211,153) + rgba(96,165,250))
- Premium/Luxury: ディープパープル + ローズ (rgba(139,92,246) + rgba(244,114,182))
- Neutral/Corporate: スレートブルー + シルバー (rgba(100,116,139) + rgba(148,163,184))
2. タイポグラフィ:映画的な階層構造
アマチュアUIとプロフェッショナルUIの最も大きな違い:極端なタイポグラフィのコントラスト。
/* ヒーロー見出し — 画面を支配する */
.hero-title {
font-size: clamp(2.5rem, 6vw, 4.5rem);
font-weight: 700;
line-height: 1.05;
letter-spacing: -0.03em;
color: var(--text-primary);
}
/* セクション見出し — コンテンツを固定する */
.section-title {
font-size: clamp(1.75rem, 3vw, 2.5rem);
font-weight: 600;
line-height: 1.15;
letter-spacing: -0.02em;
}
/* 小見出し / カードタイトル */
.card-title {
font-size: 1.1rem;
font-weight: 600;
line-height: 1.3;
letter-spacing: -0.01em;
}
/* 本文 — あえて軽く */
.body-text {
font-size: 1rem;
font-weight: 400;
line-height: 1.6;
color: var(--text-secondary);
max-width: 540px; /* リーディングメジャー */
}
/* 小さなラベル / タグ */
.label {
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 0.05em;
text-transform: uppercase;
color: var(--text-muted);
}
ルール:
- タイトルと本文のサイズ比:最低3:1(例:48pxタイトル / 16px本文)
- ヒーローテキスト:流動的なスケーリングのために常に
clamp()を使用する - 文字間隔:見出しはネガティブ(-0.02〜-0.04em)、ラベルはポジティブ(+0.03〜+0.06em)
- 行の高さ:見出しは1.0〜1.1、本文は1.5〜1.6
- 1画面で使用するフォントサイズは最大2〜3種類にする
- ウェイトのコントラスト:見出しは700、本文は400。すべてに500を使用しないこと。
3. レイアウト:余白とベントー
余白のルール:画面の60%は空きスペースにします。コンテンツは貴重です。空気で囲みましょう。
スペーシングスケール:
:root {
--space-xs: 4px;
--space-sm: 8px;
--space-md: 16px;
--space-lg: 24px;
--space-xl: 40px;
--space-2xl: 64px;
--space-3xl: 96px;
--space-4xl: 128px;
--space-section: clamp(80px, 12vw, 160px);
}
ベントーグリッド(機能セクション、ダッシュボード向け):
.bento-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(200px, auto);
gap: 16px;
}
/* フィーチャーカードは2列にまたがる */
.bento-item-wide { grid-column: span 2; }
/* ヒーローカードは2列+2行にまたがる */
.bento-item-hero { grid-column: span 2; grid-row: span 2; }
/* 縦長カード */
.bento-item-tall { grid-row: span 2; }
ルール:
- セクションの垂直パディング:80〜160px(
--space-sectionを使用) - コンテンツの最大幅:1120px(1200pxではない。少し狭い方がよりデザインされた印象になる)
- ページのサイドパディング:デスクトップは48〜80px、モバイルは20〜24px
- カードのパディング:32〜48px(ゆったりしていて、窮屈ではない)
- 見出しと本文の間:16〜24px
- カードのセクション間のギャップ:16〜20px
- ヒーローセクション:コンテンツは垂直方向の中央揃え、最小80vhの高さ
- 幅全体を埋めることは絶対にしない。十分な余白を残すこと。
4. カードとサーフェス:魂のあるグラス
/* === ダークテーマグラスカード === */
.card {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(24px) saturate(130%);
-webkit-backdrop-filter: blur(24px) saturate(130%);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: 24px;
padding: 32px;
position: relative;
overflow: hidden;
transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
/* 上端の光の反射 */
.card::before {
content: '';
position: absolute;
top: 0; left: 10%; right: 10%;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1) 50%, transparent);
}
/* ホバー:浮上 + 発光 */
.card:hover {
transform: translateY(-4px);
border-color: rgba(255, 255, 255, 0.12);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
}
/* === ライトテーマグラスカード === */
.card-light {
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(20px) saturate(150%);
border: 1px solid rgba(255, 255, 255, 0.7);
border-radius: 24px;
padding: 32px;
box-shadow:
0 4px 24px rgba(0, 0, 0, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.card-light:hover {
transform: translateY(-4px);
box-shadow:
0 12px 40px rgba(0, 0, 0, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
ルール:
- カードのボーダー半径:20〜32px(大きめに。これがモダンな外観)
- ボーダー:常にrgbaを使用し、不透明度は0.06〜0.1以下。単色は使用しない。
- 常に上端ハイライト(
::beforelinear-gradientトリック)を追加する - ホバーには
translateY(浮上)と強化されたシャドウを必ず含める - ライトカードは内部発光のために
insetシャドウを使用する - カードのパディング:最低32px、それ以下にしない
5. ボタン:ピル型 + 感情
/* プライマリーCTA — 存在感のあるピル型 */
.btn-primary {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 14px 32px;
font-size: 0.9rem;
font-weight: 500;
color: #fff;
background: var(--accent);
border: none;
border-radius: 50px;
cursor: pointer;
transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
box-shadow: 0 4px 16px rgba(var(--accent-rgb), 0.3);
}
.btn-primary:hover {
transform: translateY(-2px) scale(1.03);
box-shadow: 0 8px 24px rgba(var(--accent-rgb), 0.4);
}
.btn-primary:active {
transform: scale(0.97);
transition-duration: 0.1s;
}
/* ゴースト / セカンダリ — 繊細なアウトラインピル */
.btn-ghost {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 14px 32px;
font-size: 0.9rem;
font-weight: 500;
color: var(--text-primary);
background: transparent;
border: 1px solid rgba(var(--text-rgb), 0.15);
border-radius: 50px;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-ghost:hover {
background: rgba(var(--text-rgb), 0.05);
border-color: rgba(var(--text-rgb), 0.3);
}
ルール:
- すべてのボタンは
border-radius: 50px(ピル型)を使用する - プライマリーボタン:ソリッドフィル + 一致するカラーのシャドウグロー
- セカンダリーボタン:透明/ゴースト + 細いボーダー
- パディング:垂直14〜16px、水平28〜36px(ゆったりと)
- ホバー:常にtranslateY + scaleブースト + グロー増加
- アクティブ:scale(0.97)、高速トランジション(100ms)
- 角ばった、またはわずかに丸いボタンは絶対に使用しない。常に完全なピル型。
6. アイコン:SVGのみ — 絵文字は絶対に使用しない
絶対ルール:UIアイコンとして絵文字(🎬🎮💼🎵)を絶対に使用しないこと。これはAIが生成したアマチュアコードの最大の兆候です。
オプションA: CDN経由のLucideアイコン(推奨)
Lucideは最もモダンで軽量、オープンソースのアイコンライブラリ(1000+アイコン)です。
<!-- <head>に追加 -->
<script src="https://unpkg.com/lucide@latest"></script>
<!-- data-lucide属性でHTML内で使用 -->
<i data-lucide="music" class="icon"></i>
<i data-lucide="play" class="icon"></i>
<i data-lucide="search" class="icon"></i>
<i data-lucide="heart" class="icon"></i>
<!-- bodyの最後で初期化 -->
<script>lucide.createIcons();</script>
/* CSSでアイコンのスタイルを設定 */
.icon {
width: 20px;
height: 20px;
stroke: currentColor;
stroke-width: 1.75;
}
よく使われるアイコン名: home, search, settings, user, heart, play, pause, skip-forward, skip-back, volume-2, music, headphones, mic, star, bookmark, share-2, download, arrow-left, arrow-right, chevron-down, plus, x, check, bell, mail, calendar, clock, globe, camera, image, film, book-open, briefcase, code, terminal, zap, trending-up, bar-chart-2, pie-chart, layers, grid, list, filter, edit-3, trash-2, eye, eye-off, lock, unlock, sun, moon, menu, more-horizontal, more-vertical, external-link, link, send, message-circle, phone, map-pin
オプションB: インラインSVG(CDNが利用できない場合)
最小限のSVGパスを直接記述します。アイコンはシンプルに保つ(単一パス、24x24 viewBox):
<!-- 再生アイコン -->
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
<polygon points="5 3 19 12 5 21 5 3"/>
</svg>
<!-- 検索アイコン -->
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
</svg>
<!-- ホームアイコン -->
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>
</svg>
アイコンのスタイリングルール:
- サイズ:標準は18〜24px、コンパクトは16px、フィーチャーアイコンは28〜32px
- ストローク幅:1.5〜2(細いほど洗練される)
- 色:アイコンがテキストの色を継承するように
currentColorを使用する - アイコンコンテナ:丸みを帯びたdivと繊細な背景で包み、強調する
/* アイコンコンテナ — アイコンに「居場所」を与える */
.icon-box {
width: 40px;
height: 40px;
border-radius: 12px;
background: rgba(var(--accent-rgb), 0.1);
display: flex;
align-items: center;
justify-content: center;
color: var(--accent);
}
7. カラートークン
:root {
/* ダークテーマ(デフォルト) */
--bg: #0a0a0f;
--text-primary: #f0f0f3;
--text-secondary: #8b8b99;
--text-muted: #4a4a58;
--accent: #6366f1; /* インディゴ — プロジェクトごとに変更 */
--accent-rgb: 99, 102, 241;
--accent-glow: rgba(99, 102, 241, 0.3);
--surface: rgba(255, 255, 255, 0.03);
--surface-border: rgba(255, 255, 255, 0.06);
--text-rgb: 240, 240, 243;
}
/* ライトテーマ */
:root.light {
--bg: #f8f6f4;
--text-primary: #1a1a2e;
--text-secondary: #6b6b80;
--text-muted: #a0a0b0;
--accent: #6366f1;
--accent-rgb: 99, 102, 241;
--surface: rgba(255, 255, 255, 0.6);
--surface-border: rgba(255, 255, 255, 0.7);
--text-rgb: 26, 26, 46;
}
アクセントカラーオプション(プロジェクトごとに1つ選択):
- インディゴ:
#6366f1— テック、AI、SaaS - ブルー:
#3b82f6— 信頼、コーポレート、ファイナンス - バイオレット:
#8b5cf6— クリエイティブ、プレミアム - ローズ:
#f43f5e— 大胆、エネルギー、ソーシャル - アンバー:
#f59e0b— ウォーム、クリプト、フィンテック - エメラルド:
#10b981— ヘルス、ネイチャー、グロース - シアン:
#06b6d4— フレッシュ、モダン、トラベル
8. マイクロインタラクションとモーション
/* トランジションプリセット */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
/* カードホバー — 浮上 */
.card { transition: all 0.4s var(--ease-out-expo); }
.card:hover { transform: translateY(-4px); }
/* ボタンホバー — バウンススケール */
.btn { transition: all 0.25s var(--ease-bounce); }
.btn:hover { transform: translateY(-2px) scale(1.03); }
/* 繊細なエントランスアニメーション */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-in {
animation: fadeUp 0.6s var(--ease-out-expo) forwards;
}
ルール:
- カード:0.4s ease-out-expo、ホバー時に translateY(-4px)
- ボタン:0.25s バウンス、translateY(-2px) + scale(1.03)
- 入力欄:0.2s スムーズ、ボーダーカラーの変更 + 繊細なグロー
transition: all 0.3s easeは絶対に使用しない。これはAIの兆候です。- アクティブ/押下時:scale(0.97)、持続時間0.1s
- ページロード時:fadeUpアニメーションをずらして再生(要素ごとに0.1s遅延)
9. 視覚的な奥行き要素
「デザインされた」感覚を生み出すためにこれらを追加します。
/* フローティンググラデーションオーブ(装飾用) */
.orb {
position: absolute;
width: 400px;
height: 400px;
border-radius: 50%;
background: radial-gradient(circle, rgba(99,102,241,0.2) 0%, transparent 70%);
filter: blur(60px);
pointer-events: none;
z-index: 0;
}
/* ノイズテクスチャオーバーレイ(繊細に) */
.noise-overlay::after {
content: '';
position: fixed;
inset: 0;
opacity: 0.03;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
pointer-events: none;
z-index: 9999;
}
/* セクション間のフルードディバイダー */
.section-divider {
height: 1px;
background: linear-gradient(90deg, transparent, rgba(var(--text-rgb), 0.06) 50%, transparent);
margin: var(--space-section) 0;
}
ルール:
- オーブ:カードやヒーローの後ろに配置。ふわっと現れるように。
- ノイズ:不透明度0.02-0.04。それ以上は強すぎる。
- フルードディバイダー:70%透過→完全透過
- 背景グラデーションの配置:ヒーローセクションでは常に少なくとも1つは上部に配置
- 奥行きレイヤーの順序:背景グラデーション(z-index: 0)→ オーブ(z-index: 1)→ コンテンツ(z-index: 2)→ ノイズオーバーレイ(z-index: 9999)
テクノロジー仕様
HTML構造
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>プロジェクトタイトル</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<script src="https://unpkg.com/lucide@latest"></script>
</head>
- フォント:常にInter(このデザインシステムのデフォルトフォント)
- Lucide:常にbodyの最後で初期化する(
<script>lucide.createIcons();</script>) - ビューポート:常に
<meta name="viewport" content="width=device-width, initial-scale=1.0">を含める
フォントの優先順位
- Inter(デフォルト、SaaS、テック、コーポレートに最適)
- Space Grotesk(クリエイティブ、プレミアム、ランディングページに最適)
- Playfair Display(見出し用。高級感、エディトリアル風)
- JetBrains Mono(コード表示のみ)
フォントペアリングの例:
- モダンテック:見出しはInter 700、本文はInter 400
- クリエイティブ:見出しはSpace Grotesk 700、本文はInter 400
- プレミアム:見出しはPlayfair Display 700、本文はInter 400
React / Vue ガイドライン
JSX/テンプレートとモジュールCSSで上記のCSSパターンすべてを使用します。
Reactの例:
import './Card.css';
export default function Card({ title, description, icon }) {
return (
<div className="card">
<div className="card-icon-box">
<i data-lucide={icon} className="icon"></i>
</div>
<h3 className="card-title">{title}</h3>
<p className="body-text">{description}</p>
</div>
);
}
Reactコンポーネントのルール:
- インラインスタイルは避け、常に
.module.cssまたはCSSクラスを使用する - アイコンは
useEffectで初期化する:
useEffect(() => {
if (typeof lucide !== 'undefined') {
lucide.createIcons();
}
}, []);
- トランジションとアニメーションにはclsxやclassnamesのようなライブラリは必要ない。プレーンなCSSで十分。
- prop:
children、className、styleを常に許可する
Vueの例:
<template>
<div class="card">
<div class="card-icon-box">
<i :data-lucide="icon" class="icon"></i>
</div>
<h3 class="card-title">{{ title }}</h3>
<p class="body-text">{{ description }}</p>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
const props = defineProps({
title: String,
description: String,
icon: { type: String, default: 'zap' }
});
onMounted(() => lucide.createIcons());
</script>
Vueコンポーネントのルール:
<style scoped>を使用する- スタイルの競合を避けるために常にスコープ付きCSSを使用する
- Composition API(
<script setup>)を優先する
設計仕様書の出力
コードと共に、常に簡潔な設計仕様書(コメント内)をHTMLファイルの先頭か、別途コードファイルに含めます。
<!--
デザイン仕様書
----------
プロジェクト: SaaSランディングページ
テーマ: ダーク
雰囲気: Calm/Tech(パープルブルー + ティール)
タイポグラフィ: Inter(すべてのテキスト)
アクセントカラー: インディゴ #6366f1
レイアウト: ベントーグリッド + ヒーロー
キーコンポーネント: グラスカード、CTAボタン、ロゴ
API/データソース: なし(静的デモ)
インタラクション: カードホバー浮上、ページ読み込みフェードイン
備考: 背景グラデーションは3層、上部に1つ
-->
仕様書に含める内容:
- プロジェクトタイプ
- テーマ(ダーク/ライト)
- 雰囲気パレット名
- 使用フォント
- アクセントカラー
- レイアウトシステム
- キーコンポーネント
- API/データソース(ある場合)
- インタラクション/アニメーション
- デザイン上の決定に関する備考
チェックリスト:AI生成UIの防止
コードを生成する前に、このチェックリストを実行します。
- 背景にフラットカラーはないか?(拡散グラデーションを使用すること)
- タイポグラフィのコントラストは3:1以上か?
- カードのボーダー半径は20px以上か?
- 絵文字アイコンは使っていないか?(SVGのみ)
-
transition: all 0.3s easeは使っていないか?(カスタムイージングを使用すること) - 上端ハイライト(
::before)はあるか? - ボタンはピル型か?(
border-radius: 50px) - コンテンツ幅は1120px以下か?(詰めすぎないこと)
- スペーシングに変数(
--space-*)を使用しているか? - Lucideアイコンは初期化されているか?
- 設計仕様書は含まれているか?
設計は味方であり、敵ではありません。誰もが美しいUIを作ることができます。