
# Architektura

TailwindPHP to port 1:1. Baza kodu odwzorowuje własną strukturę TailwindCSS — te same nazwy plików i ten sam układ — a części, których *nie da się* przenieść bezpośrednio (PHP nie ma Rust ani V8), izoluje w `src/_tailwindphp/`. Ta strona opisuje potok kompilacji, układ źródeł, ponowną implementację `lightningcss` oraz konwencję dokumentowania różnic.

## Potok przetwarzania

Generowanie CSS to sekwencja etapów. Nie ma osobnego etapu budowania — każde wywołanie `tw::generate()` uruchamia cały potok.

```
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
```

**Parsowanie.** `css-parser.php` odczytuje wejście CSS — `@import`, `@theme`, `@utility`, `@layer` i surowe reguły — do postaci abstrakcyjnego drzewa składniowego z węzłami `ast.php` (reguły stylów, reguły at i deklaracje). Dyrektywy `@import` dotyczące modułów wirtualnych (`tailwindcss`, `tailwindcss/preflight`, …) oraz ścieżki plików są rozwiązywane i podstawiane na tym etapie.

**Budowanie systemu projektowego.** `theme.php` rozwiązuje wartości motywu (kolory, odstępy, punkty przerwania) na podstawie sparsowanych bloków `@theme` i wartości domyślnych. `design-system.php` to centralny rejestr łączący motyw z wyszukiwaniem klas użytkowych i wariantów zdefiniowanym w `utilities.php` oraz `variants.php`.

**Skanowanie treści.** `candidate.php` wyodrębnia kandydatów na nazwy klas z dostarczonej treści (HTML, szablonów) i dzieli każdego na części — bazową klasę użytkową, warianty, modyfikatory, dowolne wartości oraz flagę important.

**Kompilacja.** `compile.php` przekształca każdego kandydata w węzły AST, wyszukując go w systemie projektowym i stosując warianty oraz modyfikatory. Kandydaci, którzy nie odpowiadają rzeczywistej klasie użytkowej, są odrzucani.

**Serializacja i optymalizacja.** `ast.php`'s `toCss()` przechodzi przez drzewo (z użyciem funkcji pomocniczych z `walk.php`) i generuje ciąg CSS. Stosowane są przekształcenia równoważne `lightningcss` z `_tailwindphp/LightningCss.php`, dzięki czemu wynik odpowiada temu, co generuje TailwindCSS po etapie przetwarzania końcowego Rust.

**Minifikacja.** Gdy minifikacja `minify` jest włączona, `toCss()` generuje zminifikowany CSS podczas serializacji. `_tailwindphp/CssMinifier.php` obsługuje samodzielny etap przetwarzania ciągu `tw::minify()`. Zobacz [Buforowanie i minifikacja](https://tailwindphp.inline0.dev/pl/docs/advanced/caching).

## Układ źródeł

`src/` odwzorowuje TailwindCSS. Jedyna zmiana strukturalna: TailwindCSS's `utilities.ts` ma 6,000+ wierszy, więc podzielono go na `src/utilities/` z osobnym plikiem dla każdej kategorii, aby ułatwić utrzymanie.

```
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
```

## Odpowiednik lightningcss

TailwindCSS zleca [lightningcss](https://lightningcss.dev/), parserowi, transformatorowi i minifikatorowi napisanemu w Rust, przetwarzanie końcowe CSS — obsługę zagnieżdżeń, zapytań medialnych i upraszczanie wartości. PHP nie może załadować biblioteki Rust, dlatego `src/_tailwindphp/LightningCss.php` ponownie implementuje przekształcenia, z których faktycznie korzysta TailwindPHP, generując identyczny wynik bajt po bajcie dla przypadków objętych zestawem testów.

Potwierdzone przekształcenia obejmują:

| Przekształcenie | Działanie |
|-----------|--------------|
| Spłaszczanie zagnieżdżeń | Rozwiązuje selektory `&` zgodnie z regułami `:is(…)` referencji i spłaszcza zagnieżdżone reguły (`handleNesting()` w `ast.php`, port etapu TailwindCSS); `transformNesting` obniża poziom zagnieżdżeń pozostających poniżej pierwszego poziomu zawierającego deklaracje |
| Spłaszczanie warunkowych reguł at | Spłaszcza zagnieżdżone `@media`, `@supports`, `@container` i `@starting-style` w miejscu ich wystąpienia, zachowując kolejność źródłową; łączy tylko bezpośrednio sąsiadujące elementy z identycznymi warunkami |
| Kolejność deklaracji | Zmienia kolejność deklaracji zgodnie z łańcuchem obsługi deklaracji lightningcss, aby właściwości pojawiały się w kolejności referencyjnej (`reorderDeclarations`) |
| Upraszczanie `calc()` | Upraszcza wyrażenia `calc()` (`simplifyCalcExpressions`) |
| Usuwanie zer wiodących | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Odstępy w funkcjach przekształceń | Normalizuje odstępy wewnątrz funkcji przekształceń (`normalizeTransformFunctions`) |
| Normalizacja wartości siatki | Dodaje spacje wokół `/` w wartościach span; zamienia same liczby całkowite na px dla `grid-template-*` (`normalizeGridValues`) |
| Normalizacja kolorów | Normalizuje składnię kolorów i oblicza `color-mix()` do postaci `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| Cytowanie URL | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Prefiksy dostawców | Dodawanie prefiksów równoważne Autoprefixer (`addVendorPrefixes`) |

Ten plik został celowo odizolowany w `_tailwindphp/` i oznaczony jako `@port-deviation:replacement` — zastępuje zewnętrzną zależność, zamiast przenosić kod źródłowy TailwindCSS.

## Oznaczenia różnic w porcie

Każdy plik implementacji zawiera w bloku dokumentacji oznaczenia `@port-deviation:*`, które wskazują, gdzie i dlaczego implementacja PHP różni się od oryginału TypeScript. Dzięki temu osoba porównująca PHP z kodem źródłowym TailwindCSS nie musi się zastanawiać, czy dana różnica jest zamierzona.

| Oznaczenie | Znaczenie |
|--------|---------|
| `@port-deviation:none` | Bezpośredni port 1:1 bez istotnych różnic |
| `@port-deviation:async` | PHP używa kodu synchronicznego zamiast async/await |
| `@port-deviation:storage` | Inne struktury danych (tablica PHP zamiast Map/Set JS) |
| `@port-deviation:types` | Adnotacje PHPDoc zamiast typów TypeScript |
| `@port-deviation:sourcemaps` | Pominięto śledzenie mapy źródłowej |
| `@port-deviation:enum` | Stałe PHP zamiast wyliczeń TypeScript |
| `@port-deviation:errors` | Inne podejście do obsługi błędów |
| `@port-deviation:replacement` | Implementacja PHP zastępująca zewnętrzną bibliotekę (e.g. lightningcss) |
| `@port-deviation:helper` | Funkcja pomocnicza specyficzna dla PHP, nieobecna w oryginale |
| `@port-deviation:performance` | Optymalizacja specyficzna dla PHP, która zachowuje identyczny wynik |
| `@port-deviation:omitted` | Cały moduł lub funkcja nie zostały przeniesione (poza zakresem) |

Więcej informacji o oznaczeniach `@port-deviation:performance` i zapewnianiu zgodności znajdziesz w sekcji [Wydajność i testowanie](https://tailwindphp.inline0.dev/pl/docs/advanced/performance).
