
# Arhitektura

TailwindPHP so vrata 1:1. Zbirka kode zrcali lastno strukturo TailwindCSS — enaka imena datotek, enaka organizacija — in izolira dele, ki *ne morejo* biti neposredna vratitev (PHP nima Rust niti V8), pod `src/_tailwindphp/`. Ta stran opisuje pot prevajanja, razporeditev izvorne kode, ponovno implementacijo `lightningcss` in dogovor za dokumentiranje odstopanj.

## Cevovod

Ustvarjanje CSS poteka v več stopnjah. Ločenega koraka gradnje ni — vsak klic `tw::generate()` izvede celotno pot.

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

**Razčlenjevanje.** `css-parser.php` prebere vhod CSS — `@import`, `@theme`, `@utility`, `@layer` in surova pravila — ter ga pretvori v abstraktno sintaksno drevo vozlišč `ast.php` (slogovna pravila, pravila at in deklaracije). Direktive `@import` za navidezne module (`tailwindcss`, `tailwindcss/preflight`, …) in poti do datotek so razrešene in nadomeščene v tej stopnji.

**Gradnja oblikovalskega sistema.** `theme.php` iz razčlenjenih blokov `@theme` in privzetih vrednosti razreši vrednosti teme (barve, razmike, prelomne točke). `design-system.php` je osrednji register, ki povezuje temo z iskanjem pripomočkov in različic, določenim v `utilities.php` in `variants.php`.

**Pregled vsebine.** `candidate.php` iz priložene vsebine (HTML, predloge) izlušči kandidate za imena razredov ter vsakega razčleni na dele — osnovni pripomoček, različice, modifikatorje, poljubne vrednosti in zastavico important.

**Prevajanje.** `compile.php` vsak kandidat pretvori v vozlišča AST tako, da ga poišče v oblikovalskem sistemu ter uporabi njegove različice in modifikatorje. Kandidati, ki ne ustrezajo pravemu pripomočku, so izpuščeni.

**Serializacija in optimizacija.** `toCss()` `ast.php` prehodi drevo (s pomočniki v `walk.php`) in izpiše niz CSS. Uporabijo se pretvorbe, enakovredne `lightningcss`, iz `_tailwindphp/LightningCss.php`, da se izhod ujema s tistim, ki ga TailwindCSS ustvari po koraku naknadne obdelave Rust.

**Minifikacija.** Ko je omogočen `minify`, `toCss()` med serializacijo izpiše minificirani CSS. Samostojno `tw::minify()` obdelavo niza zagotavlja `_tailwindphp/CssMinifier.php`. Glejte [Predpomnjenje in minifikacija](https://tailwindphp.inline0.dev/sl/docs/advanced/caching).

## Razporeditev izvorne kode

`src/` zrcali TailwindCSS. Edina strukturna sprememba: TailwindCSSov `utilities.ts` ima 6,000+ vrstic, zato je zaradi lažjega vzdrževanja razdeljen v `src/utilities/` z eno datoteko na kategorijo.

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

## Ustreznica za lightningcss

TailwindCSS naknadno obdelavo CSS — gnezdenje, obravnavo medijskih poizvedb in poenostavljanje vrednosti — prepušča [lightningcss](https://lightningcss.dev/), razčlenjevalniku, pretvorniku in minifikatorju, napisanemu v Rust. PHP ne more naložiti knjižnice Rust, zato `src/_tailwindphp/LightningCss.php` znova implementira pretvorbe, ki jih TailwindPHP dejansko uporablja, in ustvari povsem enak izhod za primere, ki jih pokriva nabor testov.

Potrjene pretvorbe vključujejo:

| Pretvorba | Kaj naredi |
|-----------|--------------|
| Sploščitev gnezdenja | Razreši izbirnike `&` po pravilih `:is(…)` referenčne izvedbe in splošči gnezdena pravila (`handleNesting()` v `ast.php`, vrata postopka TailwindCSS); `transformNesting` zniža raven preostalega gnezdenja pod prvo ravnjo, ki vsebuje deklaracije |
| Sploščitev pogojnih pravil at | Na mestu splošči gnezdena pravila `@media`, `@supports`, `@container` in `@starting-style`, pri tem ohrani izvorni vrstni red in združi le neposredno sosednje sorodne elemente z enakimi pogoji |
| Vrstni red deklaracij | Prerazporedi deklaracije glede na verigo obravnavalnikov deklaracij lightningcss, tako da se lastnosti izpišejo v referenčnem vrstnem redu (`reorderDeclarations`) |
| Poenostavitev `calc()` | Poenostavi izraze `calc()` (`simplifyCalcExpressions`) |
| Odstranjevanje začetnih ničel | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Razmiki v transformacijskih funkcijah | Normalizira razmike znotraj transformacijskih funkcij (`normalizeTransformFunctions`) |
| Normalizacija vrednosti mreže | Doda presledke okoli `/` v vrednostih span, gola cela števila pretvori v px za `grid-template-*` (`normalizeGridValues`) |
| Normalizacija barv | Normalizira zapis barv in izračuna `color-mix()` v `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| Narekovaji za URL | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Predpone ponudnikov | Predpone, enakovredne Autoprefixer (`addVendorPrefixes`) |

Ta datoteka je namenoma ločena pod `_tailwindphp/` in označena z `@port-deviation:replacement` — predstavlja zunanjo odvisnost, namesto da bi prenesla izvorno kodo TailwindCSS.

## Oznake odstopanj pri vratitvi

Vsaka implementacijska datoteka vsebuje oznake `@port-deviation:*` v svojem bloku docblock, ki pojasnjujejo, kje in zakaj implementacija PHP odstopa od izvirnika TypeScript. Bralec pri primerjanju PHP z izvorno kodo TailwindCSS tako nikoli ne ugiba, ali je razlika namerna.

| Oznaka | Pomen |
|--------|---------|
| `@port-deviation:none` | Neposredna vrata 1:1 brez pomembnih odstopanj |
| `@port-deviation:async` | PHP uporablja sinhrono kodo namesto async/await |
| `@port-deviation:storage` | Drugačne podatkovne strukture (polje PHP namesto Map/Set JS) |
| `@port-deviation:types` | Pripisi PHPDoc namesto tipov TypeScript |
| `@port-deviation:sourcemaps` | Sledenje izvornim preslikavam je izpuščeno |
| `@port-deviation:enum` | Konstante PHP namesto enumeracij TypeScript |
| `@port-deviation:errors` | Drugačen pristop k obravnavi napak |
| `@port-deviation:replacement` | Implementacija PHP nadomesti zunanjo knjižnico (e.g. lightningcss) |
| `@port-deviation:helper` | Pomožna funkcija, značilna za PHP, ki je ni v izvirniku |
| `@port-deviation:performance` | Optimizacija, značilna za PHP, ki ohrani enak izhod |
| `@port-deviation:omitted` | Celoten modul/funkcionalnost ni prenesen (zunaj obsega) |

Za oznake `@port-deviation:performance` in zagotavljanje enakovrednosti glejte [Zmogljivost in testiranje](https://tailwindphp.inline0.dev/sl/docs/advanced/performance).
