Skip to content

Styling & Tailwind

FilamentCraft ships compiled fallback CSS so the editor and the built-in sections are usable immediately after php artisan filamentcraft:install. For a real project, you should still use a Filament custom theme and let the host app compile the Tailwind classes used by this package and by your own sections.

Why a custom theme

Filament's default panel stylesheet only contains Filament's own UI classes. Any Tailwind utilities used in package views, custom pages, custom section Blade files, or section PHP classes must be visible to the host app's Tailwind build.

1. Create a panel theme

Create a panel theme if the app does not already have one:

bash
php artisan make:filament-theme admin

2. Register it on the panel

php
use Filament\Panel;
use FilamentCraft\FilamentCraftPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->viteTheme('resources/css/filament/admin/theme.css')
        ->plugin(FilamentCraftPlugin::make());
}

3. Add FilamentCraft (and your section) sources

Add FilamentCraft and your own section sources to resources/css/filament/admin/theme.css (all @source paths are relative to the theme file itself):

css
@import '../../../../vendor/filament/filament/resources/css/theme.css';

@source '../../../../app/Filament/**/*';
@source '../../../../resources/views/filament/**/*';

/* FilamentCraft editor views, field views, and PHP classes that emit classes. */
@source '../../../../vendor/filamentcraft/filamentcraft/resources/views/**/*.blade.php';
@source '../../../../vendor/filamentcraft/filamentcraft/src/**/*.php';

/* Your host-app sections. */
@source '../../../../app/Sections/**/*.php';
@source '../../../../resources/views/sections/**/*.blade.php';

@custom-variant dark (&:where(.dark, .dark *));

4. Rebuild

Rebuild after changing the source list:

bash
npm run build
php artisan filament:assets

Re-run php artisan filament:assets after every FilamentCraft update too, so the editor bundle stays in sync with the package.

This follows Filament's plugin guidance: plugin views that use Tailwind should be included in the host custom theme with @source. FilamentCraft keeps its compiled CSS enabled as a fallback for quick installs and for users who have not created a custom theme yet.

Skip the @source dance entirely

If your panel already compiles a Tailwind build that covers your section views, call FilamentCraftPlugin::make()->mirrorEditorStyles() — it mirrors the panel's compiled stylesheets into the preview iframe, so the preview picks up the same classes with zero extra configuration. For finer control there are also ->stylesheet(), ->viteBuild(), and ->viteManifest() — see Preview & Public Assets.

Preview & public-page styling

The Filament panel theme styles the editor chrome. The iframe preview and public template output are separate HTML documents that need their own CSS. See Preview & Public Assets for the three-tier asset model.

Utility collisions with your own Tailwind build

If you inject a host Tailwind bundle into the storefront through filamentcraft.assets.vite_builds, both stylesheets emit the same utility class names — grid-cols-1, p-4, and so on. FilamentCraft's site stylesheet therefore declares an explicit cascade-layer order:

css
@layer theme, base, components, utilities, filamentcraft;
@import "tailwindcss" layer(filamentcraft);

It loads first, so that declaration is the one that counts. Two consequences worth knowing:

  • A host bundle's layered utilities (Tailwind's own @layer utilities) can no longer beat FilamentCraft's responsive variants on source order. Without this, a plain .grid-cols-1 from your build would override lg:grid-cols-4 from a section and collapse it to one column.
  • Your unlayered CSS still overrides everything FilamentCraft ships. Write storefront overrides as plain rules — not inside @layer — and they win.
css
/* Wins over FilamentCraft, because it is unlayered. */
.fc-btn { border-radius: 0; }