
# Arkitektur

TailwindPHP är en portning till 1:1. Kodbasen speglar TailwindCSSs egen struktur — samma filnamn, samma organisation — och isolerar delarna som *inte* kan porteras direkt (PHP har ingen Rust och ingen V8) under `src/_tailwindphp/`. Den här sidan går igenom kompileringspipelinen, källkodens struktur, `lightningcss`-omimplementeringen och konventionen för att dokumentera avvikelser.

## Flödet

Generering av CSS sker i flera steg. Det finns inget separat byggsteg — varje anrop till `tw::generate()` kör hela pipelinen.

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

**Parsa.** `css-parser.php` läser indata i CSS — `@import`, `@theme`, `@utility`, `@layer` och råa regler — till ett abstrakt syntaxträd med `ast.php`-noder (stilregler, at-regler, deklarationer). `@import`-direktiv för virtuella moduler (`tailwindcss`, `tailwindcss/preflight`, …) och filsökvägar löses och ersätts i detta steg.

**Bygg designsystemet.** `theme.php` löser temavärden (färger, avstånd, brytpunkter) från de parsade `@theme`-blocken och standardvärdena. `design-system.php` är det centrala registret som kopplar temat till uppslagningarna för verktyg och varianter i `utilities.php` och `variants.php`.

**Skanna innehåll.** `candidate.php` extraherar kandidater för klassnamn från det angivna innehållet (HTML, mallar) och delar upp varje kandidat i sina delar — basverktyg, varianter, modifierare, godtyckliga värden och flaggan important.

**Kompilera.** `compile.php` omvandlar varje kandidat till AST-noder genom att slå upp den i designsystemet och tillämpa dess varianter och modifierare. Kandidater som inte motsvarar ett verkligt verktyg tas bort.

**Serialisera och optimera.** `ast.php`s `toCss()` går igenom trädet (med hjälpfunktioner i `walk.php`) och genererar strängen CSS. Transformationerna motsvarande `lightningcss` i `_tailwindphp/LightningCss.php` tillämpas så att resultatet matchar det som TailwindCSS genererar efter sitt efterbehandlingssteg med Rust.

**Minifiera.** När `minify` är aktiverat genererar `toCss()` minifierad CSS under serialiseringen. `_tailwindphp/CssMinifier.php` hanterar den fristående strängpasseringen för `tw::minify()`. Se [Cachelagring och minifiering](https://tailwindphp.inline0.dev/sv/docs/advanced/caching).

## Källkodens struktur

`src/` speglar TailwindCSS. Den enda strukturella ändringen: TailwindCSSs `utilities.ts` har 6,000+ rader och delas därför upp i `src/utilities/` med en fil per kategori för enklare underhåll.

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

## Motsvarigheten till lightningcss

TailwindCSS delegerar sin efterbehandling av CSS — nästling, hantering av mediefrågor och förenkling av värden — till [lightningcss](https://lightningcss.dev/), en parser/transformerare/minifierare skriven i Rust. PHP kan inte läsa in ett Rust-bibliotek, så `src/_tailwindphp/LightningCss.php` implementerar på nytt de transformationer som TailwindPHP faktiskt använder. Resultatet blir identiskt byte för byte i de fall som testsviten omfattar.

Bekräftade transformationer omfattar:

| Transformation | Vad den gör |
|-----------|--------------|
| Utplattning av nästling | Löser `&`-selektorer med referensens `:is(…)`-regler och plattar till nästlade regler (`handleNesting()` i `ast.php`, en portning av TailwindCSS-passeringen); `transformNesting` konverterar den nästling som återstår under den första nivån med deklarationer till äldre syntax |
| Utplattning av villkorliga at-regler | Plattar till nästlade `@media`, `@supports`, `@container` och `@starting-style` på plats, bevarar källordningen och slår endast ihop direkt intilliggande syskon med identiska villkor |
| Deklarationsordning | Ordnar om deklarationer enligt lightningcss-kedjan för deklarationshantering, så att egenskaperna följer referensens ordning (`reorderDeclarations`) |
| Förenkling av `calc()` | Förenklar `calc()`-uttryck (`simplifyCalcExpressions`) |
| Borttagning av inledande nolla | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Mellanslag i transformationsfunktioner | Normaliserar mellanslag inuti transformationsfunktioner (`normalizeTransformFunctions`) |
| Normalisering av grid-värden | Lägger till mellanslag runt `/` i span-värden; omvandlar rena heltal till px för `grid-template-*` (`normalizeGridValues`) |
| Färgnormalisering | Normaliserar färgsyntax och utvärderar `color-mix()` till `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| Citering av URL | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Leverantörsprefix | Prefixning motsvarande Autoprefixer (`addVendorPrefixes`) |

Den här filen ligger avsiktligt i karantän under `_tailwindphp/` och är markerad `@port-deviation:replacement` — den står för ett externt beroende i stället för att porta källkod från TailwindCSS.

## Markörer för portningsavvikelser

Varje implementeringsfil har `@port-deviation:*`-markörer i sitt docblock som anger var och varför PHP-implementationen avviker från originalet i TypeScript. Målet är att den som jämför PHP med källkoden i TailwindCSS aldrig ska behöva undra om en skillnad är avsiktlig.

| Markör | Betydelse |
|--------|---------|
| `@port-deviation:none` | Direkt portning av 1:1 utan betydande avvikelser |
| `@port-deviation:async` | PHP använder synkron kod i stället för async/await |
| `@port-deviation:storage` | Andra datastrukturer (array i PHP jämfört med Map/Set i JS) |
| `@port-deviation:types` | PHPDoc-anteckningar i stället för typer i TypeScript |
| `@port-deviation:sourcemaps` | Spårning av källkartor utelämnad |
| `@port-deviation:enum` | Konstanter i PHP i stället för enum-typer i TypeScript |
| `@port-deviation:errors` | Annat sätt att hantera fel |
| `@port-deviation:replacement` | PHP-implementation som ersätter ett externt bibliotek (e.g. lightningcss) |
| `@port-deviation:helper` | Hjälpfunktion specifik för PHP som saknas i originalet |
| `@port-deviation:performance` | Optimering specifik för PHP som bevarar identiska resultat |
| `@port-deviation:omitted` | Hela modulen/funktionen har inte porterats (utanför omfattningen) |

Se [Prestanda och testning](https://tailwindphp.inline0.dev/sv/docs/advanced/performance) för information om `@port-deviation:performance`-markörerna och hur likvärdighet säkerställs.
