
# Arkitektur

TailwindPHP er en 1:1-portering. Kodebasen afspejler TailwindCSSs egen struktur — samme filnavne, samme organisering — og isolerer de dele, der *ikke* kan porteres direkte (PHP har ingen Rust og ingen V8), under `src/_tailwindphp/`. Denne side gennemgår kompileringspipelinen, kildelayoutet, genimplementeringen af `lightningcss` og konventionen for dokumentation af afvigelser.

## Pipelineforløbet

Generering af CSS består af en række trin. Der er intet separat buildtrin — hvert kald til `tw::generate()` kører hele 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
```

**Parse.** `css-parser.php` læser CSS-inputtet — `@import`, `@theme`, `@utility`, `@layer` og rå regler — ind i et abstrakt syntakstræ med `ast.php`-noder (stilregler, at-regler, deklarationer). `@import`-direktiver for virtuelle moduler (`tailwindcss`, `tailwindcss/preflight`, …) og filstier afklares og indsættes på dette trin.

**Byg designsystemet.** `theme.php` afklarer temaværdier (farver, afstande, brudpunkter) fra de fortolkede `@theme`-blokke plus standardværdierne. `design-system.php` er det centrale register, der forbinder temaet med opslagene for værktøjer og varianter, som defineres i `utilities.php` og `variants.php`.

**Scan indhold.** `candidate.php` udtrækker kandidater til klassenavne fra det angivne indhold (HTML, skabeloner) og opdeler hver kandidat i dens dele — basisværktøj, varianter, modifikatorer, vilkårlige værdier og vigtigt-flag.

**Kompilér.** `compile.php` omdanner hver kandidat til AST-noder ved at slå den op i designsystemet og anvende dens varianter og modifikatorer. Kandidater, der ikke svarer til et reelt værktøj, kasseres.

**Serialisér og optimér.** `ast.php`s `toCss()` gennemløber træet (hjælpefunktioner i `walk.php`) og udsender CSS-strengen. Transformationerne svarende til `lightningcss` i `_tailwindphp/LightningCss.php` anvendes, så outputtet matcher det, TailwindCSS producerer efter sin efterbehandlingsfase med Rust.

**Minificér.** Når `minify` er aktiveret, udsender `toCss()` minificeret CSS under serialisering. `_tailwindphp/CssMinifier.php` står bag den selvstændige `tw::minify()`-strengbehandling. Se [Caching og minificering](https://tailwindphp.inline0.dev/da/docs/advanced/caching).

## Kildelayout

`src/` afspejler TailwindCSS. Den eneste strukturelle ændring: TailwindCSSs `utilities.ts` fylder 6,000+ linjer, så den er opdelt i `src/utilities/` med én fil pr. kategori for at lette vedligeholdelsen.

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

## lightningcss-ækvivalenten

TailwindCSS overlader sin efterbehandling af CSS — nesting, håndtering af media queries og forenkling af værdier — til [lightningcss](https://lightningcss.dev/), en parser/transformer/minificerer skrevet i Rust. PHP kan ikke indlæse et Rust-bibliotek, så `src/_tailwindphp/LightningCss.php` genimplementerer de transformationer, som TailwindPHP faktisk bruger, og producerer byteidentisk output for de tilfælde, som testsuiten dækker.

Bekræftede transformationer omfatter:

| Transformation | Hvad den gør |
|-----------|--------------|
| Udfladning af nesting | Afklarer `&`-selektorer med referencens `:is(…)`-regler og udflader indlejrede regler (`handleNesting()` i `ast.php`, en portering af passet TailwindCSS); `transformNesting` nedgraderer den resterende nesting under det første niveau med deklarationer |
| Udfladning af betingede at-regler | Udflader indlejrede `@media`, `@supports`, `@container` og `@starting-style` på stedet, bevarer kilderækkefølgen og sammenfletter kun direkte tilstødende søskende med identiske betingelser |
| Rækkefølge af deklarationer | Omarrangerer deklarationer efter lightningcss' kæde af deklarationsbehandlere, så egenskaberne følger referencens rækkefølge (`reorderDeclarations`) |
| Forenkling af `calc()` | Forenkler `calc()`-udtryk (`simplifyCalcExpressions`) |
| Fjernelse af indledende nul | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Afstand i transform-funktioner | Normaliserer mellemrum i transform-funktioner (`normalizeTransformFunctions`) |
| Normalisering af grid-værdier | Tilføjer mellemrum omkring `/` i span-værdier, bare heltal → px for `grid-template-*` (`normalizeGridValues`) |
| Normalisering af farver | Normaliserer farvesyntaks og evaluerer `color-mix()` til `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| Citering af URL | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Leverandørpræfikser | Præfiksering svarende til Autoprefixer (`addVendorPrefixes`) |

Denne fil er bevidst placeret i karantæne under `_tailwindphp/` og markeret `@port-deviation:replacement` — den repræsenterer en ekstern afhængighed i stedet for at portere TailwindCSS-kildekode.

## Markører for porteringsafvigelser

Hver implementeringsfil indeholder `@port-deviation:*`-markører i sin docblock, der angiver, hvor og hvorfor PHP-implementeringen afviger fra originalen i TypeScript. Målet er, at læsere, der sammenligner PHP med TailwindCSS-kildekode, aldrig skal være i tvivl om, hvorvidt en forskel er tilsigtet.

| Markør | Betydning |
|--------|---------|
| `@port-deviation:none` | Direkte 1:1-portering uden væsentlige afvigelser |
| `@port-deviation:async` | PHP bruger synkron kode i stedet for async/await |
| `@port-deviation:storage` | Forskellige datastrukturer (PHP-array mod JS Map/Set) |
| `@port-deviation:types` | PHPDoc-annoteringer i stedet for TypeScript-typer |
| `@port-deviation:sourcemaps` | Sporing af source maps udeladt |
| `@port-deviation:enum` | PHP-konstanter i stedet for TypeScript-enumtyper |
| `@port-deviation:errors` | Anderledes fejlhåndtering |
| `@port-deviation:replacement` | PHP-implementering erstatter et eksternt bibliotek (e.g. lightningcss) |
| `@port-deviation:helper` | Hjælpefunktion specifik for PHP, som ikke findes i originalen |
| `@port-deviation:performance` | Optimering specifik for PHP, der bevarer identisk output |
| `@port-deviation:omitted` | Hele modulet/funktionen er ikke porteret (uden for omfanget) |

Se [Ydeevne og test](https://tailwindphp.inline0.dev/da/docs/advanced/performance) for markørerne `@port-deviation:performance` og for at se, hvordan paritet håndhæves.
