
# Архитектура

TailwindPHP е порт 1:1. Структурата на кодовата база отразява тази на TailwindCSS – същите имена и организация на файловете – а частите, които *не могат* да бъдат пренесени директно (PHP няма Rust и V8), са изолирани в `src/_tailwindphp/`. Тази страница описва процеса на компилиране, подредбата на изходния код, повторната реализация на `lightningcss` и конвенцията за документиране на отклоненията.

## Конвейерът

Генерирането на CSS преминава през поредица от етапи. Няма отделна стъпка за изграждане – всяко извикване на `tw::generate()` изпълнява целия процес.

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

**Анализиране.** `css-parser.php` чете входа CSS – `@import`, `@theme`, `@utility`, `@layer` и необработени правила – и го преобразува в абстрактно синтактично дърво от възли `ast.php` (стилови правила, at-правила, декларации). На този етап се разрешават и заместват директивите `@import` за виртуални модули (`tailwindcss`, `tailwindcss/preflight`, …) и файловите пътища.

**Изграждане на системата за дизайн.** `theme.php` разрешава стойностите на темата (цветове, отстояния, точки на прекъсване) от анализираните блокове `@theme` и стойностите по подразбиране. `design-system.php` е централният регистър, който свързва темата с търсенето на помощни класове и варианти, дефинирано в `utilities.php` и `variants.php`.

**Сканиране на съдържанието.** `candidate.php` извлича възможните имена на класове от подаденото съдържание (HTML, шаблони) и разделя всяко на съставните му части – базов помощен клас, варианти, модификатори, произволни стойности и флаг за важно правило.

**Компилиране.** `compile.php` преобразува всеки кандидат във възли на AST, като го търси в системата за дизайн и прилага вариантите и модификаторите му. Кандидатите, които не съответстват на реален помощен клас, се отхвърлят.

**Сериализиране и оптимизиране.** `toCss()` на `ast.php` обхожда дървото (с помощни функции от `walk.php`) и извежда низа CSS. Прилагат се преобразуванията, еквивалентни на `lightningcss`, от `_tailwindphp/LightningCss.php`, за да съответства резултатът на генерирания от TailwindCSS след неговия етап на последваща обработка Rust.

**Минифициране.** Когато `minify` е включено, `toCss()` генерира минифициран CSS при сериализирането. `_tailwindphp/CssMinifier.php` осигурява самостоятелната обработка на низа `tw::minify()`. Вижте [Кеширане и минифициране](https://tailwindphp.inline0.dev/bg/docs/advanced/caching).

## Подредба на изходния код

`src/` отразява TailwindCSS. Единствената структурна промяна: `utilities.ts` на TailwindCSS съдържа над 6,000 реда и затова е разделен на `src/utilities/` с по един файл за категория, за по-лесна поддръжка.

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

TailwindCSS възлага последващата обработка на CSS – влагане, обработка на медийни заявки, опростяване на стойности – на [lightningcss](https://lightningcss.dev/), анализатор/преобразувател/минимизатор, написан на Rust. PHP не може да зарежда библиотека Rust, затова `src/_tailwindphp/LightningCss.php` реализира отново преобразуванията, на които разчита TailwindPHP, и генерира побайтово идентичен резултат за случаите, обхванати от тестовия набор.

Потвърдените преобразувания включват:

| Преобразуване | Какво прави |
|-----------|--------------|
| Сплескване на влагането | Разрешава селекторите `&` според правилата `:is(…)` на еталонната реализация и сплесква вложените правила (`handleNesting()` в `ast.php`, порт на етапа TailwindCSS); `transformNesting` преобразува вложените правила, останали под първото ниво с декларации, за по-стари версии |
| Сплескване на условните at-правила | Сплесква вложените `@media`, `@supports`, `@container` и `@starting-style` на място, запазва реда в източника и обединява само непосредствено съседни елементи с еднакви условия |
| Подреждане на декларациите | Подрежда декларациите според веригата от обработчици на декларации на lightningcss, така че свойствата да излизат в реда на еталонната реализация (`reorderDeclarations`) |
| Опростяване на `calc()` | Опростява изразите `calc()` (`simplifyCalcExpressions`) |
| Премахване на водещи нули | `0.5` → `.5` (`normalizeLeadingZeros`) |
| Интервали във функциите за трансформация | Нормализира интервалите във функциите за трансформация (`normalizeTransformFunctions`) |
| Нормализиране на стойностите на мрежата | Добавя интервали около `/` в стойностите span; преобразува цели числа без единица в px за `grid-template-*` (`normalizeGridValues`) |
| Нормализиране на цветовете | Нормализира синтаксиса на цветовете и изчислява `color-mix()` до `oklab()` (`normalizeColors`, `evaluateColorMix`) |
| Кавички в URL | `url(./x.jpg)` → `url("./x.jpg")` (`normalizeUrlQuoting`) |
| Префикси за доставчици | Префиксиране, еквивалентно на Autoprefixer (`addVendorPrefixes`) |

Този файл умишлено е поставен под карантина в `_tailwindphp/` и е маркиран като `@port-deviation:replacement` – той служи като заместител на външна зависимост, вместо да пренася изходния код на TailwindCSS.

## Маркери за отклонения в порта

Всеки файл с реализация съдържа маркери `@port-deviation:*` в docblock, които указват къде и защо реализацията PHP се различава от оригинала TypeScript. Целта е читателят, който сравнява PHP с изходния код TailwindCSS, да не се чуди дали дадена разлика е умишлена.

| Маркер | Значение |
|--------|---------|
| `@port-deviation:none` | Директен порт 1:1 без съществени отклонения |
| `@port-deviation:async` | PHP използва синхронен код вместо async/await |
| `@port-deviation:storage` | Различни структури от данни (масив PHP спрямо Map/Set JS) |
| `@port-deviation:types` | Анотации PHPDoc вместо типове TypeScript |
| `@port-deviation:sourcemaps` | Проследяването на source map е пропуснато |
| `@port-deviation:enum` | Константи PHP вместо enum-и TypeScript |
| `@port-deviation:errors` | Различен подход за обработка на грешки |
| `@port-deviation:replacement` | Реализация PHP заместваща външна библиотека (e.g. lightningcss) |
| `@port-deviation:helper` | Помощна функция, специфична за PHP, която липсва в оригинала |
| `@port-deviation:performance` | Оптимизация, специфична за PHP, която запазва идентичен резултат |
| `@port-deviation:omitted` | Целият модул/функционалност не е пренесен (извън обхвата) |

За маркерите `@port-deviation:performance` и начина, по който се гарантира съответствието, вижте [Производителност и тестване](https://tailwindphp.inline0.dev/bg/docs/advanced/performance).
