# 画面設計書 5-レイアウト

## 概要

本ドキュメントは、V3 Playground（Tailwind CSS v3互換）のルートレイアウト（`playgrounds/v3/app/layout.tsx`）の画面設計書である。Tailwind CSS v3形式の`@import`ディレクティブ構成を使用するNext.js App Routerのルートレイアウトコンポーネントであり、後方互換フック（applyCompatibilityHooks）の動作検証、Interフォントの適用、任意値バリアント（`[&_h1]:font-thin`）の処理について記述する。

### 本画面の処理概要

本レイアウトは、V3 Playgroundにおけるすべてのページに共通適用されるルートレベルのレイアウトコンポーネントである。Tailwind CSS v3形式のCSS構成（`@import 'tailwindcss/base'`、`@import 'tailwindcss/components'`、`@import 'tailwindcss/utilities'`）を使用し、後方互換レイヤーの動作を検証する。

**業務上の目的・背景**：Tailwind CSS v3からv4へのマイグレーションにおいて、v3形式のCSS構成（3分割`@import`パターン）が後方互換フック（`applyCompatibilityHooks`）により正しく処理されることを検証するためのデモレイアウトである。v3ユーザーがv4に移行する際、既存のCSS構成をそのまま使用できることを確認する目的がある。また、`<html>`要素に任意値バリアント`[&_h1]:font-thin`を適用し、バリアントパーサー・管理機能の動作検証も兼ねている。

**画面へのアクセス方法**：Next.js開発サーバー起動後（`next dev`）、ブラウザで`http://localhost:3000/`にアクセスする。本レイアウトはすべてのページに自動的に適用されるため、ページコンポーネント（page.tsx）を通じて間接的に描画される。

**主要な操作・処理内容**：
1. `import './globals.css'`によりglobals.css（v3形式の3分割@import構成）が読み込まれる
2. PostCSSプラグイン（`tailwindcss`パッケージ + `autoprefixer`）がglobals.cssを処理する
3. `applyCompatibilityHooks`がv3形式の`@import 'tailwindcss/base'`等のディレクティブを検出し、v4互換の形式に変換する
4. `Inter`フォント（Google Fonts）が`next/font/google`を通じてロードされる
5. `<html lang="en" className="[&_h1]:font-thin">`でHTML要素が生成され、任意値バリアントが適用される
6. `<body>`に`inter.className`（フォントクラス）が適用される
7. `{children}`により、ルーティングに基づくページコンポーネントが子要素として挿入される

**画面遷移**：本レイアウトはV3 Playgroundの全ページに共通適用される。現在のPlayground構成では、トップページ（No.6 page.tsx）のみが子要素として表示される。ページ間遷移は存在しない。

**権限による表示制御**：認証・認可の仕組みは存在しない。すべてのユーザーが同一のレイアウトを閲覧できる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 42 | 後方互換フック（applyCompatibilityHooks） | 主機能 | globals.cssのv3形式の`@import 'tailwindcss/base'`・`'tailwindcss/components'`・`'tailwindcss/utilities'`を処理する |
| 1 | CSS入力のコンパイル（compile） | 主機能 | globals.cssのv3互換ディレクティブにより、Tailwind CSSのコンパイルパイプラインが実行される |
| 25 | @importの解決（substituteAtImports） | 主機能 | globals.cssの@importディレクティブ群を解決し、スタイルシートをインライン展開する |
| 51 | PostCSSプラグイン（@tailwindcss/postcss） | 主機能 | postcss.config.jsで`tailwindcss`プラグインが登録されており、PostCSSビルド時にTailwind CSSの処理を統合する（v3互換構成） |
| 14 | バリアント管理（Variants） | 補助機能 | htmlタグの`[&_h1]:font-thin`任意値バリアントを処理し、バリアントルールを適用する |
| 17 | 候補パーサー（parseCandidate） | 補助機能 | `[&_h1]:font-thin`のクラス文字列を解析し、任意値バリアント付きCandidate構造体に変換する |
| 19 | バリアントパーサー（parseVariant） | 補助機能 | `[&_h1]`の任意値バリアント文字列をVariant構造体に解析する |
| 26 | ファイルスキャナー（Scanner - Rust/oxide） | 補助機能 | PostCSSプラグイン経由でソースファイルからTailwind CSS候補クラスをスキャンする |

## 画面種別

レイアウト（共通テンプレート・v3互換構成）

## URL/ルーティング

- **URL**: すべてのページに適用（Next.js App Routerのルートレイアウト）
- **ルーティング方式**: Next.js App Router。`app/layout.tsx`がルートレイアウトとして機能し、`app/`配下のすべてのpage.tsxを`{children}`として内包する。

## 入出力項目

| 項目名 | 種別 | 型 | 説明 |
|--------|------|-----|------|
| children | 入力（props） | `React.ReactNode` | Next.jsのルーティングにより挿入されるページコンポーネント |

## 表示項目

| 項目名 | 表示内容 | スタイル | データソース |
|--------|----------|----------|-------------|
| htmlタグ | HTML文書ルート | `lang="en"`、`className="[&_h1]:font-thin"`（任意値バリアント: h1要素にfont-weight: 100を適用） | layout.tsx 18行目 |
| headタグ | メタデータ領域 | コメントアウトされたCDNスクリプト | layout.tsx 19行目 |
| bodyタグ | ページコンテンツコンテナ | `inter.className`（Interフォント適用） | layout.tsx 20行目 |
| メタデータ - title | "Create Next App" | Next.jsの`<title>`タグとして出力 | layout.tsx 8行目 |
| メタデータ - description | "Generated by create next app" | Next.jsの`<meta name="description">`として出力 | layout.tsx 9行目 |

## イベント仕様

### 1-サーバーサイドレンダリング

1. Next.jsサーバーがリクエストを受信し、対応するページコンポーネントを特定する
2. RootLayout関数が呼び出され、`children`にページコンポーネントが渡される
3. `Inter`フォントのCSSが生成され、`inter.className`としてbody要素に適用される
4. PostCSSプラグインがglobals.cssを処理する：
   - `applyCompatibilityHooks`がv3形式の`@import 'tailwindcss/base'`等を検出
   - v4互換の形式に変換してコンパイルパイプラインを実行
5. `[&_h1]:font-thin`バリアントが解析され、`html`要素配下の`h1`要素に`font-weight: 100`が適用されるCSSルールが生成される
6. HTMLレスポンスがクライアントに返却される

### 2-メタデータ設定

1. `export const metadata: Metadata`によりNext.jsのメタデータAPIが有効化される
2. `title: 'Create Next App'`がHTMLの`<title>`タグとして出力される
3. `description: 'Generated by create next app'`が`<meta name="description">`として出力される

### 3-任意値バリアントの処理

1. `[&_h1]:font-thin`がScanner/Extractorにより候補クラスとして検出される
2. `parseCandidate`が`[&_h1]:font-thin`を解析し、バリアント部分`[&_h1]`とユーティリティ部分`font-thin`に分離する
3. `parseVariant`が`[&_h1]`を任意値バリアントとしてVariant構造体に解析する（`& h1`セレクタに展開）
4. 生成されるCSSは `html h1 { font-weight: 100; }` に相当するルールとなる

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | - | - | 本レイアウトはデータベースを使用しない |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| なし | - | - | 本レイアウトにメッセージ表示機能は存在しない |

## 例外処理

| 例外状況 | 動作 | ユーザーへの影響 |
|----------|------|----------------|
| Interフォントの読み込み失敗 | ブラウザのデフォルトフォントにフォールバックする | テキストのフォントがInterではなくシステムフォントで表示される |
| v3互換フックの処理失敗 | v3形式の@importが解決されず、ビルドエラーが発生する | ページが表示されない |
| 任意値バリアントの解析失敗 | `[&_h1]:font-thin`が無視され、h1要素にfont-thinスタイルが適用されない | h1要素のフォントウェイトがデフォルトのまま表示される |

## 備考

- 本PlaygroundはTailwind CSS v3（`tailwindcss: "^3"`）を依存関係として使用しており、v4のmonorepo内に存在するv3互換性テスト用のPlaygroundである
- postcss.config.jsでは`tailwindcss`と`autoprefixer`の2つのプラグインが登録されている。No.3レイアウト（Next.js Playground）では`@tailwindcss/postcss`が使用されているのに対し、本PlaygroundではTailwind CSS v3のPostCSSプラグインが使用されている
- globals.cssはv3形式の3分割構成（`@import 'tailwindcss/base'`、`@import 'tailwindcss/components'`、`@import 'tailwindcss/utilities'`）を使用しており、v4の単一`@import 'tailwindcss'`形式とは異なる
- `[&_h1]:font-thin`は任意値バリアント（arbitrary variant）と呼ばれるTailwind CSSの機能であり、`[&_h1]`は「現在の要素配下のh1要素」を意味するCSSセレクタに展開される
- `<head>`内に`<script src="https://cdn.tailwindcss.com"></script>`がコメントアウトされている

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

v3形式のCSS構成と後方互換フックの関係を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | globals.css | `playgrounds/v3/app/globals.css` | 1-3行目: v3形式の3分割@import構成を確認。`tailwindcss/base`、`tailwindcss/components`、`tailwindcss/utilities` |
| 1-2 | index.ts（tailwindcss） | `packages/tailwindcss/src/index.ts` | 21行目: `import { applyCompatibilityHooks } from './compat/apply-compat-hooks'`で後方互換フックのインポートを確認 |

**読解のコツ**: v3形式の3分割`@import`パターンはTailwind CSS v3の標準構成である。v4では`@import 'tailwindcss'`の単一インポートに統一されたが、`applyCompatibilityHooks`により旧形式も引き続きサポートされている。

#### Step 2: エントリーポイントを理解する

レイアウトコンポーネントとPostCSS設定を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | layout.tsx | `playgrounds/v3/app/layout.tsx` | 3行目: `import './globals.css'`でv3形式のCSSをインポート |
| 2-2 | postcss.config.js | `playgrounds/v3/postcss.config.js` | 1-6行目: `tailwindcss`と`autoprefixer`プラグインの登録 |
| 2-3 | package.json | `playgrounds/v3/package.json` | 15行目: `"tailwindcss": "^3"`でTailwind CSS v3への依存 |

**主要処理フロー**:
1. **layout.tsx:3行目**: `import './globals.css'`でv3形式のCSSファイルをインポート
2. **postcss.config.js:3-4行目**: `tailwindcss: {}`と`autoprefixer: {}`でプラグインを登録
3. **globals.css:1-3行目**: v3形式の3分割@importが`applyCompatibilityHooks`により処理される

#### Step 3: レイアウトコンポーネントの構造を理解する

RootLayout関数の実装詳細と任意値バリアントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | layout.tsx | `playgrounds/v3/app/layout.tsx` | 2行目: `import { Inter } from 'next/font/google'`でInterフォントをインポート |
| 3-2 | layout.tsx | `playgrounds/v3/app/layout.tsx` | 5行目: `const inter = Inter({ subsets: ['latin'] })`でフォントインスタンスを生成 |
| 3-3 | layout.tsx | `playgrounds/v3/app/layout.tsx` | 18行目: `<html lang="en" className="[&_h1]:font-thin">`で任意値バリアントを適用 |
| 3-4 | layout.tsx | `playgrounds/v3/app/layout.tsx` | 20行目: `<body className={inter.className}>`でフォントクラスを適用 |

**主要処理フロー**:
- **layout.tsx:18行目**: `className="[&_h1]:font-thin"`で任意値バリアントをhtml要素に適用
  - `[&_h1]`は「現在の要素配下のh1要素」に対するCSSセレクタ
  - `font-thin`は`font-weight: 100`に相当
  - 生成CSS: `.\\[\\&_h1\\]\\:font-thin h1 { font-weight: 100; }`
- **layout.tsx:20行目**: `{children}`でページコンポーネントを挿入

#### Step 4: 後方互換フックの処理を理解する

v3形式のCSS構成がどのように互換処理されるかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts（tailwindcss） | `packages/tailwindcss/src/index.ts` | 21行目: `applyCompatibilityHooks`のインポート |
| 4-2 | index.ts（tailwindcss） | `packages/tailwindcss/src/index.ts` | 35行目付近: `compoundsForSelectors`、バリアント関連のインポート |

### プログラム呼び出し階層図

```
layout.tsx (RootLayout)
    |
    +-- import './globals.css'
    |       |
    |       +-- PostCSS パイプライン [postcss.config.js]
    |               |
    |               +-- tailwindcss プラグイン (v3)
    |               |       |
    |               |       +-- applyCompatibilityHooks()
    |               |       |       +-- v3形式@import検出・変換
    |               |       |       +-- 'tailwindcss/base' -> base styles
    |               |       |       +-- 'tailwindcss/components' -> component styles
    |               |       |       +-- 'tailwindcss/utilities' -> utility styles
    |               |       |
    |               |       +-- compile() [コンパイルパイプライン]
    |               |       |       +-- substituteAtImports()
    |               |       |
    |               |       +-- Scanner [ファイルスキャン]
    |               |               +-- "[&_h1]:font-thin" 検出
    |               |
    |               +-- autoprefixer プラグイン
    |                       +-- ベンダープレフィックス追加
    |
    +-- className="[&_h1]:font-thin" 処理
    |       |
    |       +-- parseCandidate("[&_h1]:font-thin")
    |       |       +-- バリアント部: [&_h1]
    |       |       +-- ユーティリティ部: font-thin
    |       |
    |       +-- parseVariant("[&_h1]")
    |       |       +-- 任意値バリアント解析
    |       |       +-- セレクタ: & h1
    |       |
    |       +-- Variants.apply()
    |               +-- CSS生成: html h1 { font-weight: 100; }
    |
    +-- Inter フォント
    |       +-- inter.className (bodyに適用)
    |
    +-- {children} (page.tsx)
```

### データフロー図

```
[入力]                        [処理]                           [出力]

globals.css          ------>  applyCompatibilityHooks   ------>  v4互換CSS
  @import                      (v3形式検出・変換)
  'tailwindcss/base'
  'tailwindcss/components'
  'tailwindcss/utilities'

v4互換CSS            ------>  compile()                 ------>  コンパイル済みCSS
                               +-> substituteAtImports()
                               +-> Scanner/Extractor

className属性        ------>  parseCandidate()          ------>  Candidate構造体
  "[&_h1]:font-thin"          +-> parseVariant("[&_h1]")         (バリアント付き)

Candidate構造体      ------>  compileCandidates()        ------>  CSSルール
                               +-> Variants.apply()               html h1 {
                               +-> Utilities.generate()            font-weight: 100; }

Inter フォント設定    ------>  next/font/google           ------>  フォントCSS
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| layout.tsx | `playgrounds/v3/app/layout.tsx` | ソース | ルートレイアウトコンポーネント。任意値バリアント・フォント・メタデータ定義 |
| globals.css | `playgrounds/v3/app/globals.css` | スタイル | v3形式の3分割@import構成によるTailwind CSSエントリポイント |
| postcss.config.js | `playgrounds/v3/postcss.config.js` | 設定 | PostCSS設定。tailwindcss + autoprefixerプラグインの登録 |
| page.tsx | `playgrounds/v3/app/page.tsx` | ソース | トップページコンポーネント。childrenとしてレイアウトに挿入 |
| package.json | `playgrounds/v3/package.json` | 設定 | 依存関係定義。tailwindcss ^3、autoprefixer等 |
| index.ts | `packages/tailwindcss/src/index.ts` | ソース | Tailwind CSSコア。applyCompatibilityHooks、compile等 |
