
# Imports & Virtual Modules

TailwindPHP resolves `@import` rules before compilation. Imports can point at built-in virtual modules (`tailwindcss` and friends), at files on disk via the `importPaths` option, or at anything you return from a custom resolver.

## Virtual modules

`@import "tailwindcss"` is the entry point most projects use. It expands to the four lines below — the layer order declaration plus the three sub-imports, each assigned to its cascade layer:

```css
@layer theme, base, components, utilities;
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css" layer(utilities);
```

Each sub-import is itself a virtual module you can import on its own. The available virtual modules are:

| Module | Contents |
|--------|----------|
| `tailwindcss` | The full bundle: theme + Preflight + utilities. |
| `tailwindcss/theme.css` | Theme variables only (colors, spacing base, breakpoints, etc.). |
| `tailwindcss/preflight.css` | The Preflight base reset. |
| `tailwindcss/utilities.css` | The utilities layer. |
| `tw-animate-css` | The `tw-animate-css` animation utilities. |

Importing the parts individually lets you skip Preflight or reorder layers (see below).

## Animations with tw-animate-css

[tw-animate-css](https://github.com/Wombosvideo/tw-animate-css) is a TailwindCSS v4 animation library — a drop-in replacement for `tailwindcss-animate`. It ships as a built-in virtual module, so importing it alongside the utilities layer makes its enter/exit animation classes compile like any other utility:

```css
@import "tw-animate-css";
@import "tailwindcss/utilities.css";
```

The animation utilities cover:

- **Enter / exit** — `animate-in`, `animate-out`
- **Fade** — `fade-in`, `fade-out`
- **Zoom** — `zoom-in`, `zoom-out`
- **Spin** — `spin-in`, `spin-out`
- **Blur** — `blur-in`, `blur-out`
- **Slide** — `slide-in-from-top` / `-bottom` / `-left` / `-right` and the matching `slide-out-to-*`, plus RTL-aware `-start` / `-end`
- **Timing** — `duration-*`, `delay-*`, `repeat-1` / `repeat-infinite`, `direction-normal` / `-reverse` / `-alternate`, and `fill-mode-none` / `-forwards` / `-backwards` / `-both`
- **Play state** — `running`, `paused`
- **Component animations** — `accordion-down` / `accordion-up`, `collapsible-down` / `collapsible-up`, and `caret-blink`

These classes stack with Tailwind variants like any other utility, which makes them a drop-in fit for shadcn/ui dialog and dropdown patterns.

## The `importPaths` option

To resolve `@import` against the filesystem, pass `importPaths` in the array form of `generate()`. It accepts a single path, a directory, or an array of either.

```php
use TailwindPHP\tw;

// Single file
$css = tw::generate([
    'content'     => '<div class="flex btn">Hello</div>',
    'importPaths' => '/path/to/styles.css',
]);

// Directory (loads all .css files alphabetically)
$css = tw::generate([
    'content'     => '<div class="flex btn">Hello</div>',
    'importPaths' => '/path/to/css/',
]);

// Multiple paths — files and directories
$css = tw::generate([
    'content'     => '<div class="flex btn card">Hello</div>',
    'importPaths' => [
        '/path/to/base.css',
        '/path/to/components/',
    ],
]);

// Combine with inline css
$css = tw::generate([
    'content'     => '<div class="flex btn custom">Hello</div>',
    'css'         => '.custom { color: red; }',
    'importPaths' => '/path/to/styles.css',
]);
```

### Nested imports

Imports inside a loaded file are resolved relative to that file. If `/path/to/styles.css` contains `@import "./components/buttons.css"`, the path is resolved against `/path/to/`:

```css
/* /path/to/styles.css */
@import "tailwindcss";
@import "./components/buttons.css";
@import "./components/cards.css";

@theme {
    --color-brand: #3b82f6;
}
```

### Deduplication

Importing the same file or virtual module more than once is a no-op after the first — repeated `@import "tailwindcss"` lines, or two files that both import the same partial, are deduplicated automatically. This also protects against circular imports.

## Custom resolver

For virtual file systems, databases, or any non-filesystem source, pass a callable as `importPaths`. It receives the import URI and the base directory the import is resolved against, and returns CSS or `null`:

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content'     => '<div class="flex virtual-class">Hello</div>',
    'importPaths' => function (?string $uri, ?string $fromFile): ?string {
        if ($uri === null) {
            // Entry CSS — returned when no file is supplied
            return '@import "tailwindcss"; @import "custom.css";';
        }
        if ($uri === 'custom.css') {
            return '.virtual-class { color: purple; }';
        }
        return null; // Unknown imports are silently skipped
    },
]);
```

When `$uri` is `null` (the first call, with a `null` second argument too), return the entry CSS. For any other URI, return its CSS contents, or `null` to fall back to the filesystem search, which skips the import silently when nothing is found.

## Preflight

Preflight is Tailwind's opinionated base reset, built on top of [modern-normalize](https://github.com/sindresorhus/modern-normalize). It smooths over cross-browser inconsistencies so utilities behave predictably. Among other things it removes default margins, unstyles headings and lists, makes images block-level, resets border styles so `border-width` alone draws a border, and lets buttons inherit fonts.

Preflight ships inside `@import "tailwindcss"` — if you import the full bundle, you already have it:

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'css'     => '@import "tailwindcss";',
]);
```

### Extending Preflight

Add your own base styles on top of Preflight with `@layer base`:

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content' => '<article><h1>Title</h1><p>Content</p></article>',
    'css'     => '
        @import "tailwindcss";
        @layer base {
            h1 { font-size: var(--text-2xl); }
            h2 { font-size: var(--text-xl); }
            a  { color: var(--color-blue-600); text-decoration-line: underline; }
        }
    ',
]);
```

### Disabling Preflight

When integrating into an existing project, import only the parts you need and omit the Preflight line:

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'css'     => '
        @layer theme, base, components, utilities;
        @import "tailwindcss/theme.css" layer(theme);
        @import "tailwindcss/utilities.css" layer(utilities);
    ',
]);
```

## Import modifiers

When importing Tailwind's files individually, modifiers go on the imports they affect:

```css
/* Assign the import to a cascade layer */
@import "tailwindcss/utilities.css" layer(utilities);

/* prefix affects both theme variables and utilities */
@import "tailwindcss/theme.css" layer(theme) prefix(tw);
@import "tailwindcss/utilities.css" layer(utilities) prefix(tw);

/* important affects utilities */
@import "tailwindcss/utilities.css" layer(utilities) important;

/* theme(static) or theme(inline) affects theme variables */
@import "tailwindcss/theme.css" layer(theme) theme(static);

/* theme(reference): utilities use the variables with a fallback, no :root block */
@import "tailwindcss/theme.css" layer(theme) theme(reference);
```

## Reference imports

`@import "…" reference` loads a file for its definitions only: `@theme` values, `@utility` and `@custom-variant` definitions inside it are usable, but the file emits no CSS of its own. It is the same as wrapping the file's contents in `@media reference { … }`, which you can also write directly:

```css
@import "tailwindcss/utilities.css";

@media reference {
    @theme {
        --color-brand: #f00;
    }
}
```

`bg-brand` then compiles to `background-color: var(--color-brand, #f00);` and no `--color-brand` declaration is emitted.

Two limitations in the current release ([#14](https://github.com/inline0/tailwindphp/issues/14)):

- Put reference imports and `@media reference` blocks **after** the `@import` of `tailwindcss` or `tailwindcss/utilities.css`. Placed before it, the whole output comes back empty.
- `reference` on the built-in virtual modules (`@import "tailwindcss" reference;`) has no effect yet: the theme, Preflight, and utilities are still emitted.

Continue with [Theme](/docs/usage/theme) for theme variables, or [@source](/docs/usage/source) to control which files are scanned for class names.
