From 1075305a9cdd3191b1c9a72bc8236f44fc2a4bb9 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Mon, 14 Sep 2026 13:43:23 +0200 Subject: [PATCH] Import the foundation before Tailwind in the Workbench Plan step 33. The Workbench imports foundation.css ahead of @import 'tailwindcss', so the material layers are declared first and sit below Tailwind's, then tailwind.css: the theme, the token utilities and the component stylesheets still written for Tailwind, with no tokens, so nothing is declared twice. material.css keeps working for 1.x-style imports after Tailwind by bringing the tokens, the hiding rules and tailwind.css, and never the reset, which would outrank Tailwind's utilities from there. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- resources/css/material.css | 28 ++++++------------- resources/css/tailwind.css | 34 ++++++++++++++++++++++++ tests/Feature/Components/OverlayTest.php | 2 +- workbench/resources/css/app.css | 9 ++++--- 4 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 resources/css/tailwind.css diff --git a/resources/css/material.css b/resources/css/material.css index 3524a01f..49a822a3 100644 --- a/resources/css/material.css +++ b/resources/css/material.css @@ -1,6 +1,6 @@ /* - * Livewire Material — the one stylesheet an application imports, after Tailwind, followed by - * the scheme `php artisan material:scheme` wrote for it: + * Livewire Material on 1.x-style imports — the one stylesheet an application imports, after + * Tailwind, followed by the scheme `php artisan material:scheme` wrote for it: * * @import 'tailwindcss'; * @import '../../vendor/nonameweb/livewire-material/resources/css/material.css'; @@ -11,6 +11,11 @@ * tokens/scheme.css is the package's own default (M3's baseline purple), so an application * renders before it has a scheme; the application's file declares the same roles, unlayered, and * wins over the default in `material.tokens`. + * + * It brings the tokens, the two hiding rules and tailwind.css, but not foundation.css: imported + * after Tailwind, the foundation's reset would land in a layer above Tailwind's utilities and + * undo them. An application moving to 2.0.0's vocabulary imports foundation.css before + * `@import 'tailwindcss'` and tailwind.css after it, instead of this file. */ @import './tokens/scheme.css'; @@ -19,26 +24,9 @@ @import './tokens/motion.css'; @import './tokens/type.css'; @import './tokens/font.css'; -@import './tokens/theme.css'; @import './tokens/state.css'; -@import './tokens/utilities.css'; @import './foundation/hidden.css'; -@import './components/actions.css'; -@import './components/groups.css'; -@import './components/list.css'; -@import './components/collapse.css'; -@import './components/dialog.css'; -@import './components/field.css'; -@import './components/menu.css'; -@import './components/selection.css'; -@import './components/search.css'; -@import './components/datepicker.css'; -@import './components/timepicker.css'; -@import './components/tabs.css'; -@import './components/app-bar.css'; -@import './components/navigation.css'; -@import './components/toolbar.css'; -@import './components/table.css'; +@import './tailwind.css'; @layer base { html { diff --git a/resources/css/tailwind.css b/resources/css/tailwind.css new file mode 100644 index 00000000..5d76a8c3 --- /dev/null +++ b/resources/css/tailwind.css @@ -0,0 +1,34 @@ +/* + * Livewire Material's Tailwind half: the theme that turns the tokens into utilities, the token + * utilities, and the component stylesheets still written for Tailwind (`@utility`, `@variant`, + * `@layer components`). It goes when the last component leaves Tailwind. + * + * It carries no tokens, so it can sit behind the foundation without declaring them twice — the + * Workbench imports it that way, after Tailwind: + * + * @import '../../../resources/css/foundation.css'; + * @import 'tailwindcss' source(none); + * @import '../../../resources/css/tailwind.css'; + * + * An application on 1.x-style imports keeps importing material.css, which brings the tokens and + * this file together. + */ + +@import './tokens/theme.css'; +@import './tokens/utilities.css'; +@import './components/actions.css'; +@import './components/groups.css'; +@import './components/list.css'; +@import './components/collapse.css'; +@import './components/dialog.css'; +@import './components/field.css'; +@import './components/menu.css'; +@import './components/selection.css'; +@import './components/search.css'; +@import './components/datepicker.css'; +@import './components/timepicker.css'; +@import './components/tabs.css'; +@import './components/app-bar.css'; +@import './components/navigation.css'; +@import './components/toolbar.css'; +@import './components/table.css'; diff --git a/tests/Feature/Components/OverlayTest.php b/tests/Feature/Components/OverlayTest.php index 3f78f736..9ef4396b 100644 --- a/tests/Feature/Components/OverlayTest.php +++ b/tests/Feature/Components/OverlayTest.php @@ -88,7 +88,7 @@ it('divides a scrolling body from its header and actions only while content is h ->toContain('position: absolute;') // A token that reduced motion sets to zero, so then the rule appears without a fade. ->toContain('transition: opacity var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast);') - ->and(File::get(__DIR__.'/../../../resources/css/material.css'))->toContain("@import './components/dialog.css';") + ->and(File::get(__DIR__.'/../../../resources/css/tailwind.css'))->toContain("@import './components/dialog.css';") ->and(File::get(__DIR__.'/../../../resources/js/material.js'))->toContain("import './dialog.js'") ->and(File::get(__DIR__.'/../../../resources/js/dialog.js')) ->toContain("directive('dialog-dividers'") diff --git a/workbench/resources/css/app.css b/workbench/resources/css/app.css index 60797de7..1072fdfe 100644 --- a/workbench/resources/css/app.css +++ b/workbench/resources/css/app.css @@ -1,7 +1,10 @@ -/* The Workbench builds the package exactly as an application would, with explicit - sources so the plans in docs/ are not scanned for class names. */ +/* The Workbench builds the package as an application would, with explicit sources so the plans + in docs/ are not scanned for class names. The foundation comes before Tailwind, so the + `material` layers are declared first and sit below Tailwind's; tailwind.css brings the + components still written for Tailwind, without declaring the tokens a second time. */ +@import '../../../resources/css/foundation.css'; @import 'tailwindcss' source(none); -@import '../../../resources/css/material.css'; +@import '../../../resources/css/tailwind.css'; @import './material-scheme.css'; @source '../../../resources/views';