
# Arkkitehtuuri

TailwindPHP on 1:1-siirros. Koodikanta jäljittelee TailwindCSS:n omaa rakennetta — samat tiedostonimet ja sama järjestys — ja eristää osat, joita *ei* voi siirtää suoraan (PHP:sta puuttuvat Rust ja V8), hakemistoon `src/_tailwindphp/`. Tällä sivulla käydään läpi käännösputki, lähdekoodin hakemistorakenne, `lightningcss`-uudelleentoteutus ja poikkeamien dokumentointikäytäntö.

## Käsittelyputki

CSS:n generointi koostuu vaiheista. Erillistä koostamisvaihetta ei ole — jokainen `tw::generate()`-kutsu suorittaa koko putken.

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

**Jäsennä.** `css-parser.php` lukee CSS-syötteen — `@import`, `@theme`, `@utility`, `@layer` ja raakamuotoiset säännöt — `ast.php`-solmujen abstraktiksi syntaksipuuksi (tyylisäännöt, at-säännöt ja määritykset). `@import`-direktiivit virtuaalimoduuleille (`tailwindcss`, `tailwindcss/preflight`, …) ja tiedostopolut ratkaistaan ja korvataan tässä vaiheessa.

**Rakenna suunnittelujärjestelmä.** `theme.php` ratkaisee teeman arvot (värit, välit, katkaisukohdat) jäsennetyistä `@theme`-lohkoista ja oletusarvoista. `design-system.php` on keskeinen rekisteri, joka yhdistää teeman apuluokka- ja varianttihakuihin, jotka määritellään kohteissa `utilities.php` ja `variants.php`.

**Käy sisältö läpi.** `candidate.php` poimii luokkanimikandidaatit annetusta sisällöstä (HTML, mallit) ja jäsentää kunkin osiin — perusapuluokka, variantit, muokkaimet, mielivaltaiset arvot ja tärkeystunniste.

**Käännä.** `compile.php` muuntaa kunkin ehdokkaan syntaksipuun solmuiksi etsimällä sen suunnittelujärjestelmästä ja soveltamalla sen variantteja ja muokkaimia. Ehdokkaat, jotka eivät vastaa todellista apuluokkaa, hylätään.

**Sarjoita ja optimoi.** `ast.php`:n `toCss()` käy puun läpi (apufunktioilla kohteessa `walk.php`) ja tuottaa CSS-merkkijonon. `lightningcss`-vastineen muunnokset kohteessa `_tailwindphp/LightningCss.php` suoritetaan, jotta tulos vastaa sitä, mitä TailwindCSS tuottaa Rust-jälkikäsittelyvaiheen jälkeen.

**Pienennä.** Kun `minify` on käytössä, `toCss()` tuottaa sarjoituksen aikana pienennettyä CSS-koodia. `_tailwindphp/CssMinifier.php` toteuttaa erillisen `tw::minify()`-merkkijonovaiheen. Katso [Välimuisti ja pienennys](https://tailwindphp.inline0.dev/fi/docs/advanced/caching).

## Lähdekoodin rakenne

`src/` jäljittelee TailwindCSS:tä. Ainoa rakenteellinen muutos: TailwindCSS:n `utilities.ts` on yli 6,000 riviä pitkä, joten se on ylläpidettävyyden vuoksi jaettu kohteeseen `src/utilities/`, jossa on yksi tiedosto luokkaa kohden.

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

## lightningcssin vastine

TailwindCSS siirtää CSS-jälkikäsittelynsä — sisäkkäiset säännöt, mediakyselyjen käsittelyn ja arvojen yksinkertaistamisen — [lightningcss](https://lightningcss.dev/)-ohjelmalle, joka on Rust-kielellä kirjoitettu jäsennin, muunnin ja pienentäjä. PHP ei voi ladata Rust-kirjastoa, joten `src/_tailwindphp/LightningCss.php` toteuttaa uudelleen ne muunnokset, joita TailwindPHP todella käyttää. Näin saadaan tavutasolla identtinen tulos niissä tapauksissa, jotka testisarja kattaa.

Vahvistettuihin muunnoksiin kuuluvat:

| Muunnos | Mitä se tekee |
|-----------|--------------|
| Sisäkkäisyyden litistäminen | Ratkaisee `&`-valitsimet viitteen `:is(…)`-sääntöjen avulla ja litistää sisäkkäiset säännöt (`handleNesting()` kohteessa `ast.php`, siirros TailwindCSS-vaiheesta); `transformNesting` muuntaa ensimmäisen ilmoituksia sisältävän tason alle jäävän sisäkkäisyyden vanhempaa syntaksia käyttävään muotoon |
| Ehdollisten at-sääntöjen litistäminen | Litistää sisäkkäiset `@media`-, `@supports`-, `@container`- ja `@starting-style`-säännöt paikoilleen lähdejärjestyksen säilyttäen ja yhdistää vain suoraan vierekkäiset sisarukset, joilla on samat ehdot |
| Määritysten järjestäminen | Järjestää määritykset uudelleen lightningcssin määrityskäsittelijöiden ketjun mukaan, jotta ominaisuudet ovat viitteen mukaisessa järjestyksessä (`reorderDeclarations`) |
| `calc()`-yksinkertaistus | Yksinkertaistaa `calc()`-lausekkeita (`simplifyCalcExpressions`) |
| Alkunollien poistaminen | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Muunnosfunktioiden välilyönnit | Yhtenäistää muunnosfunktioiden sisäiset välilyönnit (`normalizeTransformFunctions`) |
| Ruudukkoarvojen normalisointi | Lisää välilyönnit `/`-merkin ympärille span-arvoissa ja muuntaa paljaat kokonaisluvut px-arvoiksi kohteessa `grid-template-*` (`normalizeGridValues`) |
| Värien normalisointi | Yhtenäistää värien syntaksin ja laskee `color-mix()`-arvon muotoon `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| URL-lainausmerkit | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Valmistajakohtaiset etuliitteet | Autoprefixer-vastaavat etuliitteet (`addVendorPrefixes`) |

Tämä tiedosto on tarkoituksella eristetty hakemistoon `_tailwindphp/` ja merkitty tunnisteella `@port-deviation:replacement` — se edustaa ulkoista riippuvuutta sen sijaan, että TailwindCSS-lähdekoodi siirrettäisiin.

## Siirroksen poikkeamamerkit

Jokaisen toteutustiedoston dokumentointilohkossa on `@port-deviation:*`-merkkejä, jotka kertovat, missä ja miksi PHP-toteutus poikkeaa alkuperäisestä TypeScript-versiosta. Näin PHP- ja TailwindCSS-lähdekoodia vertailevan lukijan ei tarvitse arvailla, onko ero tarkoituksellinen.

| Merkki | Merkitys |
|--------|---------|
| `@port-deviation:none` | Suora 1:1-siirros, jossa ei ole merkittäviä poikkeamia |
| `@port-deviation:async` | PHP käyttää synkronista koodia async/await-rakenteen sijaan |
| `@port-deviation:storage` | Tietorakenteet eroavat (PHP-taulukko vastaan JS-Map/Set) |
| `@port-deviation:types` | PHPDoc-merkinnät tyyppien TypeScript sijaan |
| `@port-deviation:sourcemaps` | Lähdekartan seuranta jätetty pois |
| `@port-deviation:enum` | PHP-vakiot TypeScript-enumien sijaan |
| `@port-deviation:errors` | Erilainen virheenkäsittelytapa |
| `@port-deviation:replacement` | PHP-toteutus korvaa ulkoisen kirjaston (e.g. lightningcss) |
| `@port-deviation:helper` | PHP-kohtainen apufunktio, jota alkuperäisessä ei ole |
| `@port-deviation:performance` | PHP-kohtainen optimointi, joka säilyttää saman tulosteen |
| `@port-deviation:omitted` | Koko moduulia tai ominaisuutta ei ole siirretty (ei kuulu laajuuteen) |

Katso `@port-deviation:performance`-merkkien ja vastaavuuden valvonnan kuvaus kohdasta [Suorituskyky ja testaus](https://tailwindphp.inline0.dev/fi/docs/advanced/performance).
