# Upgrading ## From 2.1.0 to 2.1.1 - **`$store.rail.toggle()`** flips what the first rail on the page draws, as its menu button does. With nothing stored, ``'s rail is drawn collapsed from 840 to 1199px whatever `rail.default` says, and `toggle()` collapsed it again, so the first press of an application's shortcut changed nothing; it now expands the rail. Below 840px, where there is no room to expand it in the layout, `toggle()` opens and closes the modal rail (`show()`, `hide()`) instead of changing a choice nothing draws there. A shortcut that pressed the rail's menu button to get this can call `$store.rail.toggle()` again. - **`DesignGuard`** no longer reads a Markdown mail component's classes as Tailwind: a view under `mail.markdown.paths` (`resources/views/vendor/mail` by default) is drawn by the mail theme, whose `table`, `button` and `panel` share Tailwind's names, so only its icon names, the directives in its component tags and the application's own bans are checked there. A mail theme stylesheet under that path is no longer checked for literal values, and its classes no longer exempt the same names in the application's other views. A filter an application wrote around such a finding can go. - **`DesignGuard`** reports a colour utility on a colour the application's own Tailwind theme named (`bg-brand`, `text-sport-run`, `from-brand`, `border-l-zone-4`, `bg-brand/8`) in a class list, with `var(--…)` of the application's own as its replacement, unless the application's CSS declares the class. None of them has compiled since 2.0.0, and they were the leftovers its count never showed. Tailwind's other utilities on the same prefixes are named by their own family now too: `border-collapse`, `border-spacing-*`, `from-10%`, `via-none`, `fill-none`, `stroke-*`, `text-shadow-*`, `text-inherit`, and Tailwind 4.2's `mauve`, `olive`, `mist` and `taupe` palettes. A test that expects no findings may fail on them. - **A selected row written by hand** — `data-md-list-row` with `data-md-selected` on an `
  • `, a `
    ` or a ``, not `` or `` — is drawn in `secondary-container` with `on-secondary-container` ink again, as 1.x's `data-list-row` with `data-selected` was; 2.0.0 dropped the fill without saying so. Hover, focus and press now tint the fill instead of hiding it. In `` a plain row takes `data-md-selected` too, beside `aria-selected="true"`. A card still takes no selected fill. - **67 Material Symbols** in each cut (`auto_awesome`, `insights`, `tips_and_updates`, `battery_50` …) are drawn whole at every size. Google publishes them in 24 units (20 in the 20 cut) with a width and height but no viewBox, and the package dropped the size, so they fitted only at exactly 24px and were cut off or misplaced at any other — the 20 cut every small button draws from included. Nothing to change. - **A focused text field keeps its focus edge under the pointer.** The hover rule outweighed focus, so a focused field the pointer rested on drew a 2px `on-surface` edge instead of `primary`, and a field in error `on-error-container` instead of `error` — in the filled variant too, and on a customizable `` while its menu is open. An open select in error now draws `error` rather than `primary`. A test that read the hover colour off a focused field reads `primary` now. - **Escape closes one layer.** A dialog, menu, customizable select or searchable choice opened over or inside a modal ``, `` or modal navigation rail — or a sheet opened from a sheet, or inside `` — closed the layer under it on the same Escape, since each sheet closed on any Escape the window heard. Now only the topmost layer closes; a sheet with `close-on-escape` off still keeps the Escape from closing what is under it. A dialog or sheet opened from a modal sheet but rendered elsewhere on the page was also hidden from screen readers by the sheet's `aria-hidden`, and Tab could not move inside the dialog; both work now. An application's own guard around a sheet's Escape can go. - **A standard `` sticks under the top safe area** (`--material-safe-top`, else the device's inset) instead of at the window's edge, so its head and close button no longer slide under an installed app's status bar as the page scrolls; inside `` it also sticks under a sticky `` in the `top` slot, which covered it. It is as tall as the window below that, and every side sheet keeps the bottom safe area inside its bottom padding. ## From 2.0.0 to 2.1.0 - **Browsers:** Firefox 151 or later (was 147), for container style queries on a custom property; Chrome 125 and Safari 18.4 are unchanged. - **``** publishes its value as `--md-navigation-rail-value`, `collapsed` or `expanded` (M3's two rail values). Content an application puts in a rail reads it with `@container style(--md-navigation-rail-value: collapsed)` instead of copying the rail's conditions from `navigation-rail.css`. - **``** sizes the loading indicator in px, 24 to 240 (M3's responsive range), with the container and the shape in proportion. A width and height of the application's own still work. ## From 1.x to 2.0.0 2.0.0 aligns the library with Material Design 3 Expressive as Google documents it (m3.material.io, checked page by page; the audits are in `docs/audits/m3-alignment/`). Most of the change is inside the components. What reaches an application is below, in the order to do it. ### 1. Breakpoints are M3's window size classes 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`, ``'s `columns` map); the application's own CSS writes the width as a range media query: | Was | Becomes | |---|---| | `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)` | `