Teach 2.0's plain CSS in the Boost guidelines and skills

2.0.0 took Tailwind out of the stack, but the texts Boost copies into
every application still taught its utilities: the core guideline said
"built on Tailwind CSS", the always-on material-3 guideline wrote every
rule as `bg-primary`, `type-*`, `rounded-corner-*`, `state-layer` and
`medium:`, and both skills' tables and examples did the same. None of
those classes exists in 2.0's stylesheets, so an agent following the
guideline wrote markup that compiled to nothing. Found moving ReStride
onto 2.0: its CLAUDE.md, and SealShare's, carry these texts.

The guidelines and skills now teach what 2.0 has: component and layout
component props (`gap="space200"`, `hide-from="medium"`), the `md-type-*`,
`md-ink-*` and interaction classes, and `--md-sys-*` tokens in the
application's own CSS, with breakpoints as range media queries.
UPGRADE.md §1, §2 and §4 describe the finished move instead of the
in-between state, and header comments that pointed at the removed
tokens/utilities.css and tailwind.css, or called a component "still
Tailwind", say what is true now.

BoostVocabularyTest runs DesignGuard over the code in every shipped
guideline and skill (fenced Blade and CSS, and each inline class list),
so a text that teaches a class the stylesheets do not define fails the
suite; it finds 268 violations in the texts as 2.0.0 shipped them. The
guard's own table of what it reports is exempt. BoostResourcesTest now
asks the design skill for each breakpoint's prop value and media query
instead of the removed `medium:` variants.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andreas Reinhold / reini
2026-09-16 11:07:54 +02:00
co-authored by Claude Opus 5
parent bae1df09da
commit 24eb811f34
18 changed files with 462 additions and 258 deletions
+39 -27
View File
@@ -8,35 +8,43 @@ the change is inside the components. What reaches an application is below, in th
### 1. Breakpoints are M3's window size classes
Tailwind's `sm:`, `md:`, `lg:`, `xl:` and `2xl:` no longer compile. The variants are
`medium:` (600px), `expanded:` (840px), `large:` (1200px) and `extra-large:` (1600px), plus
`max-medium:` and friends for "below"; compact is everything below `medium`. Replace every
prefix in the application's views:
Tailwind's `sm:`, `md:`, `lg:`, `xl:` and `2xl:` no longer compile, and there are no responsive
variants in their place: the breakpoints are M3's window size classes — compact below 600px, then
medium (600px), expanded (840px), large (1200px) and extra-large (1600px) — and only those. A
layout component takes the class as a prop (`hide-below`, `hide-from`, `stack-below`, `<x-grid>`'s
`columns` map); the application's own CSS writes the width as a range media query:
| Was | Becomes |
|---|---|
| `sm:` / `max-sm:` (640) | `medium:` / `max-medium:` (600) |
| `md:` / `max-md:` (768) | `medium:` or `expanded:` — choose by what the layout means |
| `lg:` / `max-lg:` (1024) | `expanded:` / `max-expanded:` (840) |
| `xl:` / `max-xl:` (1280) | `large:` / `max-large:` (1200) |
| `2xl:` (1536) | `extra-large:` (1600) |
| `sm:` / `max-sm:` (640) | `medium` · `@media (width >= 600px)` / `(width < 600px)` |
| `md:` / `max-md:` (768) | `medium` or `expanded` — choose by what the layout means |
| `lg:` / `max-lg:` (1024) | `expanded` · `@media (width >= 840px)` / `(width < 840px)` |
| `xl:` / `max-xl:` (1280) | `large` · `@media (width >= 1200px)` / `(width < 1200px)` |
| `2xl:` (1536) | `extra-large` · `@media (width >= 1600px)` |
Scripts read the same numbers from `resources/js/breakpoints.js` (`from('expanded')`,
`upTo('medium')`). `DesignGuard` reports every leftover prefix with its replacement.
`<div class="hidden lg:block">` is `<x-stack hide-below="expanded">`; `flex flex-col sm:flex-row` is
`<x-row stack-below="medium">`; `grid-cols-1 lg:grid-cols-2` is
`<x-grid :columns="['compact' => 1, 'expanded' => 2]">`. Scripts read the same numbers from
`resources/js/breakpoints.js` (`from('expanded')`, `upTo('medium')`). `DesignGuard` reports every
leftover prefix with its replacement.
### 2. Only M3's scales compile
### 2. Only M3's scales, as tokens
Tailwind's default radius, shadow, text-size, weight, leading, tracking and easing utilities are
cleared like its palette was:
Tailwind's radius, shadow, text-size, weight, leading, tracking and easing utilities compile to
nothing, and so do the 1.x utilities that stood for M3's scales. A text style is a class; the
rest is a token in the application's own CSS:
| Was | Becomes |
|---|---|
| `rounded-sm``rounded-4xl` | `rounded-corner-xs` `rounded-corner-xxl` (`rounded-corner-full`, `rounded-corner-none`) |
| `shadow-sm``shadow-2xl` | `shadow-elevation-1``shadow-elevation-5` |
| `text-xs``text-9xl`, `leading-*`, `tracking-*`, `font-medium``font-black` | one `type-*` style (`type-body-md`, `type-emphasized-title-md` …) |
| `ease-in`, `ease-out`, `ease-in-out`, `duration-300` | `ease-spatial-*` / `ease-effects-*` with `duration-(--md-sys-motion-…-duration)` |
| `rounded-sm``rounded-4xl`, `rounded-corner-*` (1.x) | `var(--md-sys-shape-corner-xs)` `var(--md-sys-shape-corner-xxl)` (`-full`, `-none`), or `<x-surface corner="xs">` |
| `shadow-sm``shadow-2xl`, `shadow-elevation-*` (1.x) | `var(--md-sys-elevation-1)``var(--md-sys-elevation-5)` |
| `text-xs``text-9xl`, `leading-*`, `tracking-*`, `font-medium``font-black`, `type-*` (1.x) | one `md-type-*` class (`md-type-body-md`, `md-type-emphasized-title-md` …), or `font: var(--md-sys-typescale-body-md)` with its `-tracking` |
| `ease-in`, `ease-out`, `ease-in-out`, `duration-300`, `ease-spatial-*` (1.x) | `var(--md-sys-motion-spatial-*)` / `var(--md-sys-motion-effects-*)` with its `-duration`, in a `transition` |
| `gap-4`, `p-4`, `space-y-2` | `gap="space200"`, `<x-surface padding="space200">`, `<x-stack gap="space100">`, or `var(--md-sys-measurement-space200)` |
| `state-layer`, `focus-ring`, `touch-target`, `link` (1.x) | `md-state-layer`, `md-focus-ring`, `md-touch-target`, `md-link` |
The 4px spacing scale is unchanged. `DesignGuard` names each one with its replacement.
The spacing tokens are the 4px grid Tailwind's scale was (`space200` is 16px). `DesignGuard` names
each one with its replacement.
### 3. Regenerate the colour scheme
@@ -56,10 +64,13 @@ php artisan material:scheme "#4f46e5" --variant=tonal-spot # the command in th
### 4. Inks are roles, not opacities
`text-meta`, `text-quiet`, `border-chrome` and `border-divider` keep their names but now resolve
to `on-surface-variant`, `outline`, `outline-variant` and `outline-variant`. Where the old
translucent grey was intended, nothing to do; where a template relied on the opacity to blend
over a colour, use the role directly.
1.x's `text-meta`, `text-body`, `text-quiet`, `border-chrome`, `border-structure` and
`border-divider` are gone with the rest of the utilities. Text takes the role's `md-ink-*` class —
`md-ink-variant` (on-surface-variant) for `text-meta` and `text-body`, `md-ink-quiet` (outline) for
`text-quiet` — and a line is `<x-divider>`, `<x-surface outlined>` or
`var(--md-sys-color-outline-variant)` in the application's CSS. Where the old translucent grey was
intended, the role is the same colour; where a template relied on the opacity to blend over a
colour, use the role directly.
### 5. Changed defaults and props
@@ -117,13 +128,13 @@ over a colour, use the role directly.
and `data-md-scaffold-banner`; the skip link is `data-md-skip-link`.
- `<x-icon optical="20">` selects the optical-size-20 cut; the components pass it for their own
small icons, applications pass it for icons drawn at 20px or less.
- A text field stops at 40rem wide from `medium:`, as M3 bounds fields on wider windows; a
`max-w-*` class on the field beats it, and `full` removes it.
- A text field stops at 40rem wide from medium (600px), as M3 bounds fields on wider windows; a
width rule of the application's own on the field beats it, and `full` removes it.
- Every `<x-modal>` draws a rule under its header and over its actions while its body scrolls,
and neither when the body fits. `separator` now means "always draw both rules" and no longer
renders two `<x-divider>` elements; the spacing between header, body and actions moved to
M3's split gaps, so a dialog that fits is a few pixels shorter.
- A snackbar with a `description` is 68px tall, and below `medium:` a two-line snackbar with an
- A snackbar with a `description` is 68px tall, and below medium (600px) a two-line snackbar with an
action puts the action under the text. Alt+G moves focus to an actioned snackbar.
- `<x-bottom-sheet>`'s drag now follows the pointer and settles on the nearest preset height when
`heights` or `snap` is set; without stops it behaves as before.
@@ -203,4 +214,5 @@ whatever the page renders.
### 9. For AI agents
`php artisan boost:update --discover` picks up the new `material-3` guideline and the
`material-3-design` skill, which state M3's rules and tables beside the library's utilities.
`material-3-design` skill, which state M3's rules and tables beside the library's classes, props
and tokens.