
# Architettura

TailwindPHP è una portabilità 1:1. La codebase rispecchia la struttura originale di TailwindCSS: stessi nomi di file e stessa organizzazione; le parti che *non possono* essere portate direttamente (PHP non ha Rust né V8) sono isolate sotto `src/_tailwindphp/`. Questa pagina illustra la pipeline di compilazione, l'organizzazione dei sorgenti, la reimplementazione di `lightningcss` e la convenzione usata per documentare le differenze.

## La pipeline

La generazione di CSS è una sequenza di fasi. Non c'è un passaggio di build separato: ogni chiamata a `tw::generate()` esegue l'intera pipeline.

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

**Analisi.** `css-parser.php` legge l'input CSS: `@import`, `@theme`, `@utility`, `@layer`, regole raw; e lo trasforma in un albero sintattico astratto composto da nodi `ast.php` (regole di stile, at-rule, dichiarazioni). In questa fase vengono risolte e sostituite le direttive `@import` per i moduli virtuali (`tailwindcss`, `tailwindcss/preflight`, …) e i percorsi dei file.

**Costruzione del sistema di design.** `theme.php` risolve i valori del tema (colori, spaziatura, breakpoint) dai blocchi `@theme` analizzati e dai valori predefiniti. `design-system.php` è il registro centrale che collega il tema alle definizioni di utilità e varianti in `utilities.php` e `variants.php`.

**Scansione dei contenuti.** `candidate.php` estrae i candidati per i nomi delle classi dai contenuti forniti (HTML, template) e scompone ciascuno nelle sue parti: utilità di base, varianti, modificatori, valori arbitrari e flag important.

**Compilazione.** `compile.php` converte ogni candidato in nodi AST cercandolo nel sistema di design e applicando varianti e modificatori. I candidati che non corrispondono a un'utilità reale vengono scartati.

**Serializzazione e ottimizzazione.** `ast.php` percorre l'albero con il suo `toCss()` (helper in `walk.php`) e genera la stringa CSS. Vengono applicate in `_tailwindphp/LightningCss.php` le trasformazioni equivalenti a `lightningcss`, così l'output corrisponde a quello prodotto da TailwindCSS dopo il passaggio di post-elaborazione Rust.

**Minificazione.** Quando `minify` è abilitato, `toCss()` genera CSS minificato durante la serializzazione. `_tailwindphp/CssMinifier.php` gestisce il passaggio autonomo sulla stringa `tw::minify()`. Consultate [Cache e minificazione](https://tailwindphp.inline0.dev/it/docs/advanced/caching).

## Organizzazione dei sorgenti

`src/` rispecchia TailwindCSS. L'unica modifica strutturale: TailwindCSS`utilities.ts` contiene più di 6,000 righe, quindi è suddiviso in `src/utilities/`, con un file per categoria, per facilitarne la manutenzione.

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

## L'equivalente di lightningcss

TailwindCSS delega a [lightningcss](https://lightningcss.dev/), un parser/trasformatore/minificatore scritto in Rust, la post-elaborazione di CSS: annidamento, gestione delle media query e semplificazione dei valori. PHP non può caricare una libreria Rust, quindi `src/_tailwindphp/LightningCss.php` reimplementa le trasformazioni su cui TailwindPHP fa effettivamente affidamento, producendo un output identico byte per byte nei casi coperti dalla suite di test.

Trasformazioni confermate:

| Trasformazione | Cosa fa |
|-----------|--------------|
| Appiattimento dell'annidamento | Risolve i selettori `&` con le regole `:is(…)` di riferimento e appiattisce le regole annidate (`handleNesting()` in `ast.php`, port dell'elaborazione TailwindCSS); `transformNesting` riduce il livello delle regole annidate rimaste sotto il primo livello che contiene dichiarazioni |
| Appiattimento delle regole at-rule condizionali | Appiattisce sul posto le regole `@media`, `@supports`, `@container` e `@starting-style` annidate, mantenendo l'ordine del sorgente e unendo solo i fratelli direttamente adiacenti con condizioni identiche |
| Ordinamento delle dichiarazioni | Riordina le dichiarazioni secondo la catena di gestione delle dichiarazioni di lightningcss, così le proprietà seguono l'ordine di riferimento (`reorderDeclarations`) |
| Semplificazione di `calc()` | Semplifica le espressioni `calc()` (`simplifyCalcExpressions`) |
| Rimozione degli zeri iniziali | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Spaziatura delle funzioni di trasformazione | Normalizza gli spazi all'interno delle funzioni di trasformazione (`normalizeTransformFunctions`) |
| Normalizzazione dei valori della griglia | Aggiunge spazi intorno a `/` nei valori span; converte gli interi senza unità in px per `grid-template-*` (`normalizeGridValues`) |
| Normalizzazione dei colori | Normalizza la sintassi dei colori e valuta `color-mix()` in `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| Virgolette per URL | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Prefissi dei vendor | Aggiunge prefissi equivalenti a Autoprefixer (`addVendorPrefixes`) |

Questo file è intenzionalmente isolato sotto `_tailwindphp/` e contrassegnato come `@port-deviation:replacement`: funge da dipendenza esterna invece di portare il sorgente di TailwindCSS.

## Marcatori delle differenze del port

Ogni file di implementazione contiene marcatori `@port-deviation:*` nel docblock che indicano dove e perché l'implementazione PHP si discosta dall'originale TypeScript. L'obiettivo è consentire a chi confronta PHP con il sorgente di TailwindCSS di capire subito se una differenza è intenzionale.

| Marcatore | Significato |
|--------|---------|
| `@port-deviation:none` | Port diretto 1:1 senza differenze significative |
| `@port-deviation:async` | PHP usa codice sincrono invece di async/await |
| `@port-deviation:storage` | Strutture dati diverse (array PHP invece di Map/Set JS) |
| `@port-deviation:types` | Annotazioni PHPDoc invece dei tipi TypeScript |
| `@port-deviation:sourcemaps` | Tracciamento delle source map omesso |
| `@port-deviation:enum` | Costanti PHP invece di enum TypeScript |
| `@port-deviation:errors` | Approccio diverso alla gestione degli errori |
| `@port-deviation:replacement` | Implementazione PHP che sostituisce una libreria esterna (e.g. lightningcss) |
| `@port-deviation:helper` | Helper specifico di PHP, non presente nell'originale |
| `@port-deviation:performance` | Ottimizzazione specifica di PHP che mantiene un output identico |
| `@port-deviation:omitted` | Modulo/funzionalità non portato/a (fuori ambito) |

Per i marcatori `@port-deviation:performance` e il modo in cui viene garantita la parità, consultate [Prestazioni e test](https://tailwindphp.inline0.dev/it/docs/advanced/performance).
