mcpField
P
premium-frontend-design

premium-frontend-design

github.com/kv0906デザイン・UI181.4k 回インストール2 週間前に更新
リポジトリ

premium-frontend-design について

premium-frontend-designは、本番品質のフロントエンドを作る開発者向けのスキルです。事前のデザイン方針決定に加え、レイアウト、動き、読みやすさ、視覚効果の指針を示します。

主な機能

  1. 01目的、トーン、印象的な要素の設定
  2. 02CSS、Framer Motion、GSAPの選択
  3. 03配色、タイポグラフィ、レイアウトの規則
  4. 04グラスモーフィズムなどの視覚効果
  5. 05アクセシビリティ、性能、動きの制御

活用シーン

  1. 01SaaSランディングページのデザイン方針作成
  2. 02ダッシュボードのグリッドとコンポーネント設計
  3. 03要件に応じたアニメーション手法の選択

インストール

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

$npx skills add https://github.com/kv0906/cc-skills --skill premium-frontend-design

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

同梱ファイル

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

examples/
01-racing-dashboard.tsx
02-cyberpunk-platform.tsx
03-bioluminescent-landing.tsx
04-fintech-protocol.tsx
05-neural-interface.tsx
shaders/
cppn-generative.glsl.ts
data-grid.glsl.ts
digital-liquid.glsl.ts
holographic.glsl.ts
templates/
bento-grid.tsx
cppn-hero.tsx
dashboard-widgets.tsx
glass-components.tsx
globe-hero.tsx
hero-section.tsx
mesh-gradient-hero.tsx
preloader.tsx
terminal.tsx
wave-hero.tsx

詳細

プレミアムなフロントエンドデザインスキル

このスキルは、生き生きとした本番品質のフロントエンドインターフェースの制作を支援します。ありきたりでも、コピー&ペーストでもなく、ユーザーの記憶に残る、本当に練り上げられた体験を作り上げます。

「優れたインターフェースと忘れられないインターフェースを分けるのは、すべてのピクセルに込められた意図です。」


依存関係(柔軟に選択可能)

このスキルはフレームワークに依存しません。ユーザーの好みやプロジェクトのニーズに応じて、パッケージを選択してください。

コア3D(WebGLテンプレート向け)
pnpm add three @react-three/fiber @react-three/drei
アニメーション(ユーザーの好みに応じて選択)
ライブラリ最適な用途複雑さバンドルサイズ
CSS/Tailwindシンプルなトランジション、マイクロインタラクション低0KB
Framer MotionReactネイティブのような操作感、レイアウトアニメーション、ジェスチャー中~30KB
GSAP複雑なタイムライン、スクロール連動、テキストエフェクト高~60KB
GSAP + ClubSplitText、ScrollTrigger、MorphSVG高~80KB
# Framer Motion (simpler, React-idiomatic)
pnpm add framer-motion

# GSAP (powerful, timeline-based)
pnpm add gsap @gsap/react
# Note: SplitText, ScrollTrigger require GSAP Club license

選択ガイド:

  • ユーザーが「シンプル」または「軽量」と言った場合 → CSS + Framer Motion
  • ユーザーが「複雑なアニメーション」または「スクロールエフェクト」と言った場合 → GSAP
  • ユーザーが「テキストアニメーション」または「テキスト分割」と言った場合 → GSAP + SplitText
  • ユーザーが指定しない場合 → Framer Motionをデフォルトにします(APIがよりシンプルなため)
任意の拡張機能
# Mesh gradients (for mesh-gradient-hero)
pnpm add @paper-design/shaders-react

# Icons
pnpm add lucide-react

# Charts/Sparklines (for dashboards)
pnpm add recharts
# or lightweight: pnpm add @visx/shape @visx/scale
ブラウザー互換性に関する注意事項
  • backdrop-filter:Firefox < 103ではサポートされていません(代替の背景を追加してください)
  • WebGL:古いデバイス向けにCSSのフォールバックを用意してください
  • @starting-style:Chrome 117+、Safari 17.4+(段階的な機能強化)

基本理念

「生き生きとした」原則

インターフェースが生き生きとして感じられるのは、次のような場合です。

  • 呼吸している:控えめな環境アニメーション、パーティクル、シェーダーエフェクトが、常に動きながらも気を散らさない演出を生み出します
  • 反応する:マイクロインタラクションが、ユーザーのあらゆる操作に心地よいフィードバックで応えます
  • 奥行きがある:レイヤー、視差効果、グラスモーフィズム、シャドウが立体的な空間を作り出します
  • 意外性がある:少なくとも一つの要素が、楽しい形で期待を裏切ります
デザイン思考(コードを書く前に)

一行も書き始める前に、次の問いに答えてください。

  1. 目的:どのような問題を解決しますか?誰が使いますか?

  2. トーン:極端な方向性を一つ選んでください(組み合わせないでください)。

    • 徹底的にミニマル
    • マキシマリストな混沌
    • レトロフューチャー/サイバーパンク
    • オーガニック/ナチュラル
    • ラグジュアリー/洗練
    • 遊び心のある/おもちゃのような
    • エディトリアル/雑誌風
    • ブルータリスト/粗削り
    • アールデコ/幾何学的
    • インダストリアル/実用本位
    • 生物発光/SF
    • ミッションコントロール/テクニカル
  3. 一つの決め手:人の記憶に残る要素は何ですか?優れたインターフェースには、必ず際立った瞬間があります。

  4. 制約:フレームワーク、パフォーマンス予算、アクセシビリティ要件。

重要:大胆なマキシマリズムも、洗練されたミニマリズムも、どちらも有効です。鍵となるのは強さではなく、意図です。完璧に仕上げた一つのアニメーションは、平凡な50個のアニメーションに勝ります。


驚きと明快さのフレームワーク

依頼内容が曖昧な場合や、デザインの判断を説明する必要がある場合は、これを使ってください。目指すのは、目的のある驚きです。

1. 階層のガードレール
  • 主役となる演出は1つ(シェーダー、パーティクルシステム、またはグローブ)。それ以外はすべて、読みやすさを支えます。
  • 補助的な演出は1つ(マイクロインタラクション、アニメーション付き統計カード、または発光するCTA)。それ以上は追加しません。
  • レイアウトの原則:Hero (wild) → Content blocks (calm) → Proof (calm) → CTA (highlighted)。
  • ページにスクロール1画面分を超える文章がある場合は、2つ目ごとのセクションをほぼ静的にします。
2. タイポグラフィの規律
  • 見出し用フォントは最大2種類(ディスプレイ用+本文用)。等幅フォントはデータに限って使います。
  • 見出しの文字間隔は ≥ -0.04em。これより狭くすると、読みやすさが損なわれます。
  • 本文の幅の目安:デスクトップでは1行あたり55~75文字、モバイルでは35~45文字。
  • 大きなディスプレイテキストには、必ず80文字未満の平易な補足文を添えてください。
3. 色とコントラストのルール
  • ネオンの使用は主要な CTA + 1 つのアクセントに限定します。それ以外はすべて、ジンク/ニュートラルのパレットにします。
  • 背景が複雑な場合(シェーダー、グラデーション、パーティクル)は、テキストの背後に bg-black/70 または bg-slate-950/70 のスクリーンを追加します。
  • サイバーパンクな美しさを優先する場合でも、本文のコントラスト比は 4.5:1 以上に保ちます。
  • リリース前にグレースケールでのプレビューを確認します。濁って見える場合は、パレットを控えめにします。
4. モーションの制限
  • デフォルト:CSS または Framer Motion を使用し、duration は ≤ 400ms、イージングは cubic-bezier(0.34, 1.56, 0.64, 1) にします。
  • GSAP/WebGL への切り替えは、要件でシネマティックまたはインタラクティブな体験が明示的に求められている場合に限ります。
  • ビューポートごとの連続アニメーションは最大 1 つにします(例:シェーダーまたは波形バーのどちらか一方で、両方は使いません)。
  • 「穏やかモード」を用意します。prefers-reduced-motion が有効な場合、またはユーザーがヒーローをスクロールして通過した場合は、必須ではないモーションを無効にします。
5. 要件が曖昧な場合
状況デフォルト任意のアップグレード
ユーザーが「クリーンな SaaS」とだけ言っているmesh-gradient-hero + bento-grid後から「もっと活気を」と求められた場合は、ヒーローの背景を CPPN に変更します
ユーザーが特別な演出なしで「ダッシュボード」と言っているbento-grid + dashboard-widgets + CSS のグローピルデータビジュアライゼーションの承認後に限り、digital-liquid シェーダーを追加します
ユーザーが「ヒーローセクション」とだけ言っているテキスト優先のレイアウト + CSS グラデーションシェーダー/グローブは提案として提示し、デフォルトでは使いません

プロンプトで WebGL が明示されていない場合は、CSS 優先とし、ユーザーがコストを受け入れた場合に限りシェーダーを使用します。


アンチパターン(絶対にしないこと)

ビジュアルのアンチパターン

❌ デフォルトで白/明るい背景にする(ダークモードのほうが高級感があります) ❌ 汎用的なグラデーション(白地に紫から青へのグラデーションは、AI 生成の粗雑な見た目になります) ❌ 均等に配色された、控えめすぎるカラーパレット ❌ 静的で生気のない背景 ❌ 画一的なコンポーネントレイアウト ❌ ローディング/トランジション状態の欠如 ❌ 唐突で、イージングのないアニメーション

タイポグラフィのアンチパターン

❌ 見出しに Inter、Roboto、Arial、システムフォントを使う ❌ すべてに同じフォントを使う ❌ デフォルトの行の高さと文字間隔 ❌ 単調で予測可能な文字サイズのスケール

コードのアンチパターン

❌ インラインスタイルを無秩序に散在させる ❌ テーマ設定用の CSS 変数がない ❌ will-change や GPU アクセラレーションを使わないアニメーション ❌ requestAnimationFrame を使わない Canvas/WebGL ❌ useEffect のクリーンアップ漏れ


デザインシステム

1. カラー設計

ルール:支配的なアクセントカラーは 1 つだけにし、それ以外はすべてそれを引き立てます。

// Premium Dark Theme (Default)
const colors = {
  // Backgrounds (layer from darkest to lightest)
  bg: {
    void: '#000000',      // True black for maximum contrast
    primary: '#050505',   // Main background
    elevated: '#0a0a0a',  // Cards, modals
    subtle: '#111111',    // Hover states
  },
  
  // Glass surfaces
  glass: {
    bg: 'rgba(255, 255, 255, 0.03)',
    border: 'rgba(255, 255, 255, 0.08)',
    hover: 'rgba(255, 255, 255, 0.06)',
  },
  
  // Text hierarchy
  text: {
    primary: '#ffffff',
    secondary: '#a1a1aa',   // zinc-400
    muted: '#71717a',       // zinc-500
    ghost: '#3f3f46',       // zinc-700
  },
  
  // Accent (choose ONE per project)
  accent: '#ff4d00',  // Neon Orange
  // accent: '#00f3ff',  // Neon Cyan
  // accent: '#ccff00',  // Neon Lime
  // accent: '#F5E445',  // Premium Yellow
  // accent: '#a855f7',  // Electric Purple
}

アクセントカラーの使用ルール:

  • 主要なアクション:アクセントカラーをそのまま使用
  • 二次的な要素:不透明度 20% のアクセントカラー
  • 境界線/ライン:不透明度 30% のアクセントカラー
  • グロー:ぼかしを加えた、不透明度 40〜60% のアクセントカラー
  • 大きな背景領域にはアクセントカラーを使いません
2. タイポグラフィシステム

ルール:インパクトにはディスプレイフォント、読みやすさには本文フォント、データには等幅フォントを使います。

/* Tier 1: Display/Headlines - BOLD, characterful */
--font-display: 'Chakra Petch', 'Orbitron', 'Bebas Neue', 'Playfair Display';

/* Tier 2: Headings - Geometric, modern */
--font-heading: 'Manrope', 'Outfit', 'Syne', 'Space Grotesk';

/* Tier 3: Body - Clean, highly legible */
--font-body: 'Plus Jakarta Sans', 'DM Sans', 'Satoshi', 'General Sans';

/* Tier 4: Data/Code - ALWAYS monospace */
--font-mono: 'JetBrains Mono', 'Fira Code', 'IBM Plex Mono';

タイポグラフィのパターン:

/* Hero Headlines: Massive, tight, aggressive */
.headline {
  font-family: var(--font-display);
  font-size: clamp(3rem, 12vw, 10rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}

/* Section Titles */
.section-title {
  font-family: var(--font-heading);
  font-size: clamp(1.5rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* Technical Labels */
.label {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}

/* Data Display */
.data {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
3. 余白とレイアウト

ルール:非対称性が興味を生みます。グリッドは出発点であり、制約ではありません。

/* Spacing scale (use consistently) */
--space-1: 0.25rem;   /* 4px */
--space-2: 0.5rem;    /* 8px */
--space-3: 0.75rem;   /* 12px */
--space-4: 1rem;      /* 16px */
--space-6: 1.5rem;    /* 24px */
--space-8: 2rem;      /* 32px */
--space-12: 3rem;     /* 48px */
--space-16: 4rem;     /* 64px */
--space-24: 6rem;     /* 96px */
--space-32: 8rem;     /* 128px */

/* Use generous padding on containers */
.container {
  padding-inline: clamp(1rem, 5vw, 4rem);
}

/* Hero sections need breathing room */
.hero {
  min-height: 100vh;
  padding-block: var(--space-32);
}

ベントーグリッドのパターン(ダッシュボード向け):

.bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(150px, auto);
  gap: var(--space-4);
}

/* Feature card spans */
.card-hero { grid-column: span 2; grid-row: span 2; }
.card-wide { grid-column: span 2; }
.card-tall { grid-row: span 2; }

ビジュアルエフェクトライブラリ

1. グラスモーフィズム(正しい方法)
.glass {
  background: rgba(255, 255, 255, 0.03);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
}

/* Elevated glass (for modals, dropdowns) */
.glass-elevated {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 
    0 8px 32px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
2. CRT スキャンラインオーバーレイ
.scanlines::before {
  content: '';
  position: fixed;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    rgba(0, 0, 0, 0.1) 0px,
    rgba(0, 0, 0, 0.1) 1px,
    transparent 1px,
    transparent 2px
  );
  pointer-events: none;
  z-index: 9999;
}
3. フィルムグレインテクスチャ
.grain::before {
  content: '';
  position: fixed;
  inset: 0;
  opacity: 0.03;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
}
4. テックグリッド背景
.tech-grid {
  background-image: 
    linear-gradient(rgba(255, 255, 255, 0.02) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px);
  background-size: 60px 60px;
}
5. ネオングローエフェクト
/* Text glow */
.neon-text {
  text-shadow: 
    0 0 10px currentColor,
    0 0 20px currentColor,
    0 0 40px currentColor,
    0 0 80px currentColor;
}

/* Box glow */
.neon-box {
  box-shadow: 
    0 0 20px var(--accent-alpha-40),
    0 0 40px var(--accent-alpha-20),
    inset 0 0 20px var(--accent-alpha-10);
}

/* Border glow */
.neon-border {
  border: 1px solid var(--accent);
  box-shadow: 
    0 0 10px var(--accent-alpha-50),
    inset 0 0 10px var(--accent-alpha-20);
}

アニメーションのパターン

基本方針
  • 登場アニメーション:一度だけ使い、印象に残るものにします
  • マイクロインタラクション:控えめで高速(150〜300ms)にします
  • 環境モーション:無限に繰り返し、非常にゆっくりと動かし、注意をそらさないようにします
  • ページ遷移:滑らかにし、動きを調和させます
適切なツールの選択
必要なもの使用するもの理由
ホバー/フォーカス状態CSSJS 不要で、即時に反映されます
シンプルな表示アニメーションCSS keyframes軽量です
レイアウトアニメーションFramer Motionlayout prop の効果を利用できます
ジェスチャーベースFramer Motionドラッグ/パンが組み込み済みです
スクロール連動GSAP ScrollTrigger最も強力です
テキスト分割GSAP SplitText業界標準です
複雑なタイムラインGSAP精密に制御できます
SVG モーフィングGSAP MorphSVG代替手段がありません

まずはシンプルな解決策を選びましょう。必要な場合にのみ複雑さを高めてください。

CSS Keyframes ライブラリ
@keyframes fade-up {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes scale-in {
  from { opacity: 0; transform: scale(0.95); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes slide-in-right {
  from { opacity: 0; transform: translateX(20px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes pulse-glow {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}

@keyframes rotate-slow {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes scan-line {
  0% { transform: translateY(-100%); }
  100% { transform: translateY(100vh); }
}
段階的な表示パターン
.stagger-container > * {
  opacity: 0;
  animation: fade-up 0.6s ease-out forwards;
}

.stagger-container > *:nth-child(1) { animation-delay: 0.1s; }
.stagger-container > *:nth-child(2) { animation-delay: 0.2s; }
.stagger-container > *:nth-child(3) { animation-delay: 0.3s; }
.stagger-container > *:nth-child(4) { animation-delay: 0.4s; }
.stagger-container > *:nth-child(5) { animation-delay: 0.5s; }
CSS のみのパターン(依存関係なし)
/* View transition entrance (Chrome 111+, Safari 18+) */
@supports (view-transition-name: none) {
  .card {
    view-transition-name: card;
  }
  
  ::view-transition-old(card),
  ::view-transition-new(card) {
    animation-duration: 0.3s;
  }
}

/* Scroll-driven animations (Chrome 115+) */
@supports (animation-timeline: scroll()) {
  .parallax-bg {
    animation: parallax linear;
    animation-timeline: scroll();
  }
  
  @keyframes parallax {
    from { transform: translateY(0); }
    to { transform: translateY(-30%); }
  }
}

/* Hover with spring-like feel */
.spring-hover {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.spring-hover:hover {
  transform: scale(1.05);
}

/* Glow pulse */
.glow-pulse {
  animation: glow-pulse 2s ease-in-out infinite;
}
@keyframes glow-pulse {
  0%, 100% { box-shadow: 0 0 20px var(--accent-alpha-40); }
  50% { box-shadow: 0 0 40px var(--accent-alpha-60); }
}
GSAP パターン(強力な機能が必要な場合)
// Stagger entrance on scroll
gsap.from('.card', {
  scrollTrigger: {
    trigger: '.cards-section',
    start: 'top 80%',
  },
  y: 60,
  opacity: 0,
  duration: 0.8,
  stagger: 0.1,
  ease: 'power3.out',
});

// Text scramble effect
const scrambleText = (el: HTMLElement, text: string) => {
  const chars = '!<>-_\\/[]{}—=+*^?#';
  let iteration = 0;
  
  const interval = setInterval(() => {
    el.innerText = text
      .split('')
      .map((char, i) => 
        i < iteration ? char : chars[Math.floor(Math.random() * chars.length)]
      )
      .join('');
    
    if (iteration >= text.length) clearInterval(interval);
    iteration += 1/3;
  }, 30);
};

// Smooth parallax
gsap.to('.parallax-bg', {
  scrollTrigger: {
    scrub: 1,
  },
  y: '-30%',
  ease: 'none',
});
Framer Motion パターン
// Page transitions
<AnimatePresence mode="wait">
  <motion.div
    key={page}
    initial={{ opacity: 0, y: 20 }}
    animate={{ opacity: 1, y: 0 }}
    exit={{ opacity: 0, y: -20 }}
    transition={{ duration: 0.3 }}
  />
</AnimatePresence>

// Hover glow effect
<motion.div
  whileHover={{ 
    scale: 1.02,
    boxShadow: '0 0 30px rgba(255, 77, 0, 0.4)',
  }}
  transition={{ type: 'spring', stiffness: 300 }}
/>

// Stagger children
<motion.div
  initial="hidden"
  animate="visible"
  variants={{
    hidden: {},
    visible: { transition: { staggerChildren: 0.1 } },
  }}
>
  {items.map(item => (
    <motion.div
      key={item.id}
      variants={{
        hidden: { opacity: 0, y: 20 },
        visible: { opacity: 1, y: 0 },
      }}
    />
  ))}
</motion.div>

3D と WebGL のパターン

技術スタック
npm install three @react-three/fiber @react-three/drei
基本的なシーンのセットアップ
import { Canvas } from '@react-three/fiber';
import { Stars, Float, MeshDistortMaterial } from '@react-three/drei';

const Scene = () => (
  <Canvas
    camera={{ position: [0, 0, 5], fov: 75 }}
    style={{ position: 'fixed', inset: 0, zIndex: -1 }}
  >
    <ambientLight intensity={0.2} />
    <pointLight position={[10, 10, 10]} color="#ff4d00" />
    <Stars radius={100} depth={50} count={3000} />
    {/* Your 3D content */}
  </Canvas>
);
パーティクル球体(データグローブ)
const ParticleSphere = ({ count = 3000, color = '#ff4d00' }) => {
  const ref = useRef<THREE.Points>(null);
  
  const positions = useMemo(() => {
    const pos = new Float32Array(count * 3);
    for (let i = 0; i < count; i++) {
      const theta = Math.random() * Math.PI * 2;
      const phi = Math.acos(Math.random() * 2 - 1);
      const r = 2;
      pos[i * 3] = r * Math.sin(phi) * Math.cos(theta);
      pos[i * 3 + 1] = r * Math.sin(phi) * Math.sin(theta);
      pos[i * 3 + 2] = r * Math.cos(phi);
    }
    return pos;
  }, [count]);
  
  useFrame(() => {
    if (ref.current) ref.current.rotation.y += 0.001;
  });
  
  return (
    <points ref={ref}>
      <bufferGeometry>
        <bufferAttribute
          attach="attributes-position"
          count={count}
          array={positions}
          itemSize={3}
        />
      </bufferGeometry>
      <pointsMaterial size={0.02} color={color} transparent opacity={0.8} />
    </points>
  );
};
知性を宿すコア(AI の脳)
const SentientCore = () => (
  <Float speed={2} rotationIntensity={0.5}>
    <mesh>
      <sphereGeometry args={[1.5, 64, 64]} />
      <MeshDistortMaterial
        color="#00f3ff"
        wireframe
        distort={0.4}
        speed={2}
      />
    </mesh>
  </Float>
);
パフォーマンスのルール
  1. 常に useFrame 経由で requestAnimationFrame を使用します
  2. モバイルではパーティクル数を減らします(window.innerWidth を確認)
  3. ジオメトリや位置の計算には useMemo を使用します
  4. useEffect の戻り値でアニメーションをクリーンアップします
  5. 深度ソートのために transparent と opacity を設定します

コンポーネントのパターン

1. ローディングとページ遷移

デフォルト(ユーザーから別途指定がない限り、これを採用します):

  • カード/セクションにスケルトンプレースホルダーを表示します(上記のシマー パターンを参照)
  • CSS または Framer Motion のルート遷移を使った、シンプルなフェード/スライドのページ遷移

シネマティックモード(ユーザーが物語性のあるブートシーケンスを希望し、時間/予算がある場合のみ):

  • ブートログ、テキストスクランブル、シェーダー/WebGL 背景を備えた GSAP 駆動のプリローダー
  • データの準備ができたら実際のコンテンツへフェードインする、連携したタイムライン
2. グラスモーフィズムのナビゲーションバー
<nav className="fixed top-4 left-1/2 -translate-x-1/2 z-50">
  <div className="glass rounded-full px-6 py-3 flex items-center gap-8">
    <Logo />
    <NavLinks />
    <ThemeToggle />
    <CTA />
  </div>
</nav>
3. ライブターミナル
const Terminal = ({ logs }) => {
  const scrollRef = useRef();
  
  useEffect(() => {
    scrollRef.current?.scrollTo(0, scrollRef.current.scrollHeight);
  }, [logs]);
  
  return (
    <div className="glass font-mono text-xs">
      <header className="border-b border-white/10 px-4 py-2">
        <span className="text-accent">&gt;</span> System Logs
        <span className="ml-auto w-2 h-2 bg-green-500 rounded-full animate-pulse" />
      </header>
      <div ref={scrollRef} className="h-64 overflow-y-auto p-4">
        {logs.map(log => (
          <div key={log.id}>
            <span className="text-zinc-600">{log.time}</span>
            <span className={levelColor[log.level]}>[{log.level}]</span>
            <span>{log.message}</span>
          </div>
        ))}
      </div>
    </div>
  );
};
4. スパークライン付き統計カード
const StatCard = ({ icon, label, value, change, trend }) => (
  <motion.div
    whileHover={{ scale: 1.02, boxShadow: '0 0 30px var(--accent-alpha-30)' }}
    className="glass p-4"
  >
    <div className="flex justify-between">
      <div className="p-2 rounded-lg bg-accent/10 text-accent">{icon}</div>
      <span className={change > 0 ? 'text-green-400' : 'text-red-400'}>
        {change > 0 ? '+' : ''}{change}%
      </span>
    </div>
    <div className="mt-4 font-mono text-2xl font-bold">{value}</div>
    <div className="text-xs text-zinc-500 uppercase">{label}</div>
    <Sparkline data={trend} className="mt-2 h-8" />
  </motion.div>
);

品質チェックリスト

リリース前に、以下を確認します。

ビジュアル
  • ダークモードがデフォルトで、高級感のある見た目になっている
  • 一貫して使用する主要なアクセントカラーが 1 色になっている
  • グラス効果に適切なぼかしと境界線がある
  • テクスチャとしてスキャンラインまたはグレインのオーバーレイがある
  • 暗い背景に純白のテキストを使用していない(最大でも #f4f4f5)
タイポグラフィ
  • 見出しにディスプレイフォントを使用している(Inter/Roboto 以外)
  • すべてのデータ/コード/数値に等幅フォントを使用している
  • 適切な階層構造になっている(明確に区別できるレベルが 3~4 段階)
  • 大きな文字の字間を調整している
アニメーション
  • 読み込み時に段階的な表示アニメーションがある
  • ホバー状態に transform とグロー効果がある
  • すべての canvas が滑らかな 60fps で動作する
  • 目的のないアニメーションがない
コード
  • すべての色に CSS 変数を使用している
  • モバイルファーストでレスポンシブに対応している
  • useEffect にクリーンアップ関数がある
  • 3D コンテンツにエラーバウンダリがある

アクセシビリティ(高級感とアクセシビリティは両立します)

優れたデザインは、誰もが使いやすいものです。以下は必須です。

モーションへの配慮
/* ALWAYS respect user preferences */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
// React hook for motion preference
const usePrefersReducedMotion = () => {
  const [prefersReduced, setPrefersReduced] = useState(false);
  
  useEffect(() => {
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    setPrefersReduced(mq.matches);
    const handler = (e: MediaQueryListEvent) => setPrefersReduced(e.matches);
    mq.addEventListener('change', handler);
    return () => mq.removeEventListener('change', handler);
  }, []);
  
  return prefersReduced;
};

// Usage
const shouldAnimate = !usePrefersReducedMotion();
WebGL のアクセシビリティ
// Always mark decorative 3D as hidden
<div aria-hidden="true" className="pointer-events-none">
  <Canvas>{/* decorative background */}</Canvas>
</div>

// Provide text alternatives for meaningful 3D
<div role="img" aria-label="3D visualization of global network connections">
  <Canvas>{/* data visualization */}</Canvas>
</div>
色のコントラスト
要素最小比率目標
本文4.5:17:1
大きな文字(18px 以上)3:14.5:1
UI コンポーネント3:14.5:1
装飾要素該当なし該当なし
/* Safe text colors on dark backgrounds */
--text-primary: #ffffff;     /* ✓ 21:1 on #000 */
--text-secondary: #a1a1aa;   /* ✓ 7.2:1 on #000 */
--text-muted: #71717a;       /* ✓ 4.6:1 on #000 */
--text-ghost: #52525b;       /* ⚠ 3.2:1 - decorative only */
キーボード操作
// Interactive 3D elements need keyboard support
<mesh
  tabIndex={0}
  onKeyDown={(e) => e.key === 'Enter' && handleClick()}
  onClick={handleClick}
/>

// Focus indicators for glass components
.glass:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

モバイルとレスポンシブの戦略

高級感のあるエクスペリエンスは、あらゆる画面に自然に適応します。単に縮小するのではなく、再設計しましょう。

WebGL のフォールバック
// Detect low-power devices
const useIsLowPowerDevice = () => {
  const [isLowPower, setIsLowPower] = useState(false);
  
  useEffect(() => {
    const isLow = 
      window.innerWidth < 768 ||
      navigator.hardwareConcurrency <= 4 ||
      /Android|iPhone|iPad/.test(navigator.userAgent);
    setIsLowPower(isLow);
  }, []);
  
  return isLowPower;
};

// Usage in hero components
const HeroBackground = () => {
  const isLowPower = useIsLowPowerDevice();
  
  if (isLowPower) {
    return <CSSGradientFallback />; // Lighter alternative
  }
  
  return <WebGLBackground />;
};
パフォーマンス予算
デバイスJS の予算アニメーションの目標
デスクトップ< 500KBWebGL で 60fps
タブレット< 300KB30fps または CSS のみ
モバイル< 150KBCSS のみ、WebGL なし
タッチ操作
// Replace hover with tap/long-press on mobile
<motion.div
  whileHover={{ scale: 1.02 }}  // Desktop
  whileTap={{ scale: 0.98 }}    // Mobile
  onTouchStart={handleTouch}
/>

// Increase touch targets
.button {
  min-height: 44px;  /* Apple HIG */
  min-width: 44px;
  padding: 12px 24px;
}
レスポンシブなタイポグラフィ
/* Fluid type scale */
--text-hero: clamp(2.5rem, 8vw, 7rem);
--text-h1: clamp(2rem, 5vw, 4rem);
--text-h2: clamp(1.5rem, 3vw, 2.5rem);
--text-body: clamp(1rem, 2vw, 1.125rem);

/* Reduce letter-spacing on mobile */
@media (max-width: 768px) {
  .headline {
    letter-spacing: -0.02em; /* Less aggressive than desktop */
  }
}

ローディングとエラーの状態

高級感のある UX では、あらゆる状態を美しく扱います。

スケルトンローダー
// Glass skeleton with shimmer
const Skeleton = ({ className }: { className?: string }) => (
  <div 
    className={`relative overflow-hidden rounded-lg bg-white/5 ${className}`}
  >
    <div 
      className="absolute inset-0 -translate-x-full animate-[shimmer_2s_infinite] bg-gradient-to-r from-transparent via-white/10 to-transparent"
    />
  </div>
);

// Usage
<div className="space-y-4">
  <Skeleton className="h-8 w-3/4" />
  <Skeleton className="h-4 w-full" />
  <Skeleton className="h-4 w-5/6" />
</div>
@keyframes shimmer {
  100% { transform: translateX(100%); }
}
エラーバウンダリ(スタイル付き)
const ErrorFallback = ({ error, resetErrorBoundary }) => (
  <div className="glass p-8 text-center">
    <div className="mx-auto mb-4 h-16 w-16 rounded-full bg-red-500/10 flex items-center justify-center">
      <AlertTriangle className="h-8 w-8 text-red-400" />
    </div>
    <h2 className="text-xl font-semibold text-white mb-2">
      Something went wrong
    </h2>
    <p className="text-zinc-400 mb-4 font-mono text-sm">
      {error.message}
    </p>
    <button 
      onClick={resetErrorBoundary}
      className="px-4 py-2 bg-white/10 rounded-lg hover:bg-white/20 transition"
    >
      Try again
    </button>
  </div>
);
空の状態
const EmptyState = ({ 
  icon: Icon, 
  title, 
  description, 
  action 
}: EmptyStateProps) => (
  <div className="flex flex-col items-center justify-center py-16 text-center">
    <div className="mb-4 rounded-full bg-white/5 p-4">
      <Icon className="h-8 w-8 text-zinc-500" />
    </div>
    <h3 className="text-lg font-medium text-white mb-1">{title}</h3>
    <p className="text-zinc-400 mb-4 max-w-sm">{description}</p>
    {action}
  </div>
);

// Usage
<EmptyState
  icon={Inbox}
  title="No messages yet"
  description="When you receive messages, they'll appear here."
  action={<Button>Send your first message</Button>}
/>
データのローディング状態
// Optimistic UI with rollback
const [items, setItems] = useState(data);
const [pending, startTransition] = useTransition();

const addItem = (newItem) => {
  // Optimistic update
  setItems(prev => [...prev, { ...newItem, pending: true }]);
  
  startTransition(async () => {
    try {
      await api.createItem(newItem);
    } catch {
      // Rollback on error
      setItems(prev => prev.filter(i => i.id !== newItem.id));
      toast.error('Failed to add item');
    }
  });
};

フレームワークとの統合

Next.js App Router
// Client boundary for WebGL components
// app/components/hero-client.tsx
'use client';

import dynamic from 'next/dynamic';

// Lazy load heavy 3D components
const WebGLHero = dynamic(() => import('./webgl-hero'), {
  ssr: false,
  loading: () => <HeroSkeleton />,
});

export default function HeroClient() {
  return <WebGLHero />;
}
// Server component wrapper
// app/page.tsx
import HeroClient from './components/hero-client';

export default function Page() {
  return (
    <main>
      {/* Server-rendered SEO content */}
      <h1 className="sr-only">Your SEO Title</h1>
      
      {/* Client-side 3D hero */}
      <HeroClient />
    </main>
  );
}
WebGL コンテンツの SEO
// WebGL isn't crawlable - always provide text alternatives
<section aria-labelledby="hero-title">
  {/* Hidden but crawlable */}
  <h1 id="hero-title" className="sr-only">
    AI-Powered Trading Platform
  </h1>
  <p className="sr-only">
    {seoDescription}
  </p>
  
  {/* Visual hero (not crawled) */}
  <div aria-hidden="true">
    <Canvas>...</Canvas>
  </div>
  
  {/* Visible text (crawled) */}
  <div className="relative z-10">
    <span className="text-7xl">{visibleTitle}</span>
  </div>
</section>
ローディング状態を伴うデータ取得
// Server Component with Suspense
import { Suspense } from 'react';

async function DashboardData() {
  const data = await fetchDashboardData();
  return <DashboardWidgets data={data} />;
}

export default function Dashboard() {
  return (
    <div className="bento-grid">
      <Suspense fallback={<WidgetSkeleton />}>
        <DashboardData />
      </Suspense>
    </div>
  );
}

テンプレートクイックリファレンス

テンプレートPropsWebGLモバイル向けフォールバック最適なアニメーションライブラリ
cppn-herotitle、description、ctaButtons、microDetailsはいCSS グラデーションGSAP (SplitText)
mesh-gradient-herocolors[]、speed、distortion、swirlいいえ*ネイティブFramer Motion
wave-herotitle、subtitle、placeholder、onPromptSubmitはい単色背景GSAP
globe-heroglobeImage、dashboardImage、accentColorいいえネイティブFramer Motion
hero-sectiontitle、badge、primaryCTA、accentColorはい星のCSSどちらでも
bento-gridchildren(カードレイアウト)いいえネイティブCSS または Framer
dashboard-widgetsvalue、change、trend[]いいえネイティブFramer Motion
terminallogs[]、titleいいえネイティブCSS
preloaderonComplete、messages[]任意CSS バージョンGSAP
glass-components各種いいえネイティブCSS

*mesh-gradient-hero は @paper-design/shaders-react を使用します(WebGL ではなく Canvas)


テンプレート活用ガイド(堅実な土台から始め、意図的に驚きを加える)

目標基本構成(明快さ優先)任意の驚きのアップグレード使用を避ける条件
マーケティング/ウェイトリストmesh-gradient-hero + glass-components + bento-grid の価値提案ヒーローを cppn-hero に差し替えるか、ソーシャルプルーフ用に wave-hero の帯を追加コピーが長文、または製品のコンプライアンス要件が厳しい
AI/研究向けランディングページcppn-hero + dashboard-widgets(指標)+ terminal のログholographic シェーダーのセクションや globe-hero の中間セクションを追加ユーザーが印刷に適した成果物を必要としている
暗号資産/金融globe-hero + bento-grid の KPI + dashboard-widgets + CTA ストリップdata-grid シェーダーの背景やスクロールティッカーを追加パフォーマンス予算が 200KB 未満、またはモバイル専用
開発者向けツールwave-hero + terminal + glass-components のカードdigital-liquid シェーダーや 3D デバイスのモックアップを導入対象が保守的なトーンを求めるエンタープライズの購入担当者
製品ダッシュボードbento-grid + dashboard-widgets + mesh-gradient-hero(静的)小規模な WebGL モジュール(知覚するコア、パーティクルグローブ)を追加データが密集しており、表形式での明快さが必要
レイアウトフローのレシピ
  1. ヒーロー(印象的な演出) → 主要な指標/価値提案(落ち着いた表現)→ 製品の実証(画面)→ お客様の声/ロゴ → CTA(発光ボタン)。
  2. ダッシュボードページ:ファーストビューの要約(最小限)→ 機能グリッド(非対称)→ ライブデータ(ターミナル/スパークライン)→ ヘルプ/リソース(落ち着いた表現)。
  3. ドキュメント/プラットフォーム:すっきりしたヘッダー(CSS モードの mesh-gradient-hero)→ ナビゲーショングリッド → コンテンツ領域(等幅フォント)→ CTA。

各フローで、彩度の高いパネルは最大 2 つにしてください。さらに活気が必要な場合は、シェーダーを増やすのではなく、CTA やアクセントの枠線をアニメーションさせてください。


テンプレートのリミックスと適応パターン

ニーズアクション注記
WebGL → CSS にダウングレードcppn-hero を mesh-gradient-hero に置き換え、コピーはそのままにします。シェーダーの背景を bg-gradient-to-b に差し替えます。ユーザーが「モバイルファースト」「パフォーマンス」「軽量」と述べた場合に使用します。
CSS → WebGL にアップグレードmesh-gradient-hero をベースにしてから、ShaderBackground を挿入し、cppn-hero の props を再利用します。クライアントが「シネマティック」または「実験的」なものを希望していることを確認してから使用します。
シェーダーの差し替えシェーダーを使うヒーローは、インポートを差し替えることで別のシェーダーに変更できます(例:holographic ↔ digital-liquid)。uniform 名は一貫性を保ちます。差し替えとあわせて、新しいアクセントカラーのパレットを記載します。
コンテンツ密度モードデザインに大量のテキストを載せる必要がある場合は、ヒーローの装飾はそのままにし、それ以降のすべてのセクションをシンプルなボーダー付きの bg-black にします。例:上部に cppn-hero を配置し、その下にプレーンなグラスカードで bento-grid を配置します。
プロンプトからテンプレートを選ぶ際のデフォルト- 「クリーンな SaaS」→ Mesh gradient パッケージ
- 「AI プラットフォーム」→ CPPN ヒーロー + ダッシュボードの指標
- 「暗号資産取引」→ Globe ヒーロー + ティッカー
- 「開発者向け CLI」→ Wave ヒーロー + ターミナル
モデルが新しい構成を幻覚しないよう、回答ではこれらのデフォルトを直接伝えます。

迷った場合は、ベースラインから始めて、実用的なレイアウトをリリースし、その後の提案として「驚き」のあるアップグレードを1つだけ提示します(「必要であれば、よりニューラルな雰囲気を出すために CPPN シェーダーに差し替えることもできます。」など)。


テンプレートとシェーダーの選択ガイド

ユーザーの依頼に基づいて適切なテンプレートとシェーダーを選ぶには、このガイドを使用します。すべてに同じヒーローをデフォルトで使わないでください。ドメインに合った美的表現を選びます。

業界/分野のマッピング
業界ヒーローテンプレートシェーダーアクセントカラートーン
AI/ML/ニューラルcppn-herocppn-generativeシアン #00f3ff / パープル #a855f7有機的、生き生きとした、数学的
暗号資産/DeFi/取引globe-herodata-gridパープル #9b87f5 / アンバー #f59e0bグローバル、技術的、金融的
開発者ツール/APIwave-herodigital-liquidブルー #1f3dbc / オレンジ #ff4d00技術的、ダイナミック、開発者向け
SaaS/B2B/製品mesh-gradient-hero(CSS のみ)ソフトなパステルカラークリーン、プロフェッショナル、信頼感のある
クリエイティブエージェンシーhero-section (CyberpunkHero)holographicネオンカラー大胆、実験的、芸術的
フィンテック/ダッシュボードbento-grid + dashboard-widgetsdata-gridグリーン #10b981 / ブルー #3b82f6データ豊富、精密、分析的
キーワードに基づく選択

ユーザーの依頼を分析する際は、キーワードをテンプレートに対応付けます。

User Request Analysis:
├── Contains "AI", "neural", "intelligent", "learning", "model", "GPT"
│   → cppn-hero + cppn-generative shader
│   → Organic, flowing backgrounds that feel "alive"
│
├── Contains "crypto", "blockchain", "trading", "global", "DeFi", "web3"
│   → globe-hero + data-grid shader
│   → Earth imagery, global reach, financial precision
│
├── Contains "developer", "API", "code", "build", "deploy", "ship"
│   → wave-hero + digital-liquid shader
│   → Dynamic bars, typing animations, terminal aesthetic
│
├── Contains "SaaS", "product", "waitlist", "brand", "startup", "launch"
│   → mesh-gradient-hero (no WebGL needed)
│   → Soft, fluid gradients, professional feel
│
├── Contains "futuristic", "cyber", "agency", "creative", "portfolio"
│   → hero-section (CyberpunkHero) + holographic shader
│   → Particle spheres, text scramble, scanlines
│
└── Contains "dashboard", "analytics", "metrics", "data", "monitoring"
    → bento-grid + dashboard-widgets + terminal
    → Stat cards, sparklines, live data feeds
パフォーマンスに基づく選択

対象ユーザーとデバイスの制約に基づいて選択します。

パフォーマンス層テンプレート最適な用途
高性能(WebGL)cppn-hero、wave-hero、hero-sectionデスクトップファースト、ポートフォリオサイト、クリエイティブエージェンシー
中程度(Canvas/画像)globe-heroマーケティングサイト、暗号資産のランディングページ
軽量(CSS のみ)mesh-gradient-hero、bento-gridモバイルファースト、SaaS、B2B、アクセシビリティ重視
シェーダーの組み合わせガイド
シェーダー美的表現相性の良い用途
cppn-generativeニューラル、有機的、数学的AI 製品、ジェネレーティブアート、研究ツール
data-gridマトリックス、技術的、サイバーパンク暗号資産、フィンテック、開発者ツール
digital-liquid流れるような、ダイナミック、流動的クリエイティブツール、メディアプラットフォーム
holographicSF、虹色に輝く、未来的ゲーム、AR/VR、実験的なプロジェクト
クイック選択フローチャート
Is performance critical (mobile-first)?
├── YES → mesh-gradient-hero (CSS only)
└── NO → Continue...
    │
    Is it AI/ML related?
    ├── YES → cppn-hero
    └── NO → Continue...
        │
        Is it crypto/global/financial?
        ├── YES → globe-hero
        └── NO → Continue...
            │
            Is it developer-focused?
            ├── YES → wave-hero
            └── NO → hero-section (CyberpunkHero)

ファイル構成

premium-frontend-skill/
├── SKILL.md                           # This document
├── examples/
│   ├── 01-racing-dashboard.tsx        # Motorsport telemetry
│   ├── 02-cyberpunk-platform.tsx      # Developer platform
│   ├── 03-bioluminescent-landing.tsx  # AI agency landing
│   ├── 04-fintech-protocol.tsx        # DeFi interface
│   └── 05-neural-interface.tsx        # Sentient AI core
├── templates/
│   ├── preloader.tsx                  # Boot sequence loader
│   ├── glass-components.tsx           # Glassmorphic UI elements
│   ├── terminal.tsx                   # Live logs display
│   ├── bento-grid.tsx                 # Dashboard layout system
│   ├── dashboard-widgets.tsx          # Stat cards, charts, metrics
│   ├── hero-section.tsx               # CyberpunkHero + StarfieldScene
│   ├── cppn-hero.tsx                  # Neural network shader hero
│   ├── mesh-gradient-hero.tsx         # Fluid gradient hero (CSS-light)
│   ├── wave-hero.tsx                  # Animated wave bars hero
│   └── globe-hero.tsx                 # 3D globe with dashboard
└── shaders/
    ├── cppn-generative.glsl.ts        # Neural pattern generator
    ├── digital-liquid.glsl.ts         # Flowing noise effect
    ├── data-grid.glsl.ts              # Matrix/grid effect
    └── holographic.glsl.ts            # Hologram interference

忘れないでください

「目指すのは、生き生きとした、映画のような、忘れられないインターフェースを作ることです。すべてのピクセルに意図を込めましょう。これは単なるウェブサイトではありません。体験そのものです。」

遠慮はいりません。枠にとらわれず、独自のビジョンを徹底的に追求したときに何が実現できるのか、存分に示してください。

コメント