@verbatim ## Material 3 Every view in this application is Material 3 Expressive (m3.material.io), through `nonameweb/livewire-material`. These rules decide what to write; the `material-3-design` skill carries the tables, the numbers and Google's source pages behind each one — activate it before designing a screen. The library is plain CSS on M3's tokens, and there are no utility classes: a Tailwind class, or one of the library's 1.x utilities (bg-primary, type-body-md, medium:hidden), compiles to nothing. A view is written three ways: - Components and their props: ``, and the layout components ``, ``, ``, ``, `` and ``, whose `gap` and `padding` take a spacing token (`space200`) and whose `hide-below`, `hide-from` and `stack-below` take a window size class. - A fixed set of classes for text and interaction on plain elements: `md-type-*`, `md-ink-*`, `md-text-*`, `md-truncate`, `md-tabular`, `md-visually-hidden`, `md-state-layer`, `md-focus-ring`, `md-touch-target` and `md-link`. - The application's own CSS, named by the application, whose values are `--md-sys-*` custom properties. ### Colour - A colour is always a role: `md-ink-variant` on text, `var(--md-sys-color-outline-variant)` in the application's CSS, `color="error"` on a component. Never a hex, a palette tone or an opacity. - Pair a role only with its `on-` partner: a `primary` fill takes `on-primary` text, a `secondary-container` fill takes `on-secondary-container`. That pair is the one whose contrast is guaranteed at every contrast level; mixing pairs (`primary-container` under `on-surface`) is not. - `primary` is the one key action on a screen (a filled button; the FAB in `primary-container`). `secondary-container` is the quiet fill (tonal buttons, selected navigation, selected chips). `tertiary` is a contrasting accent, used rarely. `error`, `success`, `warning`, `info` mean state and nothing else: the `-container` for a tinted panel, the role itself for its text and icon. - Ink is `on-surface` (`md-ink`); lower emphasis is `on-surface-variant` (`md-ink-variant`); decoration is `outline` (`md-ink-quiet`). Never dim ink with an opacity: 38% means disabled. - `outline` is a boundary that must be read (a text field, the edge of a target). `outline-variant` is a divider or a card edge (``, ``). Never `outline` on a divider. - Fixed and dim roles (`primary-fixed`, `surface-dim`, …) are for a colour that must not change with the theme; if unsure, don't. Inverse roles only on an inverse surface (the snackbar). - A link in running text is underlined (`md-link`, with `md-ink-primary`); colour alone signals nothing. - Contrast: 4.5:1 for text, 3:1 for large text, icons and grouped controls; disabled is exempt. Three contrast levels exist (``: standard, medium, high) and every role changes with them — which is why only roles are allowed. ### Surfaces and elevation - The page is `surface`. Panels separate by tone first: `surface-container-lowest` … `surface-container-highest` is a hierarchy of emphasis, not of height (``). Navigation chrome is `surface-container`; a dialog, a menu, the search bar are `surface-container-high`; a modal sheet is `surface-container-low`; a filled card is `surface-container-highest`. A region keeps its role at every width. - Shadows (`var(--md-sys-elevation-1)` … `-5`) are for what floats or lifts: 1 for elevated cards, buttons and modal sheets; 2 for menus, the navigation bar, a scrolled app bar; 3 for the FAB, dialogs, pickers and search; one level more on hover; nothing rests above 3. Fewer shadows carry more meaning. - A scrim is `scrim` at 32%: `color-mix(in srgb, var(--md-sys-color-scrim) 32%, transparent)`. ### Shape - Corners come from the scale `var(--md-sys-shape-corner-{none|xs|sm|md|lg|lg-increased|xl|xl-increased|xxl|full})`, or ``; never a length of your own. - By family: `full` buttons, icon buttons, chips' avatars, badges, switches, sliders, the search bar, navigation indicators; `xs` text fields, menus, snackbars, plain tooltips; `sm` chips; `md` cards, rich tooltips; `lg` the FAB and a side sheet's inner corners; `xl` dialogs, bottom sheets, the search view, pickers, carousel items; `xxl` large hero containers. - Nested shapes: inner radius = outer radius − padding; never the same radius inside and out. - A press squares a round shape (the components do it; nothing morphs on hover). The 35 ``s are decoration, never meaning, used sparingly. ### Type - Every text element carries one `md-type-*` class: `display` for hero figures and short marketing lines; `headline` for page and section titles; `title` for card, dialog and list-section titles; `body` for paragraphs (`md-type-body-lg` for reading); `label` inside components (buttons, chips, tabs, captions). In the application's CSS a style is `font: var(--md-sys-typescale-body-md)` with its `-tracking`; never a size, weight, line height or letter spacing of your own. - `md-type-emphasized-*` is opt-in: a selected item, a primary action, a headline, a badge — not decoration. - 40–60 characters per line; `md-tabular` on figures that change; text must scale to 200% without loss (containers grow, rows wrap, no fixed heights on text, no ellipsis without a way to read the rest). ### Motion - Position, size and shape move on the spatial springs (they overshoot): `transition: transform var(--md-sys-motion-spatial-default-duration) var(--md-sys-motion-spatial-default)` — `fast` for small elements, `slow` for large ones. Colour and opacity move on the effects springs (`--md-sys-motion-effects-*`), which never overshoot. Always pair an easing with its duration. - Entering decelerates, a permanent exit accelerates, a temporary exit (a sheet, a drawer) takes the emphasized curve; exits are shorter than entrances. - Everything that moves goes through these tokens, so reduced motion makes it instant; a literal duration is a bug. ### States and targets - Interactive elements carry `md-state-layer md-focus-ring`: hover 8%, focus 10%, pressed 10%, dragged 16% (`data-md-dragged`) of the content colour. Disabled is content at 38% and a container at 12% of `on-surface` (`--md-sys-state-disabled-content-opacity`, `--md-sys-state-disabled-container-opacity`, through `color-mix()`), with no state layer. Every state shows two indicators: colour plus a shape, an outline, an icon or a word. - Every target is at least 48×48px with 8px between targets (`md-touch-target` on anything drawn smaller); a denser layout is an opt-in prop, never a default. - Keyboard: Tab between components, arrows within one, Enter and Space activate, Escape dismisses; a dialog takes focus and gives it back to what opened it. ### Layout and breakpoints - Widths are M3's window size classes and only those: compact below 600px (the default), medium 600, expanded 840, large 1200, extra-large 1600. A layout component takes them as props (``, ``, ``); the application's CSS writes `@media (width >= 840px)`; a script asks `from()` and `upTo()` from `resources/js/breakpoints.js`. - What changes per class: compact — navigation bar, one pane, full-screen dialogs, a bottom sheet for choices; medium — collapsed rail, one pane; expanded — rail (collapsible), two panes, menus and basic dialogs; large and extra-large — the rail expanded, two panes, a third only at extra-large as a side sheet. `` does this; content lives in panes (``, `` for a list's second pane), never beside the rail by hand. - Margins are 16px below medium and 24px from it (`` draws them); spacing sits on the 4px grid as `space25` … `space900`, as padding and gaps on the parent, with margins only between layout regions. A fixed pane is 360px (expanded) or 412px (large); a side sheet at most 400px. - Write logical properties (`padding-inline-start`, `inset-inline-end`, `md-text-start`); directional icons mirror in RTL; charts and media controls stay LTR. Keep controls inside the safe area (`--material-safe-*`). ### Accessibility - Native elements first (`