ランディングページ — オーケストレーター
出力ディレクトリ: ./generated/{slug}-landing(カレントワーキングディレクトリからの相対パス、またはLANDING_PAGE_OUTPUT_DIR環境変数で設定可能)
ステップ1 — 入力の解析
引数を|で分割し、トリム:
[0]→company_name(省略時は、クリエイティブで業界に適した名前を考案)[1]→industry(省略時は推測)[2]→tagline_hint(オプション)[3]→target_audience(オプション)[4]→cta_goal(オプション、デフォルト: "無料で始める")
slug = company_nameを小文字化、アクセント除去、スペースはハイフンに変換。
出力パスを解決:
OUTPUT_DIR="${LANDING_PAGE_OUTPUT_DIR:-./generated}/{slug}-landing"
ステップ2 — コンテンツブリーフ(landing-page-copy)
landing-page-copyスキルを解析済み入力で呼び出す。CONTENT_BRIEF出力が完全に返るのを待ってから次に進む。
ブリーフには以下が含まれる: ヒーローコピー、特徴、推薦の声(testimonials)、FAQ、アバウト、料金プラン、ブログ記事、ケーススタディ、ナビゲーションラベル。このコピーは生成サイト内のすべてのテキストの唯一の情報源である — コード生成中にコピーを勝手に作ってはいけない。
ステップ3 — デザイン + SEO(並列実行)
3-A. デザインインテリジェンス(ui-ux-pro-max)
以下の3つのコマンドを並列実行:
python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "{industry}" --design-system -p "{company_name}"
python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "{industry}" --domain color -n 3
python3 ~/.claude/skills/ui-ux-pro-max/scripts/search.py "{industry} landing page" --domain typography -n 3
注: ui-ux-pro-maxスキルがインストールされている必要がある。利用できない場合は、業界とブランドコンテキストから直接デザインブリーフを合成すること。
デザインブリーフに合成:
- ビジュアルムード(3〜5つの形容詞)
- カラーパレット: プライマリ、セカンダリ、アクセント、bg、bg-soft、bg-card、surface、text、text-muted、text-inverse、border、border-subtle、dot
- タイポグラフィ: 見出しフォント + 本文フォント(Google Fontsに存在していること)
- レイアウト決定: ヒーロータイプ、機能レイアウト、推薦の声スタイル
- アニメーションスタイル: 控えめ / 中程度 / 表現豊か
- シグネチャ詳細: このページを記憶に残す、1つの特徴的なビジュアル要素
3-B. SEO計画(landing-page-seo)
landing-page-seoスキルを、company_name、industry、およびCONTENT_BRIEFとともに呼び出す。SEO_PLAN出力が完全に返るのを待つ。
計画には以下が含まれる: ページごとのメタタグ、スキーママークアップタイプ、サイトマップ設定、Core Web Vitalsビルドヒント、AI SEOヒント。
ステップ4 — すべてのファイルを書き込む
{OUTPUT_DIR}を作成し、Writeツールを使ってすべてのファイルをゼロから書き込む。コピーにはCONTENT_BRIEFを、メタ/スキーマにはSEO_PLANを使用する。テンプレートは使わず、プレースホルダーテキストも使わない。
4-A. インフラストラクチャ
package.json:
{
"name": "{slug}-landing",
"version": "0.1.0",
"private": true,
"scripts": { "dev": "next dev", "build": "next build", "start": "next start" },
"dependencies": {
"next": "^16.2.7",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"lucide-react": "^0.474.0",
"framer-motion": "^12.40.0"
},
"devDependencies": {
"@next/mdx": "^16.2.7",
"@mdx-js/loader": "^3.0.0",
"@mdx-js/react": "^3.0.0",
"@types/mdx": "^2.0.0",
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"tailwindcss": "^3.4.1",
"postcss": "^8.5.10",
"autoprefixer": "^10.0.1"
}
}
バージョン: スタックはNext 16 + React 19 + framer-motion 12 + lucide-react 0.474 (ビルド
output: 'export'はOK)で検証済み。nextを14.2.0に、react/react-domを^18に固定しないでください(脆弱性のあるバージョン — 2025-12-11付のNextに関する重大なアドバイザリ)。lucide-reactは>= 0.474である必要があります(0.378や< 0.474のバージョンはReact 19のピア依存を宣言しておらず、npm installが失敗します)。
next.config.js:
const withMDX = require('@next/mdx')()
module.exports = withMDX({
output: 'export',
images: { unoptimized: true },
pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'],
})
tsconfig.json: 標準のNext.js tsconfig。@/* パスエイリアスを ./ に、"jsx": "react-jsx" に設定(Next 16はReact自動ランタイムを使用 — "preserve" はビルド時に自動的に書き換えられる)
tailwind.config.ts:
darkMode: 'class'fontFamily: 見出し + 本文のCSS変数animation:marquee、float、line-growkeyframes: marqueetranslateX(0%)→translateX(-50%)、float、lineGrow
postcss.config.js: tailwind + autoprefixer
mdx-components.tsx: h1 h2 h3 p ul li strong blockquote をCSS変数を使ったスタイル付き要素にマッピング
app/globals.css:
@tailwind base/components/utilities:root内のCSS変数 — デザインブリーフのすべてのデザイントークンhtml.dark { ... }— ダークモード用にすべての変数をオーバーライドbodyはCSS変数を使用し、background-colorとcolorにトランジションを設定- カスタムユーティリティ:
.text-gradient、.dot-grid、.glass-card、.bracket-card、.clip-diagonal-bottom、.clip-diagonal-top - ルール: コンポーネント内のすべてのカラー参照はCSS変数を使用 — ハードコードされた16進数はゼロ
4-B. コンポーネント
それぞれを .tsx として記述。すべてのコンポーネントは lib/data.ts からコピーを読み込む。すべての色はCSS変数を経由。
components/DarkModeToggle.tsx:
'use client'、マウント時にlocalStorageを読み取り、<html>のdarkクラスをトグル- 設定を保持、Sun/Moonアイコンは lucide-react から
components/LogoCarousel.tsx:
'use client'、純粋なCSSマーキー(animate-marquee)、JSスクロールなし- ブランド名は
lib/data.tsから、シームレスループのために複製
components/ContactForm.tsx:
'use client'、ステート:'idle' | 'sending' | 'sent' | 'error'<form data-netlify="true" name="contact">に隠しフィールドform-name- フィールド: 名前、メール、会社、メッセージ
- 送信:
fetch('/', { method: 'POST', body: new URLSearchParams(new FormData(form)) })
components/Navbar.tsx: 固定、スクロール検知、モバイルメニュー、<DarkModeToggle />
components/Hero.tsx:
- Framer Motionのエントリアニメーションに
useReducedMotionチェック <data value="{stat.value}">を使った統計行(AI SEO)- デザインブリーフからのシグネチャデザイン詳細
components/Features.tsx: whileInView のFramer Motion、遅延をずらす
components/Testimonials.tsx: カードごとに whileInView のFramer Motion
components/FAQ.tsx:
'use client'、アコーディオン<dl>/<dt>/<dd>セマンティックマークアップ(FAQPageスキーマ + AI SEO)
components/Pricing.tsx:
'use client'、月額/年額請求トグルに −20% バッジpricevsprice_annualの切り替え
components/About.tsx: ストーリー + バリュー
components/Footer.tsx: タグライン + ナビゲーション + コピーライト
コンポーネントルール:
'use client'はインタラクティブ/ブラウザAPIコンポーネントのみimport type { X }を型のみのインポートに使用- 動的lucideアイコン:
import type { LucideIcon } from 'lucide-react'、その後(Icons as any)[name] as LucideIcon | undefined。アイコンのプロップは常にLucideIconとして型付け —React.ComponentType<{size?:number}>ではない(lucideのsizeはstring|numberなので、狭い型はnext buildの型チェックで失敗する)。 - すべての色はCSS変数経由 — ハードコードされた16進数はゼロ
- アニメーションにはFramer Motion(IntersectionObserverは使わない)
- すべてのテキストは
lib/data.tsから
4-C. ページ
app/layout.tsx:
- Google Fontsを
next/font/google経由で - SEO_PLANのホームページメタからのメタデータ
- JSON-LD: SEO_PLANからのOrganization + WebSite(またはSoftwareApplication)
<head>内のダークモードフラッシュ防止:try{if(localStorage.getItem('theme')==='dark'||(localStorage.getItem('theme')===null&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark')}}catch(e){}<html>にsuppressHydrationWarning<link rel="preconnect" href="https://fonts.googleapis.com">
app/page.tsx: Navbar + Hero + LogoCarousel + Features + Testimonials + Pricing + FAQ + ContactForm + Footer
app/tarifs/page.tsx: SEO_PLANからのメタデータ + JSON-LD(Offer + FAQPage)+ Navbar + Pricing + FAQ + ContactForm + Footer
app/a-propos/page.tsx: SEO_PLANからのメタデータ + JSON-LD(AboutPage + Organization)+ Navbar + About + Footer
app/blog/layout.tsx + app/blog/page.tsx: lib/blog.ts からの一覧
app/blog/{slug-1}/page.mdx + app/blog/{slug-2}/page.mdx:
- コンテンツはCONTENT_BRIEFの
blog[]から <article>+<time datetime="...">のセマンティックラップ- 最初の段落にTL;DR(AI SEOでの引用可能性)
app/cas-clients/layout.tsx + app/cas-clients/page.tsx: lib/case-studies.ts からの一覧
app/cas-clients/{slug-1}/page.mdx + app/cas-clients/{slug-2}/page.mdx:
- コンテンツはCONTENT_BRIEFの
case_studies[]から - 明示的な
## 課題 / ## 解決策 / ## 結果のH2構造(AI SEO) - SEO_PLANからのBreadcrumbList JSON-LD
app/sitemap.ts: SEO_PLANの sitemap_config をすべてのページ、投稿、ケーススタディに使用
app/robots.ts: すべて許可、sitemap URL
4-D. データファイル
lib/data.ts — CONTENT_BRIEFからのすべてのコピー:
export const siteData = {
nav: { links: [...], cta: "..." },
hero: { badge, headline_a, subheadline, cta_primary, cta_secondary, social_proof_bar, stats },
logoCarousel: { section_label, brands: [...] },
features: { badge, heading, sub, items: [...] },
testimonials: [...],
faq: { items: [...] },
about: { headline, story, values: [...] },
pricing: { heading, sub, plans: [...] },
contact: { heading, sub, form_cta },
footer: { tagline }
}
lib/blog.ts: CONTENT_BRIEFからのブログレジストリ
lib/case-studies.ts: CONTENT_BRIEFからのケーススタディレジストリ
ヒーロー画像 — 以下のUnsplashプレースホルダーから選択:
- テック/SaaS/フィンテック:
https://images.unsplash.com/photo-1518770660439-4636190af475?w=1600&q=80 - ヘルス/ウェルネス:
https://images.unsplash.com/photo-1571019613454-1cb2f99b2d8b?w=1600&q=80 - フード/バイオ:
https://images.unsplash.com/photo-1504674900247-0877df9cc836?w=1600&q=80 - スポーツ/フィットネス:
https://images.unsplash.com/photo-1517836357463-d25dfeac3438?w=1600&q=80 - ファッション/ラグジュアリー:
https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1600&q=80 - 不動産:
https://images.unsplash.com/photo-1560518883-ce09059eeffa?w=1600&q=80 - 教育:
https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=1600&q=80 - デフォルト:
https://images.unsplash.com/photo-1497366216548-37526070297c?w=1600&q=80
ステップ5 — ビルド
cd {OUTPUT_DIR}
npm install
npm run build
TypeScriptエラー — 修正して再試行:
import { X }→import type { X }を型のみのインポートに- 動的アイコン:
(Icons as any)[name] as LucideIcon | undefined(lucide-reactから型をインポート); アイコンのプロップはLucideIconとして型付け、ComponentType<{size?:number}>にはしないこと - 成功を報告する前にすべてのTypeScriptエラーを修正
ステップ6 — レポート
🏢 会社: {company_name} — {industry}
🎨 デザイン: {mood} | {見出しフォント} / {本文フォント}
✨ シグネチャ: {特徴的な詳細}
📝 見出し: "{headline_a}"
📄 ページ: / · /tarifs · /a-propos · /blog · /cas-clients
🔍 SEO: {ページタイトル} | {スキーマタイプ}
📁 出力: {OUTPUT_DIR}
ローカルプレビュー: cd {OUTPUT_DIR} && npm run dev