cmx-sdk 0.2.9 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/add-studio-YUDYE2OH.js +0 -0
  2. package/dist/chunk-7TDMLYBI.js +0 -0
  3. package/dist/chunk-EDXXR5BE.js +0 -0
  4. package/dist/chunk-FPQYL5GE.js +0 -0
  5. package/dist/chunk-IIQLQIDP.js +0 -0
  6. package/dist/chunk-NZQ6SBFS.js +0 -0
  7. package/dist/{chunk-EZMBZWH7.js → chunk-Y3S3K6M3.js} +73 -28
  8. package/dist/cli.js +2 -2
  9. package/dist/init-FLRQXJX4.js +0 -0
  10. package/dist/{interactive-menu-FYVOQSTL.js → interactive-menu-5PRQIESI.js} +1 -1
  11. package/dist/studio-HAS6DYLO.js +0 -0
  12. package/dist/{update-sdk-KJZ6VB4M.js → update-sdk-ZXMWQF3I.js} +2 -1
  13. package/dist/update-studio-TWCYSYIS.js +0 -0
  14. package/package.json +14 -16
  15. package/templates/AGENTS.md +0 -173
  16. package/templates/CLAUDE.md +0 -28
  17. package/templates/claude/commands/check.md +0 -64
  18. package/templates/claude/commands/next-action.md +0 -66
  19. package/templates/claude/skills/cmx-cache/SKILL.md +0 -50
  20. package/templates/claude/skills/cmx-cache/references/cache-patterns.md +0 -153
  21. package/templates/claude/skills/cmx-component/SKILL.md +0 -108
  22. package/templates/claude/skills/cmx-component/references/component-schema.md +0 -123
  23. package/templates/claude/skills/cmx-content/SKILL.md +0 -158
  24. package/templates/claude/skills/cmx-content/references/migration-patterns.md +0 -120
  25. package/templates/claude/skills/cmx-content/references/seed-patterns.md +0 -146
  26. package/templates/claude/skills/cmx-dev/SKILL.md +0 -266
  27. package/templates/claude/skills/cmx-dev/references/api-patterns.md +0 -220
  28. package/templates/claude/skills/cmx-dev/references/cli-reference.md +0 -54
  29. package/templates/claude/skills/cmx-form/SKILL.md +0 -103
  30. package/templates/claude/skills/cmx-form/references/form-template.md +0 -152
  31. package/templates/claude/skills/cmx-migrate/SKILL.md +0 -501
  32. package/templates/claude/skills/cmx-migrate/references/analysis-guide.md +0 -127
  33. package/templates/claude/skills/cmx-migrate/references/html-to-mdx.md +0 -99
  34. package/templates/claude/skills/cmx-migrate/references/intermediate-format.md +0 -196
  35. package/templates/claude/skills/cmx-migrate/references/tool-setup.md +0 -150
  36. package/templates/claude/skills/cmx-schema/SKILL.md +0 -159
  37. package/templates/claude/skills/cmx-schema/references/field-types.md +0 -164
  38. package/templates/claude/skills/cmx-schema/references/migration-scenarios.md +0 -44
  39. package/templates/claude/skills/cmx-seo/SKILL.md +0 -54
  40. package/templates/claude/skills/cmx-seo/references/seo-patterns.md +0 -216
  41. package/templates/claude/skills/cmx-style/SKILL.md +0 -48
  42. package/templates/claude/skills/cmx-style/references/style-patterns.md +0 -114
@@ -1,164 +0,0 @@
1
- # フィールドタイプリファレンス
2
-
3
- ## 一覧
4
-
5
- | type | 説明 | options |
6
- |------|------|---------|
7
- | `text` | 単行テキスト | `maxLength`, `placeholder` |
8
- | `textarea` | 複数行テキスト | `maxLength`, `placeholder` |
9
- | `richtext` | リッチテキストエディタ | - |
10
- | `number` | 数値 | `min`, `max`, `step` |
11
- | `date` | 日付 | - |
12
- | `datetime` | 日時 | - |
13
- | `boolean` | 真偽値 | - |
14
- | `select` | ドロップダウン選択 | `choices[]`, `multiple` |
15
- | `multiselect` | 複数選択 | `choices[]` |
16
- | `image` | 画像 | - |
17
- | `file` | ファイル | - |
18
- | `json` | JSONデータ | - |
19
- | `url` | URL | - |
20
- | `email` | メールアドレス | - |
21
- | `relation` | 他データタイプへの参照 | `targetType` |
22
-
23
- ## options 詳細
24
-
25
- ```json
26
- {
27
- "maxLength": 100,
28
- "placeholder": "入力してください",
29
- "min": 0,
30
- "max": 999,
31
- "step": 1,
32
- "choices": [
33
- { "value": "option1", "label": "選択肢1" },
34
- { "value": "option2", "label": "選択肢2" }
35
- ],
36
- "multiple": false,
37
- "targetType": "staff"
38
- }
39
- ```
40
-
41
- ### text / textarea
42
-
43
- - `maxLength` (number) — 最大文字数
44
- - `placeholder` (string) — プレースホルダーテキスト
45
-
46
- ### number
47
-
48
- - `min` (number) — 最小値
49
- - `max` (number) — 最大値
50
- - `step` (number) — ステップ値
51
-
52
- ### select
53
-
54
- - `choices` (array) — `{ "value": "key", "label": "表示名" }` の配列
55
- - `multiple` (boolean) — `true` で複数選択可
56
-
57
- ### relation
58
-
59
- - `targetType` (string) — 参照先データタイプの slug
60
-
61
- ## defaultValue(デフォルト値)
62
-
63
- フィールド定義に `defaultValue` を設定すると、エントリ作成時に値が未入力の場合に自動的に適用されます。
64
-
65
- ```json
66
- {
67
- "key": "published",
68
- "label": "公開",
69
- "type": "boolean",
70
- "required": true,
71
- "defaultValue": false
72
- }
73
- ```
74
-
75
- **動作:**
76
- - エントリ作成時、フィールドに値が指定されていない場合に `defaultValue` が適用される
77
- - 明示的に `null` が指定された場合は `null` が保存される(デフォルト値は適用されない)
78
- - 値の型は `type` と一致する必要がある(例: `boolean` フィールドに `"false"` は不可)
79
-
80
- **使用例:**
81
- - `published: false` — グローバルデータタイプで、デフォルトで非公開
82
- - `status: "draft"` — ステータスフィールドで、デフォルトで下書き
83
- - `order: 0` — ソート順フィールドで、デフォルトで0
84
-
85
- ## データタイプ JSON 例
86
-
87
- ### スタッフ
88
-
89
- ```json
90
- {
91
- "slug": "staff",
92
- "name": "スタッフ",
93
- "description": "チームメンバー情報",
94
- "fields": [
95
- {
96
- "key": "name",
97
- "label": "名前",
98
- "type": "text",
99
- "required": true,
100
- "description": "フルネーム",
101
- "options": { "maxLength": 100 }
102
- },
103
- {
104
- "key": "position",
105
- "label": "役職",
106
- "type": "select",
107
- "options": {
108
- "choices": [
109
- { "value": "director", "label": "取締役" },
110
- { "value": "manager", "label": "マネージャー" },
111
- { "value": "engineer", "label": "エンジニア" }
112
- ]
113
- }
114
- },
115
- { "key": "bio", "label": "自己紹介", "type": "textarea", "options": { "maxLength": 500 } },
116
- { "key": "photo", "label": "写真", "type": "image" },
117
- { "key": "email", "label": "メールアドレス", "type": "email" }
118
- ]
119
- }
120
- ```
121
-
122
- ### FAQ
123
-
124
- ```json
125
- {
126
- "slug": "faq",
127
- "name": "よくある質問",
128
- "fields": [
129
- { "key": "question", "label": "質問", "type": "text", "required": true },
130
- { "key": "answer", "label": "回答", "type": "richtext", "required": true },
131
- {
132
- "key": "category",
133
- "label": "カテゴリ",
134
- "type": "select",
135
- "options": {
136
- "choices": [
137
- { "value": "general", "label": "一般" },
138
- { "value": "pricing", "label": "料金" },
139
- { "value": "technical", "label": "技術" }
140
- ]
141
- }
142
- },
143
- { "key": "is_featured", "label": "注目", "type": "boolean" }
144
- ]
145
- }
146
- ```
147
-
148
- ### 実績・事例
149
-
150
- ```json
151
- {
152
- "slug": "case-studies",
153
- "name": "実績・事例",
154
- "description": "導入事例や制作実績",
155
- "fields": [
156
- { "key": "title", "label": "タイトル", "type": "text", "required": true },
157
- { "key": "client", "label": "クライアント名", "type": "text" },
158
- { "key": "description", "label": "概要", "type": "textarea" },
159
- { "key": "thumbnail", "label": "サムネイル", "type": "image" },
160
- { "key": "url", "label": "サイトURL", "type": "url" },
161
- { "key": "published_date", "label": "公開日", "type": "date" }
162
- ]
163
- }
164
- ```
@@ -1,44 +0,0 @@
1
- # 移行シナリオ別ガイド
2
-
3
- サイト種別ごとに、よく使われるデータタイプとコレクションの構成例。
4
-
5
- ## コーポレートサイト
6
-
7
- データタイプ:
8
- - `staff` — メンバー紹介(name, position, bio, photo)
9
- - `service` — サービス紹介(title, description, icon, features)
10
- - `faq` — よくある質問(question, answer, category)
11
- - `testimonial` — お客様の声(name, company, content, rating)
12
-
13
- コレクション:
14
- - `news` type=news: お知らせ
15
- - `page` type=page: 会社概要、アクセス等
16
-
17
- ## LP(ランディングページ)
18
-
19
- データタイプ:
20
- - `feature` — 機能紹介(title, description, icon)
21
- - `pricing` — 料金プラン(name, price, features, is_popular)
22
- - `testimonial` — 利用者の声(name, company, content)
23
- - `cta` — CTAセクション(title, description, button_text, button_url)
24
-
25
- ## ブログ・メディア
26
-
27
- コレクション:
28
- - `post` type=post: 記事(blog, column, interview等)
29
- - フロントマター: title, description, category, tags, published_at
30
- - **category と tags はフロントマターに直接記述(データタイプ不要)**
31
-
32
- データタイプ:
33
- - `author` — 著者情報(name, bio, avatar, social_links)
34
-
35
- ## ECサイト
36
-
37
- データタイプ:
38
- - `product` — 商品(name, price, description, image, category)
39
- - `category` — カテゴリ(name, slug, parent)
40
- - `review` — レビュー(rating, content, author)
41
-
42
- コレクション:
43
- - `page` type=page: 特商法表記、プライバシーポリシー等
44
- - `news` type=news: セール情報、新商品情報
@@ -1,54 +0,0 @@
1
- ---
2
- name: cmx-seo
3
- description: |
4
- CMX Starter Kit の SEO・メタデータ実装スキル。generateMetadata、OGP、sitemap.ts、robots.ts、JSON-LD 構造化データのパターン。
5
- トリガー: 「SEOを設定」「メタデータを追加」「OGPを設定」「サイトマップを作成」
6
- 「robots.txtを設定」「構造化データを追加」「JSON-LDを追加」「検索対策」
7
- 「Twitterカードを設定」「og:imageを設定」「canonical URLを設定」など。
8
- ---
9
-
10
- # CMX SEO・メタデータ
11
-
12
- ## 事前確認
13
-
14
- `cmx/site-config.md` のサイト名・説明を確認し、メタデータに反映する。
15
-
16
- ## 環境変数
17
-
18
- `NEXT_PUBLIC_SITE_URL` — サイトの本番 URL。sitemap・canonical・OGP の URL 構築に必須。`.env.local` で設定済みか確認。
19
-
20
- ## 既存ユーティリティ
21
-
22
- `src/lib/utils/metadata.ts` に `generateCollectionMetadata` / `generateContentMetadata` ヘルパーが存在。拡張する場合はこのファイルを修正。
23
-
24
- ## パターン別ガイド
25
-
26
- 各パターンの詳細コードは [references/seo-patterns.md](references/seo-patterns.md) を参照。
27
-
28
- ### generateMetadata
29
-
30
- - **静的ページ**: `export const metadata: Metadata` で直接定義
31
- - **動的ページ**: `export async function generateMetadata()` で CMX API からデータ取得
32
- - **プレビューページ**: `robots: { index: false, follow: false }` を必ず設定
33
-
34
- ### OGP / Twitter Card
35
-
36
- `metadata.ts` の既存ヘルパーを拡張し、`openGraph` と `twitter` フィールドを追加する。デフォルト OG 画像は `/public/og-default.jpg` に配置。
37
-
38
- ### sitemap.ts
39
-
40
- `src/app/sitemap.ts` を作成。CMX API から全コレクションの記事を取得し動的生成。
41
-
42
- ### robots.ts
43
-
44
- `src/app/robots.ts` を作成。`/preview/` と `/api/` を disallow。
45
-
46
- ### JSON-LD 構造化データ
47
-
48
- 記事詳細ページに `<script type="application/ld+json">` を埋め込む。スキーマタイプは `BlogPosting`(ブログ)、`NewsArticle`(ニュース)、`WebPage`(その他)。
49
-
50
- ## 変更後
51
-
52
- 1. 各ページの `<head>` 出力を確認(ブラウザの DevTools)
53
- 2. OGP デバッガー(Facebook Sharing Debugger 等)で確認
54
- 3. Google Rich Results Test で JSON-LD を検証
@@ -1,216 +0,0 @@
1
- # SEO 実装パターン
2
-
3
- ## generateMetadata — 静的ページ
4
-
5
- ```tsx
6
- // src/app/about/page.tsx
7
- import type { Metadata } from "next"
8
-
9
- const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com"
10
-
11
- export const metadata: Metadata = {
12
- title: "会社概要 | サイト名",
13
- description: "会社概要ページの説明文",
14
- alternates: { canonical: `${SITE_URL}/about` },
15
- openGraph: {
16
- title: "会社概要 | サイト名",
17
- description: "会社概要ページの説明文",
18
- url: `${SITE_URL}/about`,
19
- images: ["/og-default.jpg"],
20
- },
21
- }
22
- ```
23
-
24
- ## generateMetadata — 動的ページ(記事詳細)
25
-
26
- `src/lib/utils/metadata.ts` を拡張:
27
-
28
- ```tsx
29
- import type { Metadata } from "next"
30
- import { fetchPublishedContent } from "@/lib/api/public-client"
31
-
32
- const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com"
33
-
34
- export async function generateContentMetadata(
35
- collectionSlug: string,
36
- contentSlug: string
37
- ): Promise<Metadata> {
38
- const data = await fetchPublishedContent(collectionSlug, contentSlug)
39
- if (!data) {
40
- throw new Error(`Failed to fetch content metadata: ${collectionSlug}/${contentSlug}`)
41
- }
42
-
43
- const url = `${SITE_URL}/${collectionSlug}/${contentSlug}`
44
- const title = `${data.content.title} | ${data.collection.name}`
45
- const description = data.content.description || undefined
46
- const image = "/og-default.jpg"
47
-
48
- return {
49
- title,
50
- description,
51
- alternates: { canonical: url },
52
- openGraph: {
53
- title: data.content.title,
54
- description,
55
- url,
56
- type: "article",
57
- images: [image],
58
- },
59
- twitter: {
60
- card: "summary_large_image",
61
- title: data.content.title,
62
- description,
63
- images: [image],
64
- },
65
- }
66
- }
67
- ```
68
-
69
- ## sitemap.ts
70
-
71
- ```tsx
72
- // src/app/sitemap.ts
73
- import type { MetadataRoute } from "next"
74
- import { fetchPublishedContents } from "@/lib/api/public-client"
75
- import { COLLECTION_SLUGS } from "@/lib/constants/collections"
76
-
77
- const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com"
78
-
79
- export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
80
- const entries: MetadataRoute.Sitemap = [
81
- {
82
- url: SITE_URL,
83
- lastModified: new Date(),
84
- changeFrequency: "daily",
85
- priority: 1,
86
- },
87
- ]
88
-
89
- // 静的ページ
90
- const staticPages = ["/about", "/contact"]
91
- for (const page of staticPages) {
92
- entries.push({
93
- url: `${SITE_URL}${page}`,
94
- changeFrequency: "monthly",
95
- priority: 0.5,
96
- })
97
- }
98
-
99
- // 各コレクションの記事を取得
100
- for (const slug of Object.values(COLLECTION_SLUGS)) {
101
- // コレクション一覧ページ
102
- entries.push({
103
- url: `${SITE_URL}/${slug}`,
104
- changeFrequency: "daily",
105
- priority: 0.8,
106
- })
107
-
108
- // 各記事
109
- try {
110
- const data = await fetchPublishedContents(slug)
111
- if (data?.contents) {
112
- for (const item of data.contents) {
113
- entries.push({
114
- url: `${SITE_URL}/${slug}/${item.slug}`,
115
- lastModified: item.publishedAt ? new Date(item.publishedAt) : new Date(),
116
- changeFrequency: "weekly",
117
- priority: 0.7,
118
- })
119
- }
120
- }
121
- } catch {
122
- // コレクション取得失敗時はスキップ
123
- }
124
- }
125
-
126
- return entries
127
- }
128
- ```
129
-
130
- ## robots.ts
131
-
132
- ```tsx
133
- // src/app/robots.ts
134
- import type { MetadataRoute } from "next"
135
-
136
- const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com"
137
-
138
- export default function robots(): MetadataRoute.Robots {
139
- return {
140
- rules: {
141
- userAgent: "*",
142
- allow: "/",
143
- disallow: ["/preview/", "/api/"],
144
- },
145
- sitemap: `${SITE_URL}/sitemap.xml`,
146
- }
147
- }
148
- ```
149
-
150
- ## JSON-LD 構造化データ
151
-
152
- ### ブログ記事
153
-
154
- ```tsx
155
- // src/app/blog/[slug]/page.tsx 内
156
- const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com"
157
-
158
- function BlogPostJsonLd({ content, collectionSlug, slug }: {
159
- content: { title: string; description?: string; publishedAt?: string; updatedAt?: string; featuredImage?: string }
160
- collectionSlug: string
161
- slug: string
162
- }) {
163
- const jsonLd = {
164
- "@context": "https://schema.org",
165
- "@type": "BlogPosting",
166
- headline: content.title,
167
- description: content.description,
168
- datePublished: content.publishedAt,
169
- dateModified: content.updatedAt ?? content.publishedAt,
170
- image: content.featuredImage,
171
- url: `${SITE_URL}/${collectionSlug}/${slug}`,
172
- publisher: {
173
- "@type": "Organization",
174
- name: "サイト名", // site-config.md のサイト名を使用
175
- },
176
- }
177
-
178
- return (
179
- <script
180
- type="application/ld+json"
181
- dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
182
- />
183
- )
184
- }
185
- ```
186
-
187
- ### 組織情報(ルートレイアウト)
188
-
189
- ```tsx
190
- // src/app/layout.tsx に追加
191
- function OrganizationJsonLd() {
192
- const jsonLd = {
193
- "@context": "https://schema.org",
194
- "@type": "Organization",
195
- name: "サイト名",
196
- url: process.env.NEXT_PUBLIC_SITE_URL,
197
- logo: `${process.env.NEXT_PUBLIC_SITE_URL}/logo.png`,
198
- }
199
-
200
- return (
201
- <script
202
- type="application/ld+json"
203
- dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
204
- />
205
- )
206
- }
207
- ```
208
-
209
- ## コレクションタイプ別の JSON-LD スキーマタイプ
210
-
211
- | コレクションタイプ | schema.org @type |
212
- |------------------|------------------|
213
- | post(ブログ) | BlogPosting |
214
- | news(ニュース) | NewsArticle |
215
- | page(ページ) | WebPage |
216
- | doc(ドキュメント) | TechArticle |
@@ -1,48 +0,0 @@
1
- ---
2
- name: cmx-style
3
- description: |
4
- CMX Starter Kit のスタイル・デザイン変更スキル。CSS 変数、フォント、レイアウト、カラーの変更パターンと site-config.md との連動。
5
- トリガー: 「スタイルを変更」「デザインを変えたい」「色を変更」「フォントを変更」
6
- 「レイアウトを変更」「ヘッダーを修正」「フッターを修正」「ダークモード」
7
- 「余白を調整」「見た目を変えたい」など。
8
- ---
9
-
10
- # CMX スタイル変更
11
-
12
- ## 事前確認
13
-
14
- 変更前に必ず `cmx/site-config.md` のデザイン方針セクションを読み、変更が方針と矛盾しないか確認する。矛盾する場合はコンフィグの更新も提案すること。
15
-
16
- ## 変更対象と対応ファイル
17
-
18
- | 変更内容 | 対象ファイル |
19
- |---------|------------|
20
- | カラー(テーマ色、背景色等) | `src/app/globals.css` |
21
- | フォント | `src/app/layout.tsx` |
22
- | Header | `src/components/layout/Header.tsx` |
23
- | Footer | `src/components/layout/Footer.tsx` |
24
- | MDX 記事のスタイル | `src/app/globals.css`(`.prose` カスタマイズ) |
25
- | コンポーネントスタイル | 該当 TSX ファイル |
26
- | 全体的なスペーシング | `src/app/globals.css` |
27
-
28
- ## パターン別ガイド
29
-
30
- 詳細は [references/style-patterns.md](references/style-patterns.md) を参照。
31
-
32
- ### カラー変更
33
-
34
- `src/app/globals.css` の CSS 変数を修正。shadcn/ui のテーマ変数体系に従う。
35
-
36
- ### フォント変更
37
-
38
- `src/app/layout.tsx` の `next/font/google` インポートを変更。CSS 変数でフォントファミリーを指定。
39
-
40
- ### レイアウト変更
41
-
42
- Header/Footer は `src/components/layout/` 配下。ナビゲーション項目、ロゴ、カラムレイアウトを修正。
43
-
44
- ## 変更後
45
-
46
- 1. 開発サーバーで全ページの表示を確認
47
- 2. レスポンシブ(モバイル/タブレット/デスクトップ)を確認
48
- 3. `cmx/site-config.md` のデザイン方針セクションを更新して同期
@@ -1,114 +0,0 @@
1
- # スタイル変更パターン
2
-
3
- ## カラー変更
4
-
5
- `src/app/globals.css` の `:root` と `.dark` で CSS 変数を定義。shadcn/ui 体系:
6
-
7
- ```css
8
- :root {
9
- --background: 0 0% 100%; /* 背景色 */
10
- --foreground: 222.2 84% 4.9%; /* テキスト色 */
11
- --card: 0 0% 100%; /* カード背景 */
12
- --card-foreground: 222.2 84% 4.9%; /* カードテキスト */
13
- --primary: 222.2 47.4% 11.2%; /* プライマリ */
14
- --primary-foreground: 210 40% 98%; /* プライマリ上のテキスト */
15
- --secondary: 210 40% 96.1%; /* セカンダリ */
16
- --muted: 210 40% 96.1%; /* 控えめな背景 */
17
- --muted-foreground: 215.4 16.3% 46.9%; /* 控えめなテキスト */
18
- --accent: 210 40% 96.1%; /* アクセント */
19
- --destructive: 0 84.2% 60.2%; /* 削除・エラー */
20
- --border: 214.3 31.8% 91.4%; /* ボーダー */
21
- --ring: 222.2 84% 4.9%; /* フォーカスリング */
22
- --radius: 0.5rem; /* 角丸 */
23
- }
24
- ```
25
-
26
- 値は HSL 形式(`hue saturation% lightness%`)。Tailwind で `bg-primary` のように使用される。
27
-
28
- ## フォント変更
29
-
30
- `src/app/layout.tsx` で Google Fonts を読み込み:
31
-
32
- ```tsx
33
- import { Inter, Noto_Sans_JP } from "next/font/google"
34
-
35
- const inter = Inter({
36
- subsets: ["latin"],
37
- variable: "--font-sans",
38
- })
39
-
40
- const notoSansJP = Noto_Sans_JP({
41
- subsets: ["latin"],
42
- weight: ["400", "500", "700"],
43
- variable: "--font-noto-sans-jp",
44
- })
45
-
46
- // <body> に className で適用
47
- <body className={`${inter.variable} ${notoSansJP.variable} font-sans`}>
48
- ```
49
-
50
- `globals.css` でフォントファミリーを定義:
51
-
52
- ```css
53
- :root {
54
- --font-sans: var(--font-inter), var(--font-noto-sans-jp), sans-serif;
55
- --font-mono: var(--font-geist-mono), monospace;
56
- }
57
- ```
58
-
59
- ## Header カスタマイズ
60
-
61
- `src/components/layout/Header.tsx`:
62
-
63
- ```tsx
64
- const navItems = [
65
- { href: "/blog", label: "ブログ" },
66
- { href: "/about", label: "企業情報" },
67
- { href: "/contact", label: "お問い合わせ" },
68
- ]
69
- ```
70
-
71
- - ナビ項目の追加・削除・順序変更
72
- - ロゴの変更(テキスト or 画像)
73
- - スティッキーヘッダーの有無
74
- - モバイルメニューの挙動
75
-
76
- ## Footer カスタマイズ
77
-
78
- `src/components/layout/Footer.tsx`:
79
-
80
- - カラム数とカラム内容の変更
81
- - SNS リンクの追加
82
- - コピーライト表記の変更
83
-
84
- ## MDX 記事スタイル
85
-
86
- `@tailwindcss/typography` の `.prose` クラスをカスタマイズ:
87
-
88
- ```css
89
- .prose {
90
- --tw-prose-body: hsl(var(--foreground));
91
- --tw-prose-headings: hsl(var(--foreground));
92
- --tw-prose-links: hsl(var(--primary));
93
- }
94
-
95
- .prose h2 {
96
- @apply border-b pb-2;
97
- }
98
-
99
- .prose img {
100
- @apply rounded-lg;
101
- }
102
- ```
103
-
104
- ## レスポンシブ設計
105
-
106
- Tailwind のブレークポイント:
107
-
108
- | プレフィックス | 最小幅 | 用途 |
109
- |-------------|-------|------|
110
- | (なし) | 0px | モバイル |
111
- | `sm:` | 640px | 小型タブレット |
112
- | `md:` | 768px | タブレット |
113
- | `lg:` | 1024px | デスクトップ |
114
- | `xl:` | 1280px | 大画面 |