
# テーマとカスタマイズ

Tailwindのテーマは、フラットなCSS変数の集合です。入力CSS内の`@theme { … }`ブロックで拡張または置換し、CSS内からテーマ関数で値を参照して、解決済みの値をPHPから読み取れます。JavaScript設定ファイルはなく、テーマはすべてCSS内にあります。

## `@theme`ブロック

`@theme`ブロックでは、デザイントークンをCSSカスタムプロパティとして宣言します。各変数の名前空間プレフィックス（`--color-*`、`--font-*`、`--breakpoint-*`、`--spacing-*`、…）によって、そのトークンを使用するユーティリティとバリアントがTailwindに示されます。

```php
use TailwindPHP\tw;

$css = tw::generate('<div class="bg-brand text-brand xs:flex">', '
    @import "tailwindcss";

    @theme {
        --color-brand: #3b82f6;
        --font-heading: "Inter", sans-serif;
        --breakpoint-xs: 20rem;
        --spacing-huge: 10rem;
    }
');
```

各トークンは、その名前空間に対応するユーティリティを登録します。上の例では`bg-brand`、`text-brand`、`border-brand`、`font-heading`ファミリー、`xs:`レスポンシブバリアント、`p-huge`/`m-huge`スペーシングを利用できるようにします。生成されるのは、クラスがコンテンツ内に現れた場合のみです。

```css
/* bg-brand resolves to the theme variable */
:root, :host {
  --color-brand: #3b82f6;
}
.bg-brand {
  background-color: var(--color-brand);
}
```

`--breakpoint-xs`トークンは`xs:`バリアントを直接登録します。

```css
@media (min-width: 20rem) {
  .xs\:flex {
    display: flex;
  }
}
```

### よく使う名前空間

| 名前空間 | 対応するもの |
|-----------|-------|
| `--color-*` | `bg-*`、`text-*`、`border-*`、`fill-*`、`stroke-*`、… |
| `--font-*` | `font-*`ファミリーのユーティリティ |
| `--text-*` | `text-*`フォントサイズユーティリティ |
| `--breakpoint-*` | レスポンシブバリアント（`sm:`、`md:`、カスタム`xs:`） |
| `--spacing-*` | 名前付きスペーシング値（`p-huge`、`m-huge`） |
| `--radius-*` | `rounded-*`ユーティリティ |
| `--shadow-*` | `shadow-*`ユーティリティ |

### 名前空間をクリアする

名前空間のワイルドカードに`initial`を設定すると、独自のトークンを追加する前に、その名前空間に対するTailwindの既定値が削除されます。これにより、初期状態から独自のパレットを作成できます。

```css
@theme {
    /* Drop every default color, then define only what you need */
    --color-*: initial;
    --color-brand: #3b82f6;
    --color-ink: #111827;
}
```

`--*: initial;`はテーマ全体をクリアします。ワイルドカードではないキー（`--color-red-500: initial;`）に`initial`を1つ指定すると、そのトークンだけを削除できます。`-*`ワイルドカードの値として認められるのは`initial`だけで、それ以外はエラーになります。

## CSS内でテーマ値を参照する

### `theme()`

従来の`theme()`関数は、v3-style名前空間に対してドット記法で値を取得します。コンパイル時にトークンの値へ解決されるため、カスタムルールやその他の宣言を含め、値が必要な場所ならどこでも使用できます。

```php
$css = tw::generate('<div class="callout">', '
    @import "tailwindcss";
    .callout { color: theme(colors.red.500); }
');
```

```css
.callout {
  color: oklch(63.7% .237 25.331);
}
```

ドットパスは基になる変数に対応します（`colors.red.500` → `--color-red-500`、`fontFamily.sans` → sansファミリー）。不透明度修飾子も使用できます: `theme(colors.red.500 / 50%)`。フォールバックは第2引数として渡せます: `theme(colors.brand, #000)`。パスを解決できず、フォールバックも指定されていない場合、それを使用する候補は除外されます。

### `--theme()`

`--theme()`はCSSカスタムプロパティ名でテーマ変数を読み取り、デフォルトでは`var()`参照を返すため、実行時に値を上書きできます:

```css
.btn { color: --theme(--color-brand); }
/* → color: var(--color-brand); */
```

`inline`を追加すると、`var()`参照の代わりに解決済みの値を展開します: `--theme(--color-brand inline)`。第2引数はフォールバックです（`--theme(--color-brand, #000)`）。`initial`フォールバックは特別に処理され、それ自体が`initial`に解決される入れ子の`var()`参照に挿入されます。アットルール（`@media`、`@container`）内では、`var()`をその前置部で使用できないため、`--theme()`は常にインラインで解決されます。

### `--spacing()`

`--spacing(n)`はテーマの基本スペーシング単位（`--spacing`）に`n`を掛けます:

```css
@utility my-gap { gap: --spacing(4); }
/* → gap: calc(var(--spacing) * 4); */
```

乗数が`1`の場合、基本変数そのものに解決され（`--spacing(1)` → `var(--spacing)`。`p-1`が出力するものと同じです）、`0`の場合は長さが単なるゼロになります。

これは組み込みのスペーシングユーティリティと同じ計算なので、カスタム値も`p-4`、`m-4`などと一貫性を保てます。

### `--alpha()`

`--alpha(color / opacity)`はoklab色空間の`color-mix()`を使って、色に不透明度を適用します:

```css
@utility tint { color: --alpha(var(--color-red-500) / 50%); }
```

```css
.tint {
  color: #fb2c3680;
}
@supports (color: color-mix(in lab, red, red)) {
  .tint {
    color: color-mix(in oklab, var(--color-red-500) 50%, transparent);
  }
}
```

`color-mix()`形式は実行時に上書きできます。その前にあるテーマ値から計算された静的フォールバックは、`color-mix()`に対応しないブラウザーをカバーします。フォールバックを無効にするには、[`tw::compile()`](https://tailwindphp.inline0.dev/ja/docs/api#twcompile)の`polyfills`オプションを使います。

### 不透明度の重ね合わせと`color-mix()` → `oklab()`

不透明度修飾子は合成されます。すでに50%の値に50%を適用すると、oklabで計算された25%になります。不透明度修飾子が静的な色に適用される場合、TailwindPHPは`color-mix(in oklab, …)`式を具体的な`oklab()`値に畳み込みます。これは上流のTailwindツールチェーンでlightningcssが行う変換と同じです。一方、動的な色（`var()`でラップされたままの色）は、実行時に上書きできるよう`color-mix()`形式を保ちます。

## PHPからテーマ値を読み取る

3つのアクセサーは、解決済みのテーマ値をPHP配列として返します。それぞれ省略可能な入力CSS文字列（デフォルトは`@import "tailwindcss";`）を受け取り、[コンパイラーインスタンス](https://tailwindphp.inline0.dev/ja/docs/api)でも利用できます。

```php
use TailwindPHP\tw;

tw::colors();
// ['red-500' => 'oklch(63.7% .237 25.331)', 'blue-500' => 'oklch(62.3% .214 259.815)', ...]

tw::breakpoints();
// ['sm' => '40rem', 'md' => '48rem', 'lg' => '64rem', 'xl' => '80rem', '2xl' => '96rem']

tw::spacing('@import "tailwindcss"; @theme { --spacing-huge: 10rem; }');
// ['huge' => '10rem']
```

カスタマイズしたテーマに対して読み取るには、CSS文字列を渡します:

```php
tw::colors('@import "tailwindcss"; @theme { --color-brand: #3b82f6; }');
// [..., 'brand' => '#3b82f6']

tw::breakpoints('@import "tailwindcss"; @theme { --breakpoint-xs: 20rem; }');
// ['sm' => '40rem', ..., '2xl' => '96rem', 'xs' => '20rem']
```

TailwindCSS 4では`--spacing-*`スケールではなく単一の`--spacing`基本値を使うため、`tw::spacing()`は定義したカスタム`--spacing-*`トークンのみを返します。コンパイラーインスタンスでも同じメソッドを使えます: `$compiler->colors()`、`$compiler->breakpoints()`、`$compiler->spacing()`。シグネチャの詳細は[API](https://tailwindphp.inline0.dev/ja/docs/api)をご覧ください。

## 次のステップ

- [ディレクティブ](https://tailwindphp.inline0.dev/ja/docs/usage/directives) — `@apply`、`@utility`、`@custom-variant`、`@layer`。
- [インポート](https://tailwindphp.inline0.dev/ja/docs/usage/imports) — `@import`、仮想モジュール、Preflight。
- [API](https://tailwindphp.inline0.dev/ja/docs/api) — すべてのアクセサーと検査メソッド。
