
# Arsitektur

TailwindPHP adalah port 1:1. Basis kode mencerminkan struktur milik TailwindCSS sendiri — nama file dan pengorganisasian yang sama — serta mengisolasi bagian yang *tidak dapat* di-port langsung (PHP tidak memiliki Rust maupun V8) di bawah `src/_tailwindphp/`. Halaman ini menjelaskan alur kompilasi, tata letak sumber, implementasi ulang `lightningcss`, dan konvensi untuk mendokumentasikan penyimpangan.

## Pipeline

Pembuatan CSS terdiri dari serangkaian tahap. Tidak ada langkah build terpisah — setiap pemanggilan `tw::generate()` menjalankan seluruh alur.

```
CSS input          (@import "tailwindcss"; @theme { … })
  │
  ▼
┌──────────────┐
│  Parse CSS   │  css-parser.php → ast.php nodes
└──────┬───────┘
       ▼  design system (theme, utilities, variants)
┌──────────────┐
│ Scan content │  candidate.php — extract class names from HTML
└──────┬───────┘
       ▼  candidates
┌──────────────┐
│   Compile    │  compile.php — candidate → AST, via design-system.php
└──────┬───────┘
       ▼  AST
┌──────────────┐
│   Optimize   │  _tailwindphp/LightningCss.php — nesting, @media, calc()
└──────┬───────┘
       ▼
┌──────────────┐
│  Serialize   │  ast.php toCss()   (minified when requested)
└──────┬───────┘
       ▼
CSS output
```

**Parsing.** `css-parser.php` membaca masukan CSS — `@import`, `@theme`, `@utility`, `@layer`, aturan mentah — menjadi pohon sintaks abstrak yang terdiri dari node `ast.php` (aturan gaya, at-rule, deklarasi). Direktif `@import` untuk modul virtual (`tailwindcss`, `tailwindcss/preflight`, …) dan jalur file diselesaikan dan disubstitusikan pada tahap ini.

**Membangun sistem desain.** `theme.php` menyelesaikan nilai tema (warna, jarak, breakpoint) dari blok `@theme` yang telah diurai beserta nilai default. `design-system.php` adalah registri pusat yang menghubungkan tema dengan pencarian utilitas dan varian yang ditentukan dalam `utilities.php` dan `variants.php`.

**Memindai konten.** `candidate.php` mengekstrak kandidat nama kelas dari konten yang diberikan (HTML, templat), lalu menguraikan setiap kandidat menjadi bagian-bagiannya — utilitas dasar, varian, modifier, nilai arbitrer, dan penanda important.

**Mengompilasi.** `compile.php` mengubah setiap kandidat menjadi node AST dengan mencarinya dalam sistem desain, lalu menerapkan varian dan modifier-nya. Kandidat yang tidak cocok dengan utilitas sungguhan akan dibuang.

**Menyerialisasi dan mengoptimalkan.** `ast.php` milik `toCss()` menelusuri pohon (dengan helper di `walk.php`) dan menghasilkan string CSS. Transformasi setara `lightningcss` di `_tailwindphp/LightningCss.php` diterapkan agar hasilnya cocok dengan keluaran TailwindCSS setelah tahap pascapemrosesan Rust.

**Minifikasi.** Saat `minify` diaktifkan, `toCss()` menghasilkan CSS yang diminifikasi selama serialisasi. `_tailwindphp/CssMinifier.php` mendukung tahap pemrosesan string mandiri `tw::minify()`. Lihat [Caching & minifikasi](https://tailwindphp.inline0.dev/id/docs/advanced/caching).

## Tata letak sumber

`src/` mencerminkan TailwindCSS. Satu perubahan strukturalnya: TailwindCSS memiliki `utilities.ts` sebanyak 6,000+ baris, jadi dipecah menjadi `src/utilities/` dengan satu file per kategori agar mudah dipelihara.

```
src/
├── _tailwindphp/                # PHP-specific — NOT part of the TailwindCSS port
│   ├── LightningCss.php         # CSS transforms (lightningcss Rust library equivalent)
│   ├── CssMinifier.php          # CSS minification
│   └── lib/                     # Companion library ports (TailwindPHP\Lib\*)
│       ├── clsx/                # clsx port
│       ├── tailwind-merge/      # tailwind-merge port
│       └── cva/                 # CVA port
│
├── plugin/                      # Plugin system
│   └── plugins/
│       ├── typography-plugin.php  # @tailwindcss/typography port
│       └── forms-plugin.php       # @tailwindcss/forms port
│
├── utilities/                   # Split from TailwindCSS utilities.ts (one file per category)
│   ├── accessibility.php        # sr-only, forced-colors
│   ├── backgrounds.php          # bg-*, gradient-*, from-*, via-*, to-*
│   ├── borders.php              # border-*, rounded-*, divide-*, outline-*
│   ├── effects.php              # shadow-*, opacity-*, mix-blend-*
│   ├── filters.php              # blur-*, brightness-*, contrast-*, …
│   ├── flexbox.php              # flex-*, grid-*, gap-*, justify-*, align-*
│   ├── interactivity.php        # cursor-*, scroll-*, touch-*, select-*
│   ├── layout.php               # display, position, z-*, overflow-*, …
│   ├── masks.php                # mask-linear-*, mask-radial-*, mask-conic-*
│   ├── sizing.php               # w-*, h-*, min-*, max-*, size-*
│   ├── spacing.php              # m-*, p-*, space-*
│   ├── svg.php                  # fill-*, stroke-*
│   ├── tables.php               # border-collapse, table-layout
│   ├── transforms.php           # translate-*, rotate-*, scale-*, skew-*
│   ├── transitions.php          # transition-*, duration-*, ease-*, delay-*
│   └── typography.php           # font-*, text-*, leading-*, tracking-*
│
├── utils/                       # Helper functions (ported from utils/)
│
├── index.php                    # Main entry — compile(), cn(), variants(), merge(), join()
├── ast.php                      # AST nodes and toCss()
├── candidate.php                # Candidate parsing (class name → parts)
├── compile.php                  # Candidate to CSS compilation
├── css-functions.php            # theme(), --theme(), --spacing(), --alpha()
├── css-parser.php               # CSS parsing
├── design-system.php            # Central registry for utilities/variants
├── plugin.php                   # Plugin system (PluginInterface, PluginAPI, PluginManager)
├── theme.php                    # Theme value resolution
├── utilities.php                # Utility registration and lookup
├── value-parser.php             # CSS value parsing
├── variants.php                 # Variant handling (hover, focus, responsive, …)
└── walk.php                     # AST traversal
```

## Padanan lightningcss

TailwindCSS menyerahkan pascapemrosesan CSS—nesting, penanganan media query, penyederhanaan nilai—kepada [lightningcss](https://lightningcss.dev/), parser/transformer/minifier yang ditulis dalam Rust. PHP tidak dapat memuat pustaka Rust, jadi `src/_tailwindphp/LightningCss.php` mengimplementasikan ulang transformasi yang benar-benar digunakan TailwindPHP, sehingga menghasilkan keluaran yang identik byte demi byte untuk kasus yang dicakup rangkaian pengujian.

Transformasi yang dikonfirmasi mencakup:

| Transformasi | Fungsinya |
|-----------|--------------|
| Perataan nesting | Menyelesaikan selector `&` dengan aturan `:is(…)` dari referensi, lalu meratakan aturan yang bersarang (`handleNesting()` dalam `ast.php`, port dari tahap TailwindCSS); `transformNesting` menurunkan level nesting yang tersisa di bawah level pertama yang memuat deklarasi |
| Perataan at-rule bersyarat | Meratakan `@media`, `@supports`, `@container`, dan `@starting-style` yang bersarang di tempatnya, mempertahankan urutan sumber, dan hanya menggabungkan sibling yang berdekatan langsung dengan kondisi identik |
| Pengurutan deklarasi | Mengurutkan ulang deklarasi sesuai rantai penangan deklarasi lightningcss, sehingga properti mengikuti urutan referensi (`reorderDeclarations`) |
| Penyederhanaan `calc()` | Menyederhanakan ekspresi `calc()` (`simplifyCalcExpressions`) |
| Penghapusan nol di depan | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Spasi fungsi transform | Menormalkan spasi di dalam fungsi transform (`normalizeTransformFunctions`) |
| Normalisasi nilai grid | Menambahkan spasi di sekitar `/` pada nilai span, integer tanpa satuan → px untuk `grid-template-*` (`normalizeGridValues`) |
| Normalisasi warna | Menormalkan sintaks warna dan mengevaluasi `color-mix()` menjadi `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| Pengutipan URL | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Prefiks vendor | Penambahan prefiks setara dengan Autoprefixer (`addVendorPrefixes`) |

File ini sengaja dikarantina di bawah `_tailwindphp/` dan ditandai `@port-deviation:replacement`—file ini berfungsi sebagai pengganti dependensi eksternal, bukan mem-porting sumber TailwindCSS.

## Penanda penyimpangan port

Setiap file implementasi memuat penanda `@port-deviation:*` dalam docblock yang menjelaskan di mana dan mengapa implementasi PHP menyimpang dari versi asli TypeScript. Tujuannya agar pembaca yang membandingkan PHP dengan sumber TailwindCSS tidak perlu bertanya-tanya apakah suatu perbedaan memang disengaja.

| Penanda | Arti |
|--------|---------|
| `@port-deviation:none` | Port langsung 1:1 tanpa penyimpangan signifikan |
| `@port-deviation:async` | PHP menggunakan kode sinkron alih-alih async/await |
| `@port-deviation:storage` | Struktur data berbeda (array PHP dibanding Map/Set JS) |
| `@port-deviation:types` | Anotasi PHPDoc alih-alih tipe TypeScript |
| `@port-deviation:sourcemaps` | Pelacakan source map dihilangkan |
| `@port-deviation:enum` | Konstanta PHP alih-alih enum TypeScript |
| `@port-deviation:errors` | Pendekatan penanganan error berbeda |
| `@port-deviation:replacement` | Implementasi PHP menggantikan pustaka eksternal (e.g. lightningcss) |
| `@port-deviation:helper` | Helper khusus PHP yang tidak ada di versi asli |
| `@port-deviation:performance` | Optimasi khusus PHP yang mempertahankan keluaran identik |
| `@port-deviation:omitted` | Seluruh modul/fitur tidak di-porting (di luar cakupan) |

Untuk penanda `@port-deviation:performance` dan cara memastikan kesetaraan, lihat [Pengujian & performa](https://tailwindphp.inline0.dev/id/docs/advanced/performance).
