# Audit: actions and communication Scope: ``, ``, ``, ``, ``, ``, ``, ``/``/``/``, ``, ``, ``, ``, ``, ``, ``, ``, ``, plus `resources/css/components/{groups,menu}.css`, `resources/css/tokens/{state,motion,shape}.css`, `resources/js/{menu,snackbar,tooltip,rich-tooltip,progress,figure}.js` and `src/Concerns/Toasts.php`. Sources are named per finding. `RC-A` = `docs/reference/m3/reference-components-a.md`, `RF` = `reference-foundations.md`, `RS` = `reference-styles.md`, `tokens/X.kt` = the androidx Compose Material 3 token file in `docs/reference/m3/tokens/`. Two numbers were fetched live from androidx-main during this audit (`Button.kt`, `ButtonGroup.kt`) and are marked as such. ## Summary The button family is the strongest part of this library: all five Expressive sizes, the icon-button width matrix, the corner/press-morph scale, the outline widths, the per-variant toggle colours and the per-size type roles match the androidx tokens *exactly*, digit for digit — I could not find a single wrong number in ``'s own size tables, and the icon-button widths (narrow/default/wide × five sizes, fifteen values) are all correct. The problems are concentrated elsewhere: the split button reuses the connected button group's corner variables, so its inner corners are wrong at four of five sizes and morph in the *opposite* direction to M3 on press; the snackbar's live region is created together with its message (so the announcement is unreliable) and auto-dismisses even when it carries an action, which M3's accessibility page forbids outright; a spinner inside a filled button is drawn in `text-primary` on a `bg-primary` container, i.e. invisible; ``'s segments carry no 48 px touch target; and `` has no maximum height, so a long menu runs off the viewport with no way to scroll it. Colour is animated on the overshooting *spatial* spring in four components, which the library's own `motion.css` comment says must never happen. Nothing in this group implements a deprecated M3 component — segmented buttons and the small FAB are correctly absent — and the two non-M3 pieces (alert, stat, empty state) stay inside M3's colour roles, type scale and shape scale. Counts: 5 must-fix, 17 should-fix, 14 nice-to-have (36 findings). ## Findings ### ACT-01 · button / loading · A button's spinner is invisible on a filled or tonal button - Severity: must-fix - M3 says: "when embedded in another component (e.g. a button), the active indicator should match the label/icon color and the **track should be removed** in that context" (RC-A, Progress indicators → Accessibility; same rule repeated for the loading indicator: "when embedded in another component (e.g. a button), the indicator needs ≥3:1 against that component"). - Library does: `resources/views/components/button.blade.php:207` renders `` — only a size class. `loading.blade.php:22` detects a caller colour with `preg_match('/(^|\s)text-(?!…)/')`, which `size-5` does not match, so `loading.blade.php:31` adds `text-primary`. The SVG is `fill="currentColor"` (`resources/svg/loading-indicator/*.svg`), so a `spinner` on `` (`bg-primary`) paints primary on primary — contrast 1:1. Same on `tonal` (primary on secondary-container) and on `variant="filled" color="error"`. - Fix: in `button.blade.php:207` pass `:class="$iconSize.' text-current'"` — `text-current` satisfies `loading.blade.php`'s `$coloured` test, so no `text-primary` is added and the indicator inherits the button's label colour. - Effort: S - Breaks API? no ### ACT-02 · toast · The snackbar's live region is created together with its message - Severity: must-fix - M3 says: "Announcement: use a **live region with a 'polite'/queued** announcement (not assertive) on Android and web" (RC-A, Snackbar → Accessibility). - Library does: `resources/views/components/toast.blade.php:41` wraps the whole snackbar in `