Lecture 1LP設計 — ランディングページの構成を考える

12:00

LP設計 — ランディングページの構成を考える

ランディングページ(LP)は、訪問者を特定のアクションへ導くために設計された1枚のWebページです。商品購入、サービス申込み、メルマガ登録など、明確な目的を持ったページであり、通常のWebサイトとは設計思想が根本的に異なります。この講義では、高コンバージョンのLPに必要な構成要素を理解し、Claude Code を使って設計段階を効率化する方法を学びます。

ランディングページの基本構成

成果の出るLPには、決まったパターンがあります。上から順に、以下のセクションで構成するのが王道です。

ヒーローセクション: ページの最上部に表示される、最も重要なエリアです。訪問者が最初に目にする部分であり、3秒以内に「このページは自分に関係がある」と感じさせる必要があります。キャッチコピー、サブテキスト、メインビジュアル、CTAボタンを配置します。

特徴・ベネフィットセクション: サービスや商品の魅力を3〜4つのポイントに整理して伝えます。「何ができるか」ではなく「ユーザーにどんなメリットがあるか」というベネフィット視点で書くことが重要です。アイコンやイラストと組み合わせて視覚的に訴求します。

テスティモニアルセクション: 実際の利用者の声を掲載して信頼性を高めます。名前、写真、具体的な成果を含めると説得力が増します。社会的証明(ソーシャルプルーフ)と呼ばれる心理効果を活用するセクションです。

CTAセクション: Call to Action、つまり行動喚起のエリアです。ページ内に複数回配置するのが効果的で、ヒーロー直下、ページ中盤、ページ最下部の3箇所が一般的です。

FAQセクション: よくある質問を先回りして回答することで、訪問者の不安や疑問を解消します。購入や申込みのハードルを下げる重要な役割を持ちます。

フッター: 会社情報、利用規約、プライバシーポリシーへのリンク、SNSリンクなどを配置します。

コンバージョンを高める設計原則

LPの成否を分ける設計原則を理解しておきましょう。

ファーストビューの法則: 訪問者の約70%はスクロールせずにページを離脱します。つまり、画面に最初に表示される領域(ファーストビュー)に最も重要な情報を集約する必要があります。キャッチコピーとCTAボタンは必ずファーストビューに入れましょう。

1ページ1目的の原則: LPには余計なナビゲーションやリンクを置きません。訪問者の注意を分散させず、ただ一つの目的(コンバージョン)に集中させる設計が鉄則です。

AIDMA/AISASモデル: 注意(Attention)→ 興味(Interest)→ 欲求(Desire)→ 記憶(Memory)→ 行動(Action)という消費者心理の流れに沿ってセクションを配置します。ヒーローで注意を引き、特徴で興味を持たせ、テスティモニアルで欲求を刺激し、FAQで不安を解消し、CTAで行動を促す流れです。

視線誘導(Zパターン・Fパターン): 人はWebページを左上から右下に向かってZ字型、またはF字型に読む傾向があります。重要な要素はこの視線の動線上に配置しましょう。

Claude Code でワイヤーフレームを設計する

実際に Claude Code を使ってLPのワイヤーフレームを作成してみましょう。

> ランディングページのワイヤーフレームをASCIIアートで作って。
  目的: オンライン英会話サービスの新規会員獲得
  セクション: ヒーロー、特徴(3カラム)、お客様の声、FAQ、CTA、フッター
  デスクトップ版(幅1280px想定)で

Claude Code は以下のようなワイヤーフレームを生成します。

┌──────────────────────────────────────────┐
│  Logo                     無料体験はこちら │  ← Sticky Header
├──────────────────────────────────────────┤
│                                            │
│   英語が話せる自分に、出会おう。          │
│   マンツーマンレッスンで確実に上達          │  ← Hero Section
│        [ 無料体験を始める ]                │
│                                            │
├──────────────────────────────────────────┤
│  ┌──────────┐ ┌──────────┐ ┌──────────┐  │
│  │ ★ 24時間 │ │ ★ 1対1  │ │ ★ 月額   │  │  ← Features
│  │ いつでも  │ │ マンツー │ │ 3,980円〜 │  │
│  │ レッスン  │ │ マン対応 │ │ 始められる│  │
│  └──────────┘ └──────────┘ └──────────┘  │
├──────────────────────────────────────────┤
│  "3ヶ月でTOEIC200点UP!" — 田中さん(30代)  │
│  "海外出張で困らなくなった" — 鈴木さん(40代)│  ← Testimonials
│  ★★★★★  ★★★★★                            │
├──────────────────────────────────────────┤
│  Q: 初心者でも大丈夫?  → A: はい、...      │
│  Q: 解約はできる?      → A: いつでも...    │  ← FAQ
│  Q: 必要な機材は?      → A: PC/スマホ...   │
├──────────────────────────────────────────┤
│                                            │
│   今すぐ始めよう。初回レッスン無料。       │  ← Final CTA
│        [ 無料体験を申し込む ]              │
│                                            │
├──────────────────────────────────────────┤
│  © 2026 English Corp | 利用規約 | Privacy  │  ← Footer
└──────────────────────────────────────────┘

次に、プロジェクトの初期構成を Claude Code に作ってもらいましょう。

> Tailwind CSSを使うランディングページのプロジェクト構成を設計して。
  Vite + Tailwind CSS v4 の構成で。
  必要なファイル一覧とフォルダ構成を出力して。

Claude Code が生成するプロジェクト構成は以下の通りです。

landing-page/
├── index.html          # メインHTML
├── src/
   ├── main.js         # エントリーポイント
   └── style.css       # Tailwind読み込み + カスタムCSS
├── public/
   └── images/         # 画像アセット
├── package.json
├── vite.config.js
└── tailwind.config.js

カラースキームとデザイントークンの決定

LPのデザインを始める前に、カラースキームとデザイントークン(色・フォント・間隔の基準値)を決めておくと、一貫性のあるデザインになります。

> ランディングページ用のカラースキームを提案して。
  条件:
  - 信頼感のあるブルー系
  - CTAボタンはオレンジ系で目立たせる
  - Tailwind CSSのtailwind.config.jsに追加する形式で

Claude Code が提案する設定例です。

// tailwind.config.js
export default {
  theme: {
    extend: {
      colors: {
        primary: {
          50: '#eff6ff',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
          900: '#1e3a5f',
        },
        accent: {
          400: '#fb923c',
          500: '#f97316',
          600: '#ea580c',
        },
      },
      fontFamily: {
        sans: ['"Noto Sans JP"', 'sans-serif'],
      },
    },
  },
};

このように、設計段階で全体の方向性を固めておくことで、以降の開発がスムーズに進みます。

演習問題

  1. オリジナルLPの企画: 自分が作りたいサービスや商品を一つ選び、Claude Code にワイヤーフレームを作ってもらいましょう。「ヨガスタジオの集客LP」「SaaSプロダクトの紹介LP」など、具体的な条件を指定してみてください。

  2. コンバージョン要素の分析: 実際に成功しているLPを3つ見つけて、各セクションの構成要素をリストアップしてください。共通するパターンを Claude Code に分析してもらいましょう。

  3. カラースキームの比較: Claude Code に3種類の異なるカラースキーム(信頼系ブルー、活力系オレンジ、高級感パープル)を提案してもらい、それぞれの印象と用途の違いを比較してください。

  4. モバイルワイヤーフレーム: デスクトップ版に加えて、スマートフォン版(幅375px想定)のワイヤーフレームも Claude Code に作ってもらい、レイアウトの違いを確認してください。

参考資料

Lecture 2Tailwind CSS導入 — 開発環境を整える

12:00

Tailwind CSS導入 — 開発環境を整える

ランディングページの設計が完了したら、いよいよ開発環境を構築します。この講義では、Vite と Tailwind CSS を使ったモダンな開発環境をゼロからセットアップします。Claude Code を活用して、面倒な設定作業を効率的に進めましょう。従来のCSS開発とは全く異なる「ユーティリティファースト」というアプローチを体験してください。

Tailwind CSS とは何か

Tailwind CSS は「ユーティリティファースト」のCSSフレームワークです。従来のCSSフレームワーク(Bootstrap など)がボタンやカードといったコンポーネント単位のスタイルを提供するのに対し、Tailwind は text-centerbg-blue-500p-4 のような小さなユーティリティクラスを組み合わせてデザインを構築します。

ユーティリティファーストのメリットは以下の通りです。

クラス名を考えなくてよい: 従来のCSSでは .hero-section-title のようなクラス名を自分で命名する必要がありましたが、Tailwind では既に定義されたユーティリティクラスを使うだけです。名前の衝突や命名規則で悩む時間がなくなります。

CSSファイルが肥大化しない: 使ったクラスだけが最終的なCSSに含まれるため、プロダクションビルドのファイルサイズが非常に小さくなります。未使用のCSSが自動的に除去されます。

デザインの一貫性が保たれる: 色、サイズ、間隔などが事前に定義されたスケールに基づいているため、デザイナーが不在でも統一感のあるUIを作れます。例えば p-41remp-82rem というように、規則的なスケールで管理されます。

レスポンシブデザインが直感的: md:text-xl lg:text-2xl のように、ブレークポイントをクラス名に含めてレスポンシブ対応ができます。メディアクエリを自分で書く必要がありません。

Vite + Tailwind CSS プロジェクトの作成

Claude Code を使って、プロジェクトを一気にセットアップしましょう。

> Vite + Tailwind CSS v4 のプロジェクトを作成して。
  プロジェクト名は landing-page。
  セットアップ手順をステップバイステップで教えて、
  各コマンドの意味も説明して。

Claude Code が案内する手順に沿って進めます。まず、Vite プロジェクトを作成します。

npm create vite@latest landing-page -- --template vanilla
cd landing-page
npm install

次に、Tailwind CSS と関連パッケージをインストールします。

npm install -D tailwindcss @tailwindcss/vite

vite.config.js を作成して Tailwind プラグインを設定します。

// vite.config.js
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    tailwindcss(),
  ],
});

src/style.css にTailwindのインポートを追加します。

/* src/style.css */
@import "tailwindcss";

index.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="stylesheet" href="/src/style.css" />
</head>
<body class="bg-white text-gray-900">
  <h1 class="text-4xl font-bold text-center mt-20">
    Tailwind CSS で LP を作ろう
  </h1>
  <p class="text-lg text-gray-600 text-center mt-4">
    環境構築が完了しました!
  </p>
</body>
</html>

開発サーバーを起動して動作を確認しましょう。

npm run dev

ブラウザで http://localhost:5173 にアクセスすると、Tailwindのスタイルが適用されたページが表示されます。

tailwind.config.js のカスタマイズ

前回の講義で決めたカラースキームやフォント設定を tailwind.config.js に反映させましょう。Tailwind v4 では CSS ベースの設定も可能ですが、ここでは src/style.css 内で @theme ディレクティブを使ってカスタマイズします。

> Tailwind CSS v4 でカスタムカラーとフォントを設定して
  - プライマリカラー: ブルー系 (#2563eb)
  - アクセントカラー: オレンジ系 (#f97316)
  - フォント: Noto Sans JP
  style.css の @theme ディレクティブを使って

Claude Code が生成する設定です。

/* src/style.css */
@import "tailwindcss";

@theme {
  --color-primary-50: #eff6ff;
  --color-primary-100: #dbeafe;
  --color-primary-500: #3b82f6;
  --color-primary-600: #2563eb;
  --color-primary-700: #1d4ed8;
  --color-primary-900: #1e3a5f;

  --color-accent-400: #fb923c;
  --color-accent-500: #f97316;
  --color-accent-600: #ea580c;

  --font-sans: "Noto Sans JP", sans-serif;
}

Google Fonts の読み込みも index.html<head> に追加します。

<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=Noto+Sans+JP:wght@400;500;700;900&display=swap" rel="stylesheet" />

VS Code 拡張機能の導入

開発効率をさらに上げるために、VS Code に以下の拡張機能を入れましょう。

Tailwind CSS IntelliSense: クラス名の自動補完、プレビュー表示、構文エラーの検知を行います。Tailwind 開発には必須の拡張機能です。bg- と入力するだけで、利用可能な背景色の一覧がサジェストされます。

PostCSS Language Support: @tailwind@apply などの Tailwind 専用構文を正しくハイライトします。CSSファイルで警告が出る場合はこの拡張機能で解消できます。

Prettier + prettier-plugin-tailwindcss: クラスの並び順を自動で整理してくれるプラグインです。チームで開発する際にクラスの順序を統一できます。

> VS Code で Tailwind CSS の開発に最適な設定を .vscode/settings.json に書いて。
  IntelliSense の設定と、Prettier のフォーマット設定を含めて。

Claude Code が生成する設定ファイルです。

{
  "css.validate": false,
  "editor.quickSuggestions": {
    "strings": "on"
  },
  "tailwindCSS.includeLanguages": {
    "html": "html",
    "javascript": "javascript"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true
}

ユーティリティクラスの基本

環境が整ったところで、Tailwind のユーティリティクラスの基本パターンを確認しましょう。

<!-- 余白: p(padding) m(margin) + 方向 + サイズ -->
<div class="p-4 mt-8 mx-auto">パディング1rem、上マージン2rem、左右中央</div>

<!-- テキスト: text-{サイズ} font-{太さ} text-{色} -->
<h1 class="text-4xl font-bold text-gray-900">大見出し</h1>

<!-- Flexbox: flex + 方向 + 配置 -->
<div class="flex items-center justify-between gap-4">横並び</div>

<!-- レスポンシブ: sm: md: lg: xl: -->
<div class="text-base md:text-lg lg:text-xl">画面幅で文字サイズ変更</div>

<!-- 状態: hover: focus: active: -->
<button class="bg-blue-500 hover:bg-blue-600 focus:ring-2">ボタン</button>

この基本を押さえておけば、次の講義からスムーズにLPの各セクションを構築できます。

演習問題

  1. 環境構築の実践: この講義の手順に従って、Vite + Tailwind CSS のプロジェクトを実際に作成し、開発サーバーが起動することを確認してください。

  2. ユーティリティクラスの練習: Claude Code に「Tailwind CSS で名刺風のカードコンポーネントを作って」と依頼して、生成されたコードを index.html に貼り付けて表示を確認してください。

  3. カスタムカラーのテスト: @theme で定義したカスタムカラーを使って、bg-primary-500text-accent-500 が正しく反映されることを確認してください。

  4. レスポンシブの確認: ブラウザの開発者ツールでスマートフォンサイズに切り替え、md:lg: プレフィックスの効果を確認してください。

参考資料

Lecture 3ヒーローセクション — 第一印象を決めるエリアを作る

12:00

ヒーローセクション — 第一印象を決めるエリアを作る

ヒーローセクションは、ランディングページの「顔」です。訪問者がページにアクセスして最初に目にするこのエリアで、サービスの価値を一瞬で伝えなければなりません。統計によると、訪問者の約55%は15秒以内にページを離脱します。つまり、ヒーローセクションで興味を引けなければ、どれだけ優れたコンテンツをページ下部に用意しても読まれないのです。この講義では、Claude Code を使って印象的なヒーローセクションを Tailwind CSS で構築します。

ヒーローセクションの構成要素

効果的なヒーローセクションには、以下の要素が含まれます。

キャッチコピー(見出し): ページで最も大きく目立つテキストです。訪問者の課題を端的に表現するか、得られる成果を一言で伝えます。「英語が話せる自分に出会おう」のように、感情に訴える表現が効果的です。文字数は15〜25文字程度が読みやすいとされています。

サブテキスト(補足説明): キャッチコピーの下に配置する、やや小さめのテキストです。サービスの具体的な内容や特徴を1〜2文で説明します。キャッチコピーだけでは伝えきれない情報をここで補完します。

CTAボタン: Call to Action ボタンです。「無料で始める」「今すぐ申し込む」のように、具体的なアクションを促すラベルにします。ヒーローセクション内で最も目立つ要素である必要があります。

背景ビジュアル: グラデーション、画像、またはパターンを使って視覚的なインパクトを与えます。テキストの可読性を損なわないよう、オーバーレイを活用するのがコツです。

Claude Code でヒーローセクションを生成する

早速 Claude Code にヒーローセクションを作ってもらいましょう。

> Tailwind CSSを使ったヒーローセクションを作って。
  グラデーション背景、大きな見出し、サブテキスト、
  CTAボタンを含めて。レスポンシブ対応で。
  見出し: "ビジネスを加速する、最高のツール"
  サブテキスト: "AIを活用した業務効率化で、あなたのチームの生産性を3倍に"
  CTAボタン: "無料トライアルを始める"

Claude Code が生成するコードは以下のようになります。

<!-- Hero Section -->
<section class="relative min-h-screen flex items-center justify-center
               bg-gradient-to-br from-primary-900 via-primary-700 to-primary-500
               overflow-hidden">
  <!-- 装飾用の背景パターン -->
  <div class="absolute inset-0 opacity-10">
    <div class="absolute top-20 left-10 w-72 h-72 bg-white rounded-full blur-3xl"></div>
    <div class="absolute bottom-20 right-10 w-96 h-96 bg-accent-400 rounded-full blur-3xl"></div>
  </div>

  <!-- コンテンツ -->
  <div class="relative z-10 max-w-4xl mx-auto px-6 text-center">
    <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl
               font-black text-white leading-tight tracking-tight">
      ビジネスを加速する、<br class="hidden sm:block" />
      最高のツール
    </h1>

    <p class="mt-6 text-lg sm:text-xl md:text-2xl
              text-primary-100 max-w-2xl mx-auto leading-relaxed">
      AIを活用した業務効率化で、<br class="sm:hidden" />
      あなたのチームの生産性を3倍に
    </p>

    <div class="mt-10 flex flex-col sm:flex-row gap-4 justify-center">
      <a href="#cta"
         class="inline-block px-8 py-4 text-lg font-bold
                bg-accent-500 text-white rounded-full
                hover:bg-accent-600 transform hover:scale-105
                transition-all duration-300 shadow-lg hover:shadow-xl">
        無料トライアルを始める
      </a>
      <a href="#features"
         class="inline-block px-8 py-4 text-lg font-bold
                border-2 border-white text-white rounded-full
                hover:bg-white hover:text-primary-900
                transition-all duration-300">
        詳しく見る
      </a>
    </div>

    <!-- 信頼バッジ -->
    <div class="mt-16 flex items-center justify-center gap-8 text-primary-200">
      <span class="text-sm">導入企業 500社以上</span>
      <span class="text-sm">|</span>
      <span class="text-sm">満足度 98%</span>
      <span class="text-sm">|</span>
      <span class="text-sm">初期費用 0円</span>
    </div>
  </div>
</section>

このコードのポイントを一つずつ解説しましょう。

各クラスの詳細解説

レイアウトの仕組み: min-h-screen でビューポート全体の高さを確保し、flex items-center justify-center でコンテンツを上下左右中央に配置しています。これにより、どの画面サイズでも見出しが画面中央に表示されます。

グラデーション背景: bg-gradient-to-br は右下に向かうグラデーションです。from-primary-900 via-primary-700 to-primary-500 で3色のグラデーションを定義しています。Tailwind のグラデーションクラスは to-t(上向き)、to-r(右向き)、to-br(右下向き)など、8方向を指定できます。

レスポンシブタイポグラフィ: text-4xl sm:text-5xl md:text-6xl lg:text-7xl は画面幅に応じて文字サイズを段階的に大きくしています。モバイルでは text-4xl(2.25rem)、大画面では text-7xl(4.5rem)になります。

ボタンのインタラクション: hover:scale-105 transition-all duration-300 でホバー時に1.05倍に拡大するアニメーションを付けています。shadow-lg hover:shadow-xl で影の強さも変化させ、ボタンが浮き上がるような効果を演出します。

背景装飾: absolute で配置した円形要素に blur-3xl を適用し、ぼかしたグロー効果を作っています。opacity-10 で薄く表示することで、背景に奥行き感を与えつつテキストの可読性を保っています。

キャッチコピーの改善を Claude Code に依頼する

ヒーローの見た目ができたら、キャッチコピーの改善も Claude Code に相談できます。

> 以下のキャッチコピーをより効果的にするため、
  5つのバリエーションを提案して。
  ターゲット: 中小企業の経営者
  現在のコピー: "ビジネスを加速する、最高のツール"
  条件: 15文字以内、ベネフィットを含む

コピーライティングの知識がなくても、Claude Code が複数の選択肢を提示してくれるため、最適なキャッチコピーを選べます。

レスポンシブ対応のポイント

ヒーローセクションをモバイルでも美しく表示するために、以下の点に注意しましょう。

改行位置の制御: <br class="hidden sm:block" /> を使うと、デスクトップでは改行してモバイルでは改行しない、という制御ができます。長い見出しをデバイスごとに最適な位置で折り返せます。

ボタンの配置: flex-col sm:flex-row で、モバイルではボタンを縦並び、タブレット以上では横並びにしています。モバイルでは指でタップしやすいよう、ボタンを大きめに表示するのが重要です。

余白の調整: px-6 でコンテンツの左右に余白を確保し、モバイルでテキストが画面端にくっつかないようにしています。

演習問題

  1. ヒーローセクションの実装: 上記のコードを自分のプロジェクトの index.html に追加し、ブラウザで表示を確認してください。開発者ツールでモバイル表示に切り替えて、レスポンシブの動作も確認しましょう。

  2. グラデーションの変更: Claude Code に「夕焼け色のグラデーション背景に変更して」と依頼し、from- via- to- クラスを変更した結果を比較してください。

  3. 背景画像の追加: グラデーションの代わりに背景画像を使ったヒーローセクションを Claude Code に作ってもらいましょう。「背景画像にオーバーレイをかけたヒーローセクションをTailwindで」と依頼してみてください。

  4. アニメーション追加: ページ読み込み時にテキストがフェードインするアニメーションを Claude Code に追加してもらいましょう。「Tailwind の @keyframes を使ってヒーローのテキストにフェードインアニメーションを付けて」と依頼してみてください。

参考資料

Lecture 4特徴セクション — サービスの魅力を伝える

12:00

特徴セクション — サービスの魅力を伝える

ヒーローセクションで訪問者の関心を引いたら、次に必要なのは「なぜこのサービスを選ぶべきか」を具体的に伝えることです。特徴(Features)セクションは、サービスの強みをカード形式で分かりやすく並べるエリアです。3〜4つのポイントに絞って簡潔に伝えるのが効果的で、LP全体のコンバージョン率を左右する重要なセクションです。この講義では、Claude Code を使ってレスポンシブな3カラムグリッドの特徴セクションを構築します。

特徴セクションの設計原則

特徴セクションで成果を出すためには、以下の設計原則を守りましょう。

ベネフィット視点で書く: 「高性能なAIエンジン搭載」はスペック(機能)であり、「作業時間を70%削減」がベネフィット(利益)です。訪問者が知りたいのは「自分にとって何が嬉しいか」です。機能を羅列するのではなく、その機能によってユーザーがどう変わるかを伝えましょう。

3つのポイントに絞る: 人間が一度に記憶できる情報量には限界があります。マジカルナンバー3と呼ばれるように、3つのポイントが最も記憶に残りやすく、説得力も高いとされています。多くても4つまでに絞りましょう。

視覚的な差別化: アイコンやイラストを使って各特徴を視覚的に区別します。テキストだけのセクションよりも、アイコン付きのカードの方が情報の把握が格段に速くなります。

セクション見出しを入れる: 「選ばれる3つの理由」「なぜ〇〇が選ばれるのか」のように、セクション全体のコンテキストを示す見出しを配置します。

Claude Code で特徴セクションを生成する

Claude Code に3カラムの特徴セクションを作ってもらいましょう。

> Tailwind CSSで特徴セクションを作って。
  3カラムのカードレイアウトで、各カードにはアイコン(SVG)、
  タイトル、説明文を含めて。
  レスポンシブ対応(モバイルは1カラム、タブレットは2カラム、
  デスクトップは3カラム)で。
  特徴:
  1. "AIが自動で分析" — 膨大なデータを瞬時に分析
  2. "かんたん導入" — 最短5分でスタートできる
  3. "手厚いサポート" — 専任担当が伴走

Claude Code が生成するコードです。

<!-- Features Section -->
<section id="features" class="py-20 md:py-28 bg-gray-50">
  <div class="max-w-6xl mx-auto px-6">
    <!-- セクション見出し -->
    <div class="text-center mb-16">
      <span class="inline-block px-4 py-1 text-sm font-semibold
                   text-primary-600 bg-primary-100 rounded-full mb-4">
        特徴
      </span>
      <h2 class="text-3xl md:text-4xl font-bold text-gray-900">
        選ばれる3つの理由
      </h2>
      <p class="mt-4 text-lg text-gray-600 max-w-2xl mx-auto">
        多くの企業が当サービスを選ぶ理由をご紹介します
      </p>
    </div>

    <!-- 3カラムグリッド -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
      <!-- カード1 -->
      <div class="bg-white rounded-2xl p-8 shadow-sm
                  hover:shadow-lg transition-shadow duration-300
                  border border-gray-100">
        <div class="w-14 h-14 bg-primary-100 rounded-xl
                    flex items-center justify-center mb-6">
          <svg class="w-7 h-7 text-primary-600" fill="none"
               stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round"
                  stroke-width="2"
                  d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
          </svg>
        </div>
        <h3 class="text-xl font-bold text-gray-900 mb-3">
          AIが自動で分析
        </h3>
        <p class="text-gray-600 leading-relaxed">
          膨大なデータを瞬時に分析し、ビジネスに直結するインサイトを
          自動で抽出。手作業の分析レポート作成が不要になります。
        </p>
      </div>

      <!-- カード2 -->
      <div class="bg-white rounded-2xl p-8 shadow-sm
                  hover:shadow-lg transition-shadow duration-300
                  border border-gray-100">
        <div class="w-14 h-14 bg-green-100 rounded-xl
                    flex items-center justify-center mb-6">
          <svg class="w-7 h-7 text-green-600" fill="none"
               stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round"
                  stroke-width="2"
                  d="M13 10V3L4 14h7v7l9-11h-7z" />
          </svg>
        </div>
        <h3 class="text-xl font-bold text-gray-900 mb-3">
          かんたん導入
        </h3>
        <p class="text-gray-600 leading-relaxed">
          アカウント作成から利用開始まで最短5分。難しい設定や
          専門知識は一切不要です。既存のツールとの連携もスムーズ。
        </p>
      </div>

      <!-- カード3 -->
      <div class="bg-white rounded-2xl p-8 shadow-sm
                  hover:shadow-lg transition-shadow duration-300
                  border border-gray-100">
        <div class="w-14 h-14 bg-accent-400/20 rounded-xl
                    flex items-center justify-center mb-6">
          <svg class="w-7 h-7 text-accent-600" fill="none"
               stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round"
                  stroke-width="2"
                  d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z" />
          </svg>
        </div>
        <h3 class="text-xl font-bold text-gray-900 mb-3">
          手厚いサポート
        </h3>
        <p class="text-gray-600 leading-relaxed">
          専任の担当者がお客様のビジネス成長を伴走支援。
          導入から運用まで、いつでもご相談いただけます。
        </p>
      </div>
    </div>
  </div>
</section>

グリッドレイアウトの仕組み

このセクションの核となるのは Tailwind のグリッドシステムです。各クラスの役割を詳しく見ていきましょう。

grid: CSS Grid を有効にします。Flexbox との違いは、Gridが行と列の両方を同時に制御できる点です。カードの等間隔配置に最適です。

grid-cols-1 md:grid-cols-2 lg:grid-cols-3: モバイルでは1列、タブレット(768px以上)では2列、デスクトップ(1024px以上)では3列に変化します。レスポンシブなグリッドをたった3つのクラスで実現しています。

gap-8: グリッド要素間の余白を 2rem(32px)に設定します。gap は行間・列間の両方に適用されます。行と列で異なる余白にしたい場合は gap-x-8 gap-y-12 のように分けて指定できます。

max-w-6xl mx-auto px-6: コンテンツの最大幅を 72rem(1152px)に制限し、mx-auto で左右中央に配置しています。px-6 で左右のパディングを確保し、モバイルで端まで広がらないようにしています。

カードデザインのバリエーション

基本の特徴カードを作ったら、Claude Code にバリエーションを提案してもらいましょう。

> 先ほどの特徴カードをリデザインして。
  以下の3パターンを提案して:
  1. 左にアイコン、右にテキストの横並びレイアウト
  2. 上部にカラーバーがあるカード
  3. ホバーで色が変わるインタラクティブなカード
  すべてTailwind CSSで

たとえばホバーで色が変わるパターンは以下のようになります。

<div class="bg-white rounded-2xl p-8 border border-gray-100
            hover:bg-primary-600 hover:border-primary-600
            group transition-all duration-300 cursor-pointer">
  <div class="w-14 h-14 bg-primary-100 group-hover:bg-white/20
              rounded-xl flex items-center justify-center mb-6
              transition-colors duration-300">
    <svg class="w-7 h-7 text-primary-600 group-hover:text-white
                transition-colors duration-300" ...>
    </svg>
  </div>
  <h3 class="text-xl font-bold text-gray-900
             group-hover:text-white transition-colors duration-300">
    AIが自動で分析
  </h3>
  <p class="text-gray-600 group-hover:text-primary-100
            transition-colors duration-300 leading-relaxed">
    膨大なデータを瞬時に分析...
  </p>
</div>

ここで使われている groupgroup-hover: は Tailwind の強力な機能です。親要素に group クラスを付けると、子要素で group-hover: を使って親のホバー状態に連動したスタイル変更ができます。

演習問題

  1. 特徴セクションの実装: 上記のコードをヒーローセクションの下に追加し、ブラウザでレスポンシブの動作を確認してください。画面幅を変えると1列→2列→3列にレイアウトが変化することを確認しましょう。

  2. 4カラムへの変更: Claude Code に「4つの特徴を4カラムで表示するように変更して」と依頼し、グリッドの設定がどう変わるかを学びましょう。

  3. アイコンの変更: Claude Code に「ロケット、星、盾の形をしたSVGアイコンに変更して」と依頼し、各カードのアイコンをカスタマイズしてください。

  4. カードのバリエーション: 上記の3パターン(横並び、カラーバー、ホバー色変更)をすべて試して、最も効果的だと思うデザインを選んでください。

参考資料

Lecture 5CTAボタン — ユーザーのアクションを促す

12:00

CTAボタン — ユーザーのアクションを促す

CTA(Call to Action)は、ランディングページの最終目的である「ユーザーに行動を起こさせる」ための要素です。どれだけ美しいデザインのLPを作っても、CTAボタンの設計が悪ければコンバージョンは生まれません。ボタンの色、サイズ、ラベル、配置場所、そしてインタラクション(ホバーやフォーカス時の動き)が、クリック率を大きく左右します。この講義では、Claude Code を使ってコンバージョン率を高めるCTAボタンを Tailwind CSS で作成し、LP内の適切な位置に配置する方法を学びます。

CTAボタンの設計原則

効果的なCTAボタンを作るために、以下の原則を押さえておきましょう。

コントラストの法則: CTAボタンは周囲の色とは対照的な色にします。青系のLPならオレンジや黄色のボタンが目を引きます。背景と同系色のボタンは埋もれてしまい、クリック率が低下します。色相環で対角に位置する補色を使うのが基本テクニックです。

具体的なラベル: 「送信」「クリック」のような曖昧なラベルではなく、「無料トライアルを始める」「今すぐダウンロード」のように、ボタンを押した後に何が起こるかを具体的に伝えます。動詞で始めることで、アクションへの心理的なハードルが下がります。

適切なサイズ: 小さすぎるボタンはクリックしにくく、大きすぎると安っぽく見えます。デスクトップでは横幅200〜300px、高さ48〜56pxが推奨サイズです。モバイルでは指でタップしやすいよう、高さ48px以上を確保しましょう(Googleのガイドラインでは44px以上を推奨)。

余白(ホワイトスペース): CTAボタンの周囲には十分な余白を取り、他の要素から視覚的に独立させます。余白があることでボタンが際立ち、視線が自然にボタンに向かいます。

Claude Code でCTAボタンを作成する

さまざまなスタイルのCTAボタンを Claude Code に作ってもらいましょう。

> Tailwind CSSでランディングページ用のCTAボタンを
  5種類作って。それぞれホバー、フォーカス、アクティブ状態の
  スタイルも含めて。アクセシビリティにも配慮して。

Claude Code が生成するボタンのバリエーションです。

<!-- 1. ソリッド(塗りつぶし)ボタン -->
<a href="#signup"
   class="inline-flex items-center justify-center
          px-8 py-4 text-lg font-bold text-white
          bg-accent-500 rounded-full
          hover:bg-accent-600
          focus:outline-none focus:ring-4 focus:ring-accent-500/50
          active:scale-95
          transition-all duration-200
          shadow-lg shadow-accent-500/30 hover:shadow-xl hover:shadow-accent-500/40">
  無料トライアルを始める
  <svg class="ml-2 w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
          d="M13 7l5 5m0 0l-5 5m5-5H6" />
  </svg>
</a>

<!-- 2. アウトライン(枠線)ボタン -->
<a href="#learn-more"
   class="inline-flex items-center justify-center
          px-8 py-4 text-lg font-bold
          text-primary-600 border-2 border-primary-600 rounded-full
          hover:bg-primary-600 hover:text-white
          focus:outline-none focus:ring-4 focus:ring-primary-500/50
          active:scale-95
          transition-all duration-200">
  詳しく見る
</a>

<!-- 3. グラデーションボタン -->
<a href="#signup"
   class="inline-flex items-center justify-center
          px-8 py-4 text-lg font-bold text-white rounded-full
          bg-gradient-to-r from-accent-500 to-pink-500
          hover:from-accent-600 hover:to-pink-600
          focus:outline-none focus:ring-4 focus:ring-accent-500/50
          active:scale-95
          transition-all duration-200
          shadow-lg hover:shadow-xl">
  今すぐ申し込む
</a>

<!-- 4. パルスアニメーション付きボタン -->
<a href="#signup"
   class="relative inline-flex items-center justify-center
          px-8 py-4 text-lg font-bold text-white
          bg-accent-500 rounded-full
          hover:bg-accent-600
          focus:outline-none focus:ring-4 focus:ring-accent-500/50
          transition-all duration-200">
  <span class="absolute inset-0 rounded-full bg-accent-500 animate-ping opacity-20"></span>
  <span class="relative">無料で始める</span>
</a>

<!-- 5. アイコン+テキスト大型ボタン -->
<a href="#signup"
   class="inline-flex items-center gap-4
          px-10 py-5 text-xl font-bold text-white
          bg-primary-600 rounded-2xl
          hover:bg-primary-700
          focus:outline-none focus:ring-4 focus:ring-primary-500/50
          active:scale-95
          transition-all duration-200
          shadow-lg hover:shadow-xl">
  <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
          d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
          d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
  </svg>
  デモ動画を見る
</a>

ボタンの状態設計を深掘りする

CTAボタンには4つの状態があり、それぞれに適切なスタイルを設定することが重要です。

通常状態(default): ボタンの基本スタイルです。背景色、テキスト色、サイズ、影を定義します。

ホバー状態(hover): マウスカーソルを乗せた時の変化です。色を少し濃くする、影を強くする、わずかに拡大するなどの変化を加えます。hover:bg-accent-600 hover:shadow-xl のように指定します。

フォーカス状態(focus): キーボード操作でボタンにフォーカスした時の状態です。アクセシビリティの観点で必須です。focus:ring-4 focus:ring-accent-500/50 でボタンの周囲にリングを表示します。focus:outline-none でブラウザデフォルトのアウトラインを消し、独自のフォーカスリングに置き換えています。

アクティブ状態(active): ボタンをクリック中の状態です。active:scale-95 で少し縮小させると「押した感」が出て、フィードバックとして機能します。

<!-- 4つの状態をすべて含むボタン -->
<button class="px-8 py-4 text-lg font-bold text-white
               bg-accent-500 rounded-full
               hover:bg-accent-600
               focus:outline-none focus:ring-4 focus:ring-accent-500/50
               active:scale-95
               disabled:opacity-50 disabled:cursor-not-allowed
               transition-all duration-200">
  今すぐ申し込む
</button>

disabled:opacity-50 disabled:cursor-not-allowed を追加すると、ボタンが無効化された時のスタイルも定義できます。

LP内のCTA配置戦略

CTAボタンはLP内に1箇所だけでは不十分です。効果的な配置戦略を Claude Code に相談しましょう。

> ランディングページにCTAセクションを追加して。
  ヒーローとフッターの間に配置する、
  背景色付きの独立したCTAエリア。
  見出し、補足テキスト、大きなCTAボタンを含めて。
  Tailwind CSSで。

Claude Code が生成するCTAセクションです。

<!-- CTA Section -->
<section class="py-20 bg-primary-900">
  <div class="max-w-3xl mx-auto px-6 text-center">
    <h2 class="text-3xl md:text-4xl font-bold text-white">
      今すぐ始めて、<br />ビジネスを次のステージへ
    </h2>
    <p class="mt-4 text-lg text-primary-200">
      14日間の無料トライアル。クレジットカード不要。
    </p>
    <div class="mt-10">
      <a href="#signup"
         class="inline-flex items-center px-10 py-5
                text-xl font-bold text-primary-900
                bg-white rounded-full
                hover:bg-gray-100
                focus:outline-none focus:ring-4 focus:ring-white/50
                active:scale-95
                transition-all duration-200
                shadow-xl hover:shadow-2xl">
        無料トライアルを始める
        <svg class="ml-3 w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round"
                stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6" />
        </svg>
      </a>
    </div>
    <p class="mt-6 text-sm text-primary-300">
      5分で設定完了 ・ いつでも解約可能 ・ 500社以上が導入
    </p>
  </div>
</section>

推奨される配置箇所は以下の3箇所です。ヒーローセクション内(ファーストビュー)、特徴セクションの直後(興味を持った時点)、ページ最下部のFAQ直後(不安が解消された時点)です。

演習問題

  1. 5種類のボタン実装: 上記の5種類のCTAボタンをすべて実装し、ホバー・フォーカス・アクティブ状態の動作をブラウザで確認してください。キーボードのTabキーでフォーカスリングが表示されることも確認しましょう。

  2. A/Bテストの準備: Claude Code に「同じCTAボタンで、ラベルが異なる2パターンを作って。パターンA: '無料で始める'、パターンB: '今すぐ申し込む'」と依頼し、どちらがクリックしたくなるかを考察してください。

  3. CTAセクションの配置: LP内の3箇所(ヒーロー、特徴の後、ページ最下部)にCTAを配置し、それぞれでデザインを少しずつ変えてみてください。

  4. マイクロコピーの追加: CTAボタンの下に「クレジットカード不要」「30秒で登録完了」などのマイクロコピー(小さな補足テキスト)を追加し、心理的ハードルを下げる工夫をしてみてください。

参考資料

Lecture 6お客様の声 — テスティモニアルセクションを作る

12:00

お客様の声 — テスティモニアルセクションを作る

テスティモニアル(お客様の声)は、ランディングページにおける最も強力な説得要素の一つです。心理学では「社会的証明(ソーシャルプルーフ)」と呼ばれる現象で、他の人がすでに使って満足しているという事実が、新しい訪問者の意思決定を大きく後押しします。第三者の声は、サービス提供者自身が語る言葉よりも何倍も信頼されるのです。この講義では、Claude Code を使って信頼感のあるテスティモニアルセクションを Tailwind CSS で構築します。

効果的なテスティモニアルの要素

テスティモニアルに信頼性を持たせるために、以下の要素を含めましょう。

顔写真(アバター): 人の顔が見えると信頼性が格段に上がります。写真がある口コミは、テキストだけの口コミと比較してコンバージョン率が約35%向上するというデータがあります。実際のお客様の写真が最も効果的ですが、プライバシーの観点からイニシャル入りのアバターを使うケースも多いです。

名前と属性: 「田中太郎さん・30代・マーケティング担当」のように、名前と属性を記載します。匿名よりも実名、実名よりも肩書きや会社名付きの方が説得力があります。

具体的な成果: 「とても良かったです」のような曖昧な感想ではなく、「導入3ヶ月で売上が150%に増加しました」のような具体的な数字を含む声が効果的です。

評価スター: 5つ星の評価は視覚的に分かりやすく、ページを流し読みしている訪問者にも瞬時にポジティブな印象を与えます。

Claude Code でテスティモニアルカードを作成する

Claude Code にテスティモニアルセクションを作ってもらいましょう。

> Tailwind CSSでテスティモニアルセクションを作って。
  3枚のカードを横並びに配置。各カードには:
  - 5つ星の評価(SVG)
  - お客様の声(引用テキスト)
  - 顔写真(丸いアバター)
  - 名前と肩書き
  レスポンシブ対応で。背景はグレー系で。

Claude Code が生成するテスティモニアルセクションです。

<!-- Testimonials Section -->
<section class="py-20 md:py-28 bg-white">
  <div class="max-w-6xl mx-auto px-6">
    <!-- セクション見出し -->
    <div class="text-center mb-16">
      <span class="inline-block px-4 py-1 text-sm font-semibold
                   text-primary-600 bg-primary-100 rounded-full mb-4">
        お客様の声
      </span>
      <h2 class="text-3xl md:text-4xl font-bold text-gray-900">
        ご利用いただいたお客様の声
      </h2>
      <p class="mt-4 text-lg text-gray-600 max-w-2xl mx-auto">
        実際にサービスをご利用いただいた方々からの評価です
      </p>
    </div>

    <!-- テスティモニアルカード -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
      <!-- カード1 -->
      <div class="bg-gray-50 rounded-2xl p-8 border border-gray-100
                  hover:shadow-lg transition-shadow duration-300">
        <!-- 星評価 -->
        <div class="flex gap-1 mb-4">
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
        </div>

        <!-- 引用テキスト -->
        <blockquote class="text-gray-700 leading-relaxed mb-6">
          "導入してわずか2週間で、チーム全体の作業効率が劇的に改善しました。
          特にレポート作成の自動化が素晴らしく、毎月20時間の削減に成功しています。"
        </blockquote>

        <!-- プロフィール -->
        <div class="flex items-center gap-4">
          <div class="w-12 h-12 bg-primary-500 rounded-full
                      flex items-center justify-center
                      text-white font-bold text-lg">
            T
          </div>
          <div>
            <p class="font-bold text-gray-900">田中 美咲</p>
            <p class="text-sm text-gray-500">株式会社ABC / マーケティング部長</p>
          </div>
        </div>
      </div>

      <!-- カード2 -->
      <div class="bg-gray-50 rounded-2xl p-8 border border-gray-100
                  hover:shadow-lg transition-shadow duration-300">
        <div class="flex gap-1 mb-4">
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
        </div>
        <blockquote class="text-gray-700 leading-relaxed mb-6">
          "以前は分析に丸一日かかっていた作業が、ボタン一つで完了するようになりました。
          サポート体制も手厚く、困った時にすぐ相談できるのが心強いです。"
        </blockquote>
        <div class="flex items-center gap-4">
          <div class="w-12 h-12 bg-green-500 rounded-full
                      flex items-center justify-center
                      text-white font-bold text-lg">
            S
          </div>
          <div>
            <p class="font-bold text-gray-900">鈴木 健一</p>
            <p class="text-sm text-gray-500">DEF株式会社 / CTO</p>
          </div>
        </div>
      </div>

      <!-- カード3 -->
      <div class="bg-gray-50 rounded-2xl p-8 border border-gray-100
                  hover:shadow-lg transition-shadow duration-300">
        <div class="flex gap-1 mb-4">
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
          <svg class="w-5 h-5 text-gray-300" fill="currentColor" viewBox="0 0 20 20">
            <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
          </svg>
        </div>
        <blockquote class="text-gray-700 leading-relaxed mb-6">
          "スタートアップとして予算が限られる中、この価格帯でこれだけの機能が
          使えるのは本当にありがたい。チームの規模が倍になっても問題なく使えています。"
        </blockquote>
        <div class="flex items-center gap-4">
          <div class="w-12 h-12 bg-accent-500 rounded-full
                      flex items-center justify-center
                      text-white font-bold text-lg">
            Y
          </div>
          <div>
            <p class="font-bold text-gray-900">山本 裕子</p>
            <p class="text-sm text-gray-500">GHI株式会社 / 代表取締役</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

星評価コンポーネントの効率化

上記のコードでは星のSVGが繰り返されていますが、Claude Code に効率的な方法を相談できます。

> 上記のテスティモニアルカードで、星評価のSVGが冗長です。
  JavaScriptで星評価を動的に生成するコンポーネントを作って。
  引数で星の数(1-5)を指定できるようにして。

Claude Code が提案する星評価の生成関数です。

// 星評価を生成する関数
function createStarRating(count, maxStars = 5) {
  const container = document.createElement('div');
  container.className = 'flex gap-1 mb-4';

  for (let i = 0; i < maxStars; i++) {
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    svg.setAttribute('class', `w-5 h-5 ${i < count ? 'text-yellow-400' : 'text-gray-300'}`);
    svg.setAttribute('fill', 'currentColor');
    svg.setAttribute('viewBox', '0 0 20 20');

    const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    path.setAttribute('d', 'M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z');
    svg.appendChild(path);
    container.appendChild(svg);
  }
  return container;
}

// 使用例
document.querySelectorAll('[data-stars]').forEach(el => {
  const rating = parseInt(el.dataset.stars);
  el.appendChild(createStarRating(rating));
});

HTML側では data-stars 属性で星の数を指定するだけです。

<div data-stars="5"></div>  <!-- ★★★★★ -->
<div data-stars="4"></div>  <!-- ★★★★☆ -->

カルーセル表示のアイデア

テスティモニアルが多数ある場合は、カルーセル(スライダー)で表示することも検討しましょう。

> テスティモニアルカードをカルーセル形式で表示する方法を教えて。
  ライブラリなしで、CSS scroll-snap を使ったシンプルな実装で。
  Tailwind CSSで。
<!-- スクロールスナップを使ったカルーセル -->
<div class="flex gap-6 overflow-x-auto snap-x snap-mandatory
            scroll-smooth pb-4 -mx-6 px-6
            scrollbar-hide">
  <div class="snap-center shrink-0 w-80 md:w-96">
    <!-- カード内容 -->
  </div>
  <div class="snap-center shrink-0 w-80 md:w-96">
    <!-- カード内容 -->
  </div>
  <div class="snap-center shrink-0 w-80 md:w-96">
    <!-- カード内容 -->
  </div>
</div>

snap-x snap-mandatory で水平方向のスクロールスナップを有効にし、snap-center で各カードが中央に吸着するようになります。CSS だけで実現できるため、JavaScript ライブラリが不要です。

演習問題

  1. テスティモニアルセクションの実装: 上記のコードをLPに追加し、ブラウザで表示を確認してください。モバイルでは1カラム、デスクトップでは3カラムに変化することを確認しましょう。

  2. 実在の写真に変更: Claude Code に「アバターのイニシャル表示を、img タグの丸い写真に変更して」と依頼し、プレースホルダー画像(picsum.photos など)を使った表示に切り替えてください。

  3. カルーセルの実装: CSS scroll-snap を使ったカルーセル版のテスティモニアルを実装し、横スクロールで切り替わることを確認してください。

  4. 企業ロゴの追加: テスティモニアルセクションの下に「導入企業ロゴ一覧」を Claude Code に作ってもらいましょう。「企業ロゴをグレースケールで横一列に並べるセクションを Tailwind で」と依頼してみてください。

参考資料

Lecture 7FAQ セクション — よくある質問をアコーディオンで表示

12:00

FAQ セクション — よくある質問をアコーディオンで表示

ランディングページの終盤に配置するFAQ(Frequently Asked Questions)セクションは、訪問者の最後の不安を解消する重要な役割を持ちます。「料金はいくら?」「解約は簡単?」「サポートはある?」といった疑問に先回りで答えることで、CTAボタンへの心理的ハードルを大きく下げることができます。この講義では、Claude Code を使ってアコーディオン形式のFAQセクションを Tailwind CSS と JavaScript で構築し、さらに SEO に有利な構造化データ(Schema Markup)も実装します。

FAQセクションの設計ポイント

効果的なFAQセクションを作るために、以下のポイントを押さえましょう。

よくある質問を厳選する: 5〜8問程度が適切です。多すぎると読む気が失せ、少なすぎると不安が残ります。実際にお客様から頻繁に寄せられる質問を優先的に掲載します。

ネガティブな質問も含める: 「解約はできますか?」「返金はされますか?」といったネガティブな質問を避けるのではなく、正直に回答することで信頼感が高まります。

アコーディオン形式の利点: すべての回答を一度に表示するとページが長くなりすぎます。アコーディオン(開閉式)にすることで、必要な情報だけを表示でき、ユーザーが自分の関心ある質問を見つけやすくなります。

回答は簡潔に: 各回答は2〜3文程度にまとめます。詳細な説明が必要な場合は「詳しくはこちら」のリンクで別ページに誘導しましょう。

HTML の details/summary を使ったアコーディオン

最もシンプルなアコーディオンは、HTML ネイティブの <details><summary> 要素を使う方法です。JavaScript が不要で、アクセシビリティも標準で確保されています。

> Tailwind CSSでFAQセクションを作って。
  HTMLのdetails/summary要素を使ったアコーディオン形式で。
  5つの質問と回答を含めて。
  開閉アイコン(+/-)も付けて。
  テーマはAI業務効率化サービス。

Claude Code が生成するFAQセクションです。

<!-- FAQ Section -->
<section id="faq" class="py-20 md:py-28 bg-gray-50">
  <div class="max-w-3xl mx-auto px-6">
    <!-- セクション見出し -->
    <div class="text-center mb-16">
      <span class="inline-block px-4 py-1 text-sm font-semibold
                   text-primary-600 bg-primary-100 rounded-full mb-4">
        FAQ
      </span>
      <h2 class="text-3xl md:text-4xl font-bold text-gray-900">
        よくあるご質問
      </h2>
      <p class="mt-4 text-lg text-gray-600">
        お寄せいただく質問にお答えします
      </p>
    </div>

    <!-- アコーディオン -->
    <div class="space-y-4">
      <!-- Q1 -->
      <details class="group bg-white rounded-xl border border-gray-200
                      overflow-hidden">
        <summary class="flex items-center justify-between
                        cursor-pointer p-6 text-lg font-semibold
                        text-gray-900 hover:bg-gray-50
                        transition-colors duration-200
                        list-none [&::-webkit-details-marker]:hidden">
          <span>無料トライアル期間はどのくらいですか?</span>
          <span class="ml-4 shrink-0 w-6 h-6 flex items-center
                       justify-center rounded-full bg-gray-100
                       group-open:bg-primary-100
                       transition-colors duration-200">
            <svg class="w-4 h-4 text-gray-500 group-open:text-primary-600
                        group-open:rotate-45
                        transition-all duration-200"
                 fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round"
                    stroke-width="2" d="M12 4v16m8-8H4" />
            </svg>
          </span>
        </summary>
        <div class="px-6 pb-6 text-gray-600 leading-relaxed">
          14日間の無料トライアルをご用意しています。トライアル期間中は
          すべての機能をご利用いただけます。クレジットカードの登録は不要で、
          トライアル終了後に自動で課金されることはありません。
        </div>
      </details>

      <!-- Q2 -->
      <details class="group bg-white rounded-xl border border-gray-200
                      overflow-hidden">
        <summary class="flex items-center justify-between
                        cursor-pointer p-6 text-lg font-semibold
                        text-gray-900 hover:bg-gray-50
                        transition-colors duration-200
                        list-none [&::-webkit-details-marker]:hidden">
          <span>どのような業種で利用されていますか?</span>
          <span class="ml-4 shrink-0 w-6 h-6 flex items-center
                       justify-center rounded-full bg-gray-100
                       group-open:bg-primary-100
                       transition-colors duration-200">
            <svg class="w-4 h-4 text-gray-500 group-open:text-primary-600
                        group-open:rotate-45
                        transition-all duration-200"
                 fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round"
                    stroke-width="2" d="M12 4v16m8-8H4" />
            </svg>
          </span>
        </summary>
        <div class="px-6 pb-6 text-gray-600 leading-relaxed">
          IT、製造、小売、金融、医療など幅広い業種でご利用いただいています。
          特にマーケティング部門やカスタマーサポート部門での導入が多く、
          データ分析やレポート作成の効率化に活用されています。
        </div>
      </details>

      <!-- Q3 -->
      <details class="group bg-white rounded-xl border border-gray-200
                      overflow-hidden">
        <summary class="flex items-center justify-between
                        cursor-pointer p-6 text-lg font-semibold
                        text-gray-900 hover:bg-gray-50
                        transition-colors duration-200
                        list-none [&::-webkit-details-marker]:hidden">
          <span>解約はいつでもできますか?</span>
          <span class="ml-4 shrink-0 w-6 h-6 flex items-center
                       justify-center rounded-full bg-gray-100
                       group-open:bg-primary-100
                       transition-colors duration-200">
            <svg class="w-4 h-4 text-gray-500 group-open:text-primary-600
                        group-open:rotate-45
                        transition-all duration-200"
                 fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round"
                    stroke-width="2" d="M12 4v16m8-8H4" />
            </svg>
          </span>
        </summary>
        <div class="px-6 pb-6 text-gray-600 leading-relaxed">
          はい、いつでも解約可能です。管理画面から数クリックで手続きが完了します。
          解約後は次の請求日まで引き続きご利用いただけます。
          違約金や解約手数料は一切かかりません。
        </div>
      </details>

      <!-- Q4 -->
      <details class="group bg-white rounded-xl border border-gray-200
                      overflow-hidden">
        <summary class="flex items-center justify-between
                        cursor-pointer p-6 text-lg font-semibold
                        text-gray-900 hover:bg-gray-50
                        transition-colors duration-200
                        list-none [&::-webkit-details-marker]:hidden">
          <span>データのセキュリティは大丈夫ですか?</span>
          <span class="ml-4 shrink-0 w-6 h-6 flex items-center
                       justify-center rounded-full bg-gray-100
                       group-open:bg-primary-100
                       transition-colors duration-200">
            <svg class="w-4 h-4 text-gray-500 group-open:text-primary-600
                        group-open:rotate-45
                        transition-all duration-200"
                 fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round"
                    stroke-width="2" d="M12 4v16m8-8H4" />
            </svg>
          </span>
        </summary>
        <div class="px-6 pb-6 text-gray-600 leading-relaxed">
          すべてのデータは暗号化されて保存・通信されます。
          SOC2 Type II認証を取得しており、定期的な第三者機関による
          セキュリティ監査も実施しています。GDPR にも対応しています。
        </div>
      </details>

      <!-- Q5 -->
      <details class="group bg-white rounded-xl border border-gray-200
                      overflow-hidden">
        <summary class="flex items-center justify-between
                        cursor-pointer p-6 text-lg font-semibold
                        text-gray-900 hover:bg-gray-50
                        transition-colors duration-200
                        list-none [&::-webkit-details-marker]:hidden">
          <span>サポート体制はどうなっていますか?</span>
          <span class="ml-4 shrink-0 w-6 h-6 flex items-center
                       justify-center rounded-full bg-gray-100
                       group-open:bg-primary-100
                       transition-colors duration-200">
            <svg class="w-4 h-4 text-gray-500 group-open:text-primary-600
                        group-open:rotate-45
                        transition-all duration-200"
                 fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round"
                    stroke-width="2" d="M12 4v16m8-8H4" />
            </svg>
          </span>
        </summary>
        <div class="px-6 pb-6 text-gray-600 leading-relaxed">
          メール・チャットサポートは平日9:00〜18:00で対応しています。
          プロプランではSlack連携による優先サポートもご利用いただけます。
          導入時には専任の担当者がオンボーディングを支援します。
        </div>
      </details>
    </div>
  </div>
</section>

開閉アニメーションの実装

<details> 要素はデフォルトではアニメーションなしで開閉します。スムーズなアニメーションを追加するには、少しの CSS と JavaScript が必要です。

> details/summary のアコーディオンに
  スムーズな開閉アニメーションを追加して。
  TailwindのクラスとわずかなカスタムCSSで。

Claude Code が提案するアニメーション付きの実装です。

/* src/style.css に追加 */
details .faq-content {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s ease-out;
}

details[open] .faq-content {
  grid-template-rows: 1fr;
}

details .faq-content > div {
  overflow: hidden;
}

HTML側の回答部分をラッパーで囲みます。

<details class="group bg-white rounded-xl border border-gray-200">
  <summary class="...">質問テキスト</summary>
  <div class="faq-content">
    <div>
      <div class="px-6 pb-6 text-gray-600 leading-relaxed">
        回答テキスト
      </div>
    </div>
  </div>
</details>

grid-template-rows0fr から 1fr に遷移させることで、高さが0から自然な高さまでスムーズにアニメーションします。この手法は max-height を使う方法よりも滑らかで、高さを事前に知る必要がありません。

FAQ Schema Markup(構造化データ)

FAQセクションに構造化データを追加すると、Google検索結果にFAQがリッチスニペットとして表示される可能性があります。これにより検索結果での占有面積が大きくなり、クリック率(CTR)が向上します。

> FAQセクションにJSON-LD形式のFAQ Schema Markupを追加して。
  上記の5つのQ&Aを含めて。

Claude Code が生成する構造化データです。

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "無料トライアル期間はどのくらいですか?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "14日間の無料トライアルをご用意しています。トライアル期間中はすべての機能をご利用いただけます。クレジットカードの登録は不要で、トライアル終了後に自動で課金されることはありません。"
      }
    },
    {
      "@type": "Question",
      "name": "解約はいつでもできますか?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "はい、いつでも解約可能です。管理画面から数クリックで手続きが完了します。違約金や解約手数料は一切かかりません。"
      }
    }
  ]
}
</script>

このスクリプトタグを index.html<head> 内に追加します。Google のリッチリザルトテストツールで正しくマークアップされているか検証できます。

演習問題

  1. FAQセクションの実装: 上記のコードをLPに追加し、各質問をクリックして開閉できることを確認してください。

  2. アニメーションの追加: CSS の grid-template-rows を使ったスムーズな開閉アニメーションを実装してください。

  3. FAQ Schema Markup の検証: JSON-LD を追加し、Google リッチリザルトテスト で構造化データが正しく認識されるか確認してください。

  4. 質問の追加: Claude Code に「料金プランについてのFAQ」を3つ追加してもらい、合計8問のFAQセクションに拡張してください。

参考資料

Lecture 8アニメーション — スクロール連動の動きをつける

12:00

アニメーション — スクロール連動の動きをつける

ここまでの講義で、ランディングページの主要なセクションがすべて揃いました。しかし、静的なページのままでは訪問者の印象に残りにくいことがあります。この講義では、スクロールに連動して要素がふわっと現れるフェードインアニメーションを実装します。Intersection Observer API と Tailwind CSS のトランジションを組み合わせることで、ページに洗練された動きを加えましょう。派手すぎず、ユーザー体験を損なわない上品なアニメーションが目標です。

アニメーションの原則

ランディングページにアニメーションを追加する際は、以下の原則を守りましょう。

目的を持ったアニメーション: アニメーションは装飾ではなく、ユーザーの注意を適切な場所に誘導するための手段です。CTAボタンへの視線誘導や、新しいセクションの登場を知らせるために使います。意味のないアニメーションは逆にユーザーのストレスになります。

パフォーマンスを意識する: transformopacity のアニメーションはGPUで処理されるため高速です。一方、widthheightmargin などのプロパティのアニメーションはレイアウトの再計算が発生し、パフォーマンスが低下します。アニメーションには transformopacity だけを使うのがベストプラクティスです。

控えめに: アニメーションの時間は0.3〜0.6秒が快適な範囲です。1秒を超えると「遅い」と感じます。また、ページ内のすべての要素にアニメーションを付けるのではなく、見出し、カード、CTAボタンなど重要な要素に絞りましょう。

アクセシビリティへの配慮: 一部のユーザーはアニメーションで体調を崩すことがあります。prefers-reduced-motion メディアクエリでアニメーションを無効にするオプションを提供しましょう。

Intersection Observer API の基本

Intersection Observer API は、ある要素が画面内(ビューポート)に入ったかどうかを監視する JavaScript API です。スクロールイベントを直接リッスンする方法よりもはるかにパフォーマンスが良く、モダンなスクロールアニメーションの標準的な実装方法です。

> Intersection Observer API を使って、
  スクロールで要素が画面に入った時にフェードインする
  アニメーションを実装して。Tailwind CSSのクラスを活用して。
  再利用しやすい汎用的な実装にして。

Claude Code が生成するアニメーションの実装です。

// src/main.js
document.addEventListener('DOMContentLoaded', () => {
  // アニメーション対象の要素を取得
  const animatedElements = document.querySelectorAll('[data-animate]');

  // Intersection Observer の設定
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          // 画面内に入ったら visible クラスを追加
          entry.target.classList.add('animate-visible');
          // 一度表示したら監視を解除(再度アニメーションしない)
          observer.unobserve(entry.target);
        }
      });
    },
    {
      threshold: 0.1,  // 要素の10%が見えたら発火
      rootMargin: '0px 0px -50px 0px',  // 下から50px手前で発火
    }
  );

  // 各要素を監視対象に登録
  animatedElements.forEach((el) => {
    observer.observe(el);
  });
});

Tailwind CSS でアニメーションクラスを定義する

次に、CSSでアニメーションの初期状態と表示状態を定義します。

/* src/style.css に追加 */

/* フェードイン + 上方向から */
[data-animate="fade-up"] {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

[data-animate="fade-up"].animate-visible {
  opacity: 1;
  transform: translateY(0);
}

/* フェードイン + 左から */
[data-animate="fade-left"] {
  opacity: 0;
  transform: translateX(-30px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

[data-animate="fade-left"].animate-visible {
  opacity: 1;
  transform: translateX(0);
}

/* フェードイン + 右から */
[data-animate="fade-right"] {
  opacity: 0;
  transform: translateX(30px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

[data-animate="fade-right"].animate-visible {
  opacity: 1;
  transform: translateX(0);
}

/* スケールイン */
[data-animate="scale-in"] {
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}

[data-animate="scale-in"].animate-visible {
  opacity: 1;
  transform: scale(1);
}

/* アクセシビリティ: モーション軽減設定のユーザー向け */
@media (prefers-reduced-motion: reduce) {
  [data-animate] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

HTML に data-animate 属性を追加する

準備ができたら、アニメーションさせたい要素に data-animate 属性を追加するだけです。

> 既存のLPの各セクションにスクロールアニメーションを追加して。
  - セクション見出し: fade-up
  - 特徴カード: fade-up(遅延付きでずらす)
  - テスティモニアル: fade-up
  - CTAセクション: scale-in
  data-animate 属性と遅延用の style を付けて。

Claude Code が提案する実装例です。

<!-- セクション見出し -->
<div class="text-center mb-16" data-animate="fade-up">
  <h2 class="text-3xl md:text-4xl font-bold text-gray-900">
    選ばれる3つの理由
  </h2>
</div>

<!-- 特徴カード(遅延をずらしてスタガーアニメーション) -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
  <div class="bg-white rounded-2xl p-8" data-animate="fade-up"
       style="transition-delay: 0ms;">
    <!-- カード1の内容 -->
  </div>
  <div class="bg-white rounded-2xl p-8" data-animate="fade-up"
       style="transition-delay: 150ms;">
    <!-- カード2の内容 -->
  </div>
  <div class="bg-white rounded-2xl p-8" data-animate="fade-up"
       style="transition-delay: 300ms;">
    <!-- カード3の内容 -->
  </div>
</div>

<!-- CTAセクション -->
<section data-animate="scale-in" class="py-20 bg-primary-900">
  <!-- CTA内容 -->
</section>

transition-delay を各カードにずらして設定することで「スタガーアニメーション」になります。カードが左から順番に0ms、150ms、300msの遅延で現れ、波のような動きを演出します。

Tailwind のビルトインアニメーションの活用

Tailwind CSS にはいくつかのビルトインアニメーションが用意されています。これらはスクロール連動ではなく、要素が表示された瞬間から常に動き続けるアニメーションです。

<!-- パルスアニメーション(CTAボタンの注目効果) -->
<div class="relative">
  <span class="absolute inset-0 rounded-full bg-accent-500
               animate-ping opacity-20"></span>
  <button class="relative px-8 py-4 bg-accent-500 text-white rounded-full">
    今すぐ申し込む
  </button>
</div>

<!-- バウンスアニメーション(スクロール誘導の矢印) -->
<div class="animate-bounce mt-10">
  <svg class="w-8 h-8 text-white mx-auto" fill="none"
       stroke="currentColor" viewBox="0 0 24 24">
    <path stroke-linecap="round" stroke-linejoin="round"
          stroke-width="2" d="M19 9l-7 7-7-7" />
  </svg>
</div>

<!-- スピンアニメーション(ローディング表示) -->
<svg class="animate-spin h-8 w-8 text-primary-500" viewBox="0 0 24 24">
  <circle class="opacity-25" cx="12" cy="12" r="10"
          stroke="currentColor" stroke-width="4" fill="none" />
  <path class="opacity-75" fill="currentColor"
        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>

animate-ping は脈動するパルス効果、animate-bounce は上下に弾むアニメーション、animate-spin は回転アニメーションです。ヒーローセクションの下向き矢印に animate-bounce を使うと、「下にスクロールしてね」というヒントを視覚的に伝えられます。

カスタム @keyframes の定義

ビルトインのアニメーションだけでは足りない場合、独自の @keyframes を定義することもできます。

> Tailwind CSSでカスタムアニメーションを定義して。
  テキストが1文字ずつ現れるタイプライター風アニメーション。
  ヒーローの見出しに使いたい。
/* src/style.css */
@keyframes typewriter {
  from { width: 0; }
  to { width: 100%; }
}

@keyframes blink-caret {
  from, to { border-color: transparent; }
  50% { border-color: white; }
}

.typewriter-text {
  overflow: hidden;
  white-space: nowrap;
  border-right: 3px solid white;
  animation:
    typewriter 2s steps(20) 0.5s forwards,
    blink-caret 0.75s step-end infinite;
  width: 0;
}
<h1 class="typewriter-text text-5xl font-bold text-white">
  ビジネスを加速する、最高のツール
</h1>

このタイプライター効果はヒーローセクションの見出しに使うと非常にインパクトがあります。ただし、レスポンシブ対応が難しい(white-space: nowrap のため折り返しが効かない)ため、デスクトップのみに適用するのが無難です。

演習問題

  1. フェードインアニメーションの実装: main.js に Intersection Observer のコードを追加し、各セクションの見出しに data-animate="fade-up" を追加して動作を確認してください。

  2. スタガーアニメーション: 特徴カード3枚に遅延をずらしたフェードインを実装し、左から順番にカードが現れることを確認してください。

  3. バウンス矢印の追加: ヒーローセクションの下部に animate-bounce を使った下向き矢印を追加してください。

  4. prefers-reduced-motion の検証: ブラウザの開発者ツールで prefers-reduced-motion: reduce をエミュレートし、アニメーションが無効になることを確認してください。

参考資料

Lecture 9ダークモード — テーマ切替機能を実装する

12:00

ダークモード — テーマ切替機能を実装する

ダークモードは、もはやトレンドではなく標準機能です。多くのユーザーが夜間や暗い環境でダークモードを利用しており、OSレベルでダークモードを設定しているユーザーも増えています。ランディングページにダークモード対応を追加することで、ユーザー体験の向上だけでなく、技術力のアピールにもなります。この講義では、Tailwind CSS の dark: プレフィックスと JavaScript を使って、テーマ切替機能を実装します。ユーザーの選択を localStorage に保存し、ページ再訪時にも設定が維持される仕組みを作りましょう。

ダークモードの設計方針

ダークモードを実装する前に、設計方針を決めておきましょう。

純粋な黒(#000)は避ける: 真っ黒な背景に白文字はコントラストが強すぎて目が疲れます。代わりに、濃いグレー(#111827#1f2937)を使うのが一般的です。Tailwind の gray-900gray-950 が適しています。

色のコントラスト比: WCAG 2.1 のガイドラインでは、テキストと背景のコントラスト比が4.5:1以上であることを推奨しています。ダークモードでは白文字にしがちですが、gray-100gray-200 のようにわずかにトーンを落とした白の方が読みやすくなります。

アクセントカラーの調整: ライトモードで使用している鮮やかな色は、ダークモードでは明るすぎて眩しく感じることがあります。ダークモード用に彩度を少し下げるか、明度を上げた色を用意しましょう。

画像とシャドウ: ダーク背景では shadow が見えにくくなります。代わりに border で区切りを表現するか、わずかに明るい背景色で要素を浮き立たせます。画像は brightness を少し下げると背景に馴染みます。

Tailwind CSS のダークモード設定

Tailwind CSS v4 では、ダークモードの検出方法を CSS で設定します。

> Tailwind CSS v4 でダークモードを設定して。
  手動切替(class方式)とOS設定の自動検出の両方に対応して。
  style.css の設定を教えて。

Claude Code が案内する設定です。Tailwind v4 ではデフォルトで prefers-color-scheme メディアクエリによる自動検出が有効ですが、手動切替も可能にするには selector 方式を使います。

/* src/style.css */
@import "tailwindcss";

@custom-variant dark (&:where(.dark, .dark *));

この設定により、<html> タグに dark クラスを付与することでダークモードを有効にできます。

各セクションにダークモードのクラスを追加する

既存のセクションに dark: プレフィックスを追加していきましょう。

> 既存のランディングページの各セクションに
  Tailwind CSSのdark:プレフィックスを追加して。
  ヒーロー、特徴、テスティモニアル、FAQ、CTAの各セクション。
  ダークモード時の配色も考慮して。

Claude Code が生成するダークモード対応の例です。

<!-- body タグ -->
<body class="bg-white text-gray-900
             dark:bg-gray-950 dark:text-gray-100
             transition-colors duration-300">

<!-- ヒーローセクション(元々暗い色なので変更少なめ) -->
<section class="bg-gradient-to-br from-primary-900 via-primary-700 to-primary-500
                dark:from-gray-950 dark:via-primary-900 dark:to-primary-800">
  <!-- 内容はほぼ同じ -->
</section>

<!-- 特徴セクション -->
<section class="py-20 bg-gray-50 dark:bg-gray-900">
  <div class="max-w-6xl mx-auto px-6">
    <h2 class="text-3xl font-bold text-gray-900 dark:text-white">
      選ばれる3つの理由
    </h2>
    <p class="text-gray-600 dark:text-gray-400">
      多くの企業が当サービスを選ぶ理由
    </p>

    <!-- 特徴カード -->
    <div class="bg-white dark:bg-gray-800
                border border-gray-100 dark:border-gray-700
                rounded-2xl p-8
                hover:shadow-lg dark:hover:shadow-gray-900/50">
      <h3 class="text-xl font-bold text-gray-900 dark:text-white">
        AIが自動で分析
      </h3>
      <p class="text-gray-600 dark:text-gray-400">
        膨大なデータを瞬時に分析...
      </p>
    </div>
  </div>
</section>

<!-- テスティモニアルセクション -->
<section class="py-20 bg-white dark:bg-gray-950">
  <div class="bg-gray-50 dark:bg-gray-800
              border border-gray-100 dark:border-gray-700
              rounded-2xl p-8">
    <blockquote class="text-gray-700 dark:text-gray-300">
      "導入してわずか2週間で..."
    </blockquote>
    <p class="font-bold text-gray-900 dark:text-white">田中 美咲</p>
    <p class="text-sm text-gray-500 dark:text-gray-400">マーケティング部長</p>
  </div>
</section>

<!-- FAQセクション -->
<section class="py-20 bg-gray-50 dark:bg-gray-900">
  <details class="bg-white dark:bg-gray-800
                  border border-gray-200 dark:border-gray-700
                  rounded-xl">
    <summary class="text-gray-900 dark:text-white
                    hover:bg-gray-50 dark:hover:bg-gray-750">
      質問テキスト
    </summary>
    <div class="text-gray-600 dark:text-gray-400">
      回答テキスト
    </div>
  </details>
</section>

テーマ切替ボタンの実装

ユーザーが手動でテーマを切り替えられるトグルボタンを実装します。

> ダークモードの切替ボタンを作って。
  太陽/月のアイコンで、クリックでトグルする。
  localStorage に保存して、ページリロード後も設定を維持。
  Tailwind CSSでスタイリング。

Claude Code が生成するトグルボタンです。

<!-- ヘッダーに配置するテーマ切替ボタン -->
<button id="theme-toggle"
        class="p-2 rounded-lg bg-gray-100 dark:bg-gray-800
               hover:bg-gray-200 dark:hover:bg-gray-700
               transition-colors duration-200"
        aria-label="テーマ切替">
  <!-- 太陽アイコン(ダークモード時に表示) -->
  <svg class="w-5 h-5 text-yellow-500 hidden dark:block"
       fill="currentColor" viewBox="0 0 20 20">
    <path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd" />
  </svg>
  <!-- 月アイコン(ライトモード時に表示) -->
  <svg class="w-5 h-5 text-gray-700 block dark:hidden"
       fill="currentColor" viewBox="0 0 20 20">
    <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
  </svg>
</button>

次に、テーマの切替と永続化を行う JavaScript です。

// src/theme.js
(function () {
  const toggle = document.getElementById('theme-toggle');
  const html = document.documentElement;

  // 保存されたテーマまたはOSの設定を適用
  function applyTheme() {
    const savedTheme = localStorage.getItem('theme');

    if (savedTheme === 'dark') {
      html.classList.add('dark');
    } else if (savedTheme === 'light') {
      html.classList.remove('dark');
    } else {
      // 保存がなければOSの設定に従う
      if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        html.classList.add('dark');
      } else {
        html.classList.remove('dark');
      }
    }
  }

  // 初回適用
  applyTheme();

  // トグルボタンのクリックイベント
  if (toggle) {
    toggle.addEventListener('click', () => {
      const isDark = html.classList.toggle('dark');
      localStorage.setItem('theme', isDark ? 'dark' : 'light');
    });
  }

  // OSのテーマ変更を検知(ユーザーが手動設定していない場合)
  window.matchMedia('(prefers-color-scheme: dark)')
    .addEventListener('change', (e) => {
      if (!localStorage.getItem('theme')) {
        if (e.matches) {
          html.classList.add('dark');
        } else {
          html.classList.remove('dark');
        }
      }
    });
})();

FOUC(Flash of Unstyled Content)の防止

テーマの JavaScript がページ読み込み後に実行されると、一瞬ライトモードが表示されてからダークモードに切り替わる「ちらつき」が発生します。これを防ぐには、<head> タグ内にインラインスクリプトを配置します。

> ダークモードのFOUC(ちらつき)を防止する方法を教えて。
  head内にインラインスクリプトを配置する方式で。
<head>
  <!-- FOUC防止: テーマをできるだけ早く適用 -->
  <script>
    (function () {
      var theme = localStorage.getItem('theme');
      if (theme === 'dark' ||
          (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
        document.documentElement.classList.add('dark');
      }
    })();
  </script>
</head>

このスクリプトは <head> 内で同期的に実行されるため、HTMLのレンダリング前にダーククラスが適用され、ちらつきが発生しません。

ダークモードのデバッグ

Chrome DevTools を使ったダークモードのデバッグ方法も覚えておきましょう。

DevTools を開き、Rendering パネルから Emulate CSS media feature prefers-color-schemedark に設定すると、OSの設定を変更せずにダークモードの表示をテストできます。Elements パネルで <html> タグの dark クラスの有無を確認することで、手動切替が正しく動作しているかも検証できます。

演習問題

  1. ダークモードの基本実装: @custom-variant の設定を追加し、body と各セクションに dark: プレフィックスのクラスを追加してください。ブラウザの DevTools で prefers-color-scheme: dark をエミュレートして表示を確認しましょう。

  2. トグルボタンの追加: 太陽/月アイコンのトグルボタンをヘッダーに追加し、クリックでテーマが切り替わることを確認してください。localStorage に保存されることも確認しましょう。

  3. FOUC防止の実装: <head> 内にインラインスクリプトを追加し、ページリロード時にちらつきが発生しないことを確認してください。ダークモードを有効にした状態でページをリロードして確認します。

  4. カラーパレットの調整: Claude Code に「ダークモード時にアクセントカラーの彩度を下げて目に優しくして」と依頼し、ダークモード専用のカラー調整を実装してみてください。

参考資料

Lecture 10最適化とデプロイ — 高速なLPを公開する

12:00

最適化とデプロイ — 高速なLPを公開する

コース最終講義です。ここまでの講義で、ヒーロー、特徴、テスティモニアル、FAQ、CTA、アニメーション、ダークモードと、フル機能のランディングページが完成しました。しかし、作って終わりではありません。実際にインターネット上に公開し、世界中の人がアクセスできる状態にする必要があります。この講義では、パフォーマンス最適化(画像、フォント、コードの軽量化)を行い、Lighthouse で品質を検証した後、Netlify または Vercel にデプロイする方法を学びます。Claude Code を使って、公開までの手順を効率的に進めましょう。

パフォーマンス最適化の重要性

ページの表示速度は、ユーザー体験とコンバージョン率に直結します。Google の調査によると、ページの読み込みが1秒から3秒に遅くなるだけで、直帰率が32%増加します。5秒になると90%増加します。また、Google はページ速度を検索ランキングの要因として使用しているため、SEO の観点からも最適化は必須です。

ランディングページは特にパフォーマンスが重要です。広告やSNSから流入した訪問者は、通常のオーガニック検索ユーザーよりも忍耐力が低く、少しでも表示が遅いとすぐに離脱します。

画像の最適化

画像はWebページの中で最もファイルサイズが大きくなりがちな要素です。Claude Code に最適化の方法を聞いてみましょう。

> ランディングページの画像を最適化する方法を教えて。
  以下を含めて:
  1. WebP/AVIF フォーマットへの変換
  2. レスポンシブ画像(srcset
  3. 遅延読み込み(lazy loading
  HTMLとTailwind CSSで実装して

Claude Code が提案する画像最適化の実装です。

<!-- 最適化された画像の例 -->
<picture>
  <!-- AVIF形式(最も軽量、対応ブラウザで使用) -->
  <source srcset="images/hero-480w.avif 480w,
                  images/hero-768w.avif 768w,
                  images/hero-1280w.avif 1280w"
          type="image/avif"
          sizes="(max-width: 768px) 100vw, 1280px" />

  <!-- WebP形式(AVIFの次に軽量) -->
  <source srcset="images/hero-480w.webp 480w,
                  images/hero-768w.webp 768w,
                  images/hero-1280w.webp 1280w"
          type="image/webp"
          sizes="(max-width: 768px) 100vw, 1280px" />

  <!-- フォールバック(JPEG) -->
  <img src="images/hero-1280w.jpg"
       alt="サービスイメージ"
       width="1280" height="720"
       loading="lazy"
       decoding="async"
       class="w-full h-auto object-cover rounded-2xl" />
</picture>

各属性のポイントを説明します。

<picture><source>: ブラウザが対応する最も効率的なフォーマットを自動選択します。AVIF > WebP > JPEG の優先順位で読み込まれます。

srcsetsizes: 画面幅に応じて適切なサイズの画像を読み込みます。モバイルで1280pxの大きな画像を読み込む無駄を防げます。

loading="lazy": 画面に表示される直前まで画像の読み込みを遅延させます。ファーストビュー以外の画像に設定することで、初期読み込み速度が大幅に改善します。ヒーロー画像など、ファーストビューに表示される画像には loading="eager" を指定して遅延させないようにしましょう。

widthheight: 画像サイズを明示することで、読み込み前にブラウザがレイアウトを確定でき、CLS(Cumulative Layout Shift:レイアウトのずれ)を防止します。

画像のフォーマット変換は、Claude Code にコマンドを聞きましょう。

> 画像をWebPとAVIFに変換するコマンドを教えて。
  複数サイズ(480px、768px、1280px)も一括生成したい。
# sharp-cli を使った一括変換
npx sharp-cli --input images/hero.jpg \
  --output images/hero-480w.webp --width 480 --format webp
npx sharp-cli --input images/hero.jpg \
  --output images/hero-768w.webp --width 768 --format webp
npx sharp-cli --input images/hero.jpg \
  --output images/hero-1280w.webp --width 1280 --format webp

フォントの最適化

Google Fonts を最適化するポイントもClaude Code に聞いてみましょう。

> Google FontsのNoto Sans JPの読み込みを最適化して。
  必要なウェイトだけ読み込み、font-display: swap で
  FOIT を防止して。preconnect も含めて。
<head>
  <!-- DNSプリフェッチとプリコネクト -->
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />

  <!-- 必要なウェイトのみ読み込み + display=swap -->
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap"
        rel="stylesheet" />
</head>

display=swap: フォントの読み込み中はシステムフォントを表示し、読み込み完了後に切り替えます。フォントの読み込みが遅くてもテキストが表示されないFOIT(Flash of Invisible Text)を防止します。

必要なウェイトに限定: wght@400;700 のように、実際に使用するウェイトだけを指定します。全ウェイトを読み込むと数百KBの無駄な転送が発生します。

Vite プロダクションビルド

Tailwind CSS と Vite のプロダクションビルドで、最終的なファイルサイズを最小化しましょう。

> Viteのプロダクションビルドの設定を最適化して。
  CSS・JSの圧縮、ハッシュ付きファイル名を含めて。
  vite.config.js の設定を教えて。
// vite.config.js
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [tailwindcss()],
  build: {
    // CSS・JSのminification(デフォルトで有効)
    minify: 'esbuild',
    // CSSを分離してキャッシュ効率を上げる
    cssCodeSplit: false,
    // 500KB以上のアセットに警告
    chunkSizeWarningLimit: 500,
    rollupOptions: {
      output: {
        // ハッシュ付きファイル名でキャッシュバスティング
        assetFileNames: 'assets/[name]-[hash][extname]',
        entryFileNames: 'assets/[name]-[hash].js',
      },
    },
  },
});

ビルドを実行します。

npm run build

dist/ フォルダに最適化されたファイルが出力されます。Tailwind CSS は使用されたクラスだけを含むため、CSSファイルは通常10〜30KB程度に収まります。

Lighthouse による品質検証

デプロイ前に、Google Lighthouse でページの品質を検証しましょう。

> Lighthouseのスコアを改善するためのチェックリストを作って。
  Performance、Accessibility、Best Practices、SEO
  の各カテゴリについて。

Claude Code が提案するチェックリストです。

Performance: LCP(Largest Contentful Paint)が2.5秒以内か。FID(First Input Delay)が100ms以内か。CLS(Cumulative Layout Shift)が0.1以内か。未使用のCSSやJSがないか。画像の最適化は完了しているか。

Accessibility: すべての画像に alt 属性があるか。ボタンに aria-label があるか。フォーカスリングが適切に表示されるか。カラーコントラスト比が4.5:1以上か。

Best Practices: HTTPS を使用しているか。コンソールにエラーがないか。セキュリティヘッダー(CSP、X-Frame-Options)を設定しているか。

SEO: <title><meta description> が適切か。OGPタグが設定されているか。FAQ Schema Markup が正しいか。モバイルフレンドリーか。

Chrome DevTools の Lighthouse タブからテストを実行し、100点を目指しましょう。

Netlify / Vercel へのデプロイ

いよいよLPを世界に公開します。Netlify と Vercel はどちらも無料プランがあり、Git連携で自動デプロイが可能です。

> Netlifyにデプロイする手順を教えて。
  GitHubリポジトリ連携と、CLIからの手動デプロイの
  両方の方法を教えて。

方法1: Netlify CLI を使った手動デプロイ

# Netlify CLIのインストール
npm install -g netlify-cli

# ビルド
npm run build

# デプロイ(プレビュー)
netlify deploy --dir=dist

# 本番デプロイ
netlify deploy --dir=dist --prod

方法2: Vercel CLI を使ったデプロイ

# Vercel CLIのインストール
npm install -g vercel

# デプロイ(対話式で設定)
vercel

# 本番デプロイ
vercel --prod

方法3: GitHub連携による自動デプロイ

GitHubリポジトリにプッシュするたびに自動でビルド・デプロイされる設定です。

# Gitリポジトリの初期化
git init
git add .
git commit -m "Initial commit: Landing page with Tailwind CSS"

# GitHubリポジトリを作成してプッシュ
gh repo create my-landing-page --public --push --source=.

Netlify または Vercel のダッシュボードで「Import from GitHub」を選択し、リポジトリを連携すると、以降のプッシュで自動デプロイが実行されます。ビルドコマンドは npm run build、公開ディレクトリは dist を指定します。

公開後のチェック

デプロイ後に確認すべき項目です。

> LP公開後にチェックすべき項目のリストを作って。
  パフォーマンス、SEO、OGP、アクセシビリティを含めて。

公開URLにアクセスし、以下を確認します。すべてのセクションが正しく表示されるか。レスポンシブが機能しているか。ダークモード切替が動作するか。アニメーションが正しく動くか。CTAボタンのリンク先が正しいか。OGPタグが正しく表示されるか(SNS共有プレビュー)。PageSpeed Insights でスコアが90点以上か。Google Search Console にサイトマップを送信したか。

これで全10講義が完了です。皆さんは、Claude Code と Tailwind CSS を使って、プロフェッショナルなランディングページをゼロから構築し、最適化してデプロイするまでの一連の流れを習得しました。

演習問題

  1. 画像最適化の実践: ヒーロー画像をWebP形式に変換し、<picture> タグを使って複数フォーマットに対応させてください。loading="lazy" の効果をNetwork タブで確認しましょう。

  2. Lighthouse テスト: プロダクションビルドしたページを Lighthouse でテストし、全カテゴリで90点以上を目指してください。スコアが低い項目は Claude Code に改善方法を相談しましょう。

  3. 実際のデプロイ: Netlify または Vercel のいずれかにデプロイし、公開URLでページを確認してください。スマートフォンからもアクセスして確認しましょう。

  4. OGPタグの設定: Claude Code に「SNSでシェアした時にサムネイルとタイトルが表示されるようにOGPタグを設定して」と依頼し、Twitter Cards Validator や Facebook Debugger で確認してください。

参考資料