
# Tema & Penyesuaian

Tema Tailwind berupa kumpulan variabel CSS datar. Anda dapat memperluas atau menggantinya dengan blok `@theme { … }` di CSS input Anda, merujuk nilai tersebut dari dalam CSS melalui fungsi tema, dan membaca kembali nilai yang telah diselesaikan dari PHP. Tidak ada file konfigurasi JavaScript — tema sepenuhnya berada di CSS.

## Blok `@theme`

Blok `@theme` mendeklarasikan token desain sebagai properti kustom CSS. Prefiks namespace pada tiap variabel (`--color-*`, `--font-*`, `--breakpoint-*`, `--spacing-*`, …) memberi tahu Tailwind utilitas dan varian mana yang menggunakan token tersebut.

```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;
    }
');
```

Setiap token mendaftarkan utilitas dalam namespace-nya. Contoh di atas membuat `bg-brand`, `text-brand`, `border-brand`, keluarga `font-heading`, varian responsif `xs:`, serta spasi `p-huge`/`m-huge` tersedia — hanya dibuat ketika kelas tersebut muncul dalam konten Anda.

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

Token `--breakpoint-xs` mendaftarkan varian `xs:` secara langsung:

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

### Namespace umum

| Namespace | Menghasilkan |
|-----------|-------|
| `--color-*` | `bg-*`, `text-*`, `border-*`, `fill-*`, `stroke-*`, … |
| `--font-*` | Utilitas keluarga `font-*` |
| `--text-*` | Utilitas ukuran font `text-*` |
| `--breakpoint-*` | Varian responsif (`sm:`, `md:`, `xs:` kustom) |
| `--spacing-*` | Nilai spasi bernama (`p-huge`, `m-huge`) |
| `--radius-*` | Utilitas `rounded-*` |
| `--shadow-*` | Utilitas `shadow-*` |

### Menghapus namespace

Mengatur wildcard namespace ke `initial` menghapus default Tailwind untuk namespace tersebut sebelum token Anda sendiri ditambahkan. Dengan begitu, Anda dapat memulai dari palet kosong:

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

`--*: initial;` menghapus seluruh tema. Satu nilai `initial` pada kunci non-wildcard (`--color-red-500: initial;`) hanya menghapus satu token tersebut. Hanya `initial` yang diterima sebagai nilai untuk wildcard `-*` — nilai lainnya akan menyebabkan kesalahan.

## Membaca nilai tema di CSS

### `theme()`

Fungsi lama `theme()` membaca nilai menggunakan notasi titik berdasarkan namespace bergaya v3. Fungsi ini menyelesaikan nilai token saat kompilasi, sehingga dapat digunakan di mana pun nilai diperlukan — termasuk dalam aturan kustom dan deklarasi lainnya.

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

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

Jalur titik memetakan ke variabel yang mendasarinya (`colors.red.500` → `--color-red-500`, `fontFamily.sans` → keluarga sans). Modifier opasitas didukung: `theme(colors.red.500 / 50%)`. Nilai fallback dapat diberikan sebagai argumen kedua: `theme(colors.brand, #000)`. Jika jalur tidak dapat diresolusikan dan tidak ada fallback, kandidat yang menggunakannya akan dihapus.

### `--theme()`

`--theme()` membaca variabel tema berdasarkan nama properti kustom CSS dan secara default mengembalikan referensi `var()`, sehingga nilainya tetap dapat ditimpa saat runtime:

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

Tambahkan `inline` untuk menyisipkan nilai yang telah diresolusikan alih-alih referensi `var()`: `--theme(--color-brand inline)`. Argumen kedua adalah nilai fallback (`--theme(--color-brand, #000)`), dan fallback `initial` ditangani secara khusus — nilainya disisipkan ke dalam referensi `var()` bertingkat yang juga diresolusikan menjadi `initial`. Di dalam at-rule (`@media`, `@container`), `--theme()` selalu diresolusikan secara inline karena `var()` tidak valid dalam prelude tersebut.

### `--spacing()`

`--spacing(n)` mengalikan unit spasi dasar tema (`--spacing`) dengan `n`:

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

Pengali `1` diresolusikan menjadi variabel dasar itu sendiri (`--spacing(1)` → `var(--spacing)`, sama seperti yang dihasilkan `p-1`), sedangkan `0` menjadi panjang nol biasa.

Ini adalah perhitungan yang sama dengan yang digunakan utilitas spasi bawaan, sehingga nilai kustom tetap konsisten dengan `p-4`, `m-4`, dan lainnya.

### `--alpha()`

`--alpha(color / opacity)` menerapkan opasitas pada warna menggunakan `color-mix()` dalam ruang warna oklab:

```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);
  }
}
```

Bentuk `color-mix()` tetap dapat ditimpa saat runtime; fallback statis sebelumnya, yang dihitung dari nilai tema, mencakup browser yang tidak mendukung `color-mix()`. Nonaktifkan fallback dengan opsi `polyfills` pada [`tw::compile()`](https://tailwindphp.inline0.dev/id/docs/api#twcompile).

### Menumpuk opasitas dan `color-mix()` → `oklab()`

Modifier opasitas dapat digabungkan. Menerapkan 50% pada nilai yang sudah memiliki opasitas 50% menghasilkan 25%, dihitung dalam oklab. Saat modifier opasitas diresolusikan terhadap warna statis, TailwindPHP menyederhanakan ekspresi `color-mix(in oklab, …)` menjadi nilai `oklab()` konkret — konversi yang sama dengan yang dilakukan lightningcss pada toolchain Tailwind upstream — sedangkan warna dinamis (yang masih dibungkus dalam `var()`) mempertahankan bentuk `color-mix()` agar tetap dapat ditimpa saat runtime.

## Membaca nilai tema dari PHP

Tiga accessor mengembalikan nilai tema yang telah diresolusikan sebagai array PHP. Masing-masing menerima string input CSS opsional (default `@import "tailwindcss";`) dan juga tersedia pada instance [compiler](https://tailwindphp.inline0.dev/id/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']
```

Berikan string CSS untuk membaca berdasarkan tema yang dikustomisasi:

```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 menggunakan satu nilai dasar `--spacing`, bukan skala `--spacing-*`, sehingga `tw::spacing()` hanya mengembalikan token `--spacing-*` kustom yang Anda definisikan. Metode yang sama juga tersedia dari instance compiler: `$compiler->colors()`, `$compiler->breakpoints()`, `$compiler->spacing()`. Lihat [API](https://tailwindphp.inline0.dev/id/docs/api) untuk signature lengkap.

## Langkah berikutnya

- [Direktif](https://tailwindphp.inline0.dev/id/docs/usage/directives) — `@apply`, `@utility`, `@custom-variant`, `@layer`.
- [Impor](https://tailwindphp.inline0.dev/id/docs/usage/imports) — `@import`, modul virtual, dan Preflight.
- [API](https://tailwindphp.inline0.dev/id/docs/api) — setiap accessor dan metode inspeksi.
