Cut duplicated and speculative code across the package

An over-engineering audit of the whole tree, applied in five reviewed
batches. Behaviour stays the same except where UPGRADE.md says otherwise.

PHP: the showcase and error-page stylesheets are prebuilt into
resources/dist by bin/stylesheets.mjs, through Vite's own postcss-import
(first occurrence kept, the order an application's build gives), instead
of Stylesheets::bundle() inlining imports on every request; only the
import walk DesignGuard needs stays. SchemeStylesheet::withProfiles()
replaces three copies of the scheme-plus-profiles loop, material:scheme
leaves spec and contrast checks to the node script that already made
them, and the error page's scheme cache, the hashed view namespace, the
translations path with no lang/ folder and DesignGuard's 1.x-name hints
are gone.

JS: the androidx shape port progress.js and both bin scripts each carried
lives once in resources/js/shapes.js (the generated SVGs are unchanged);
util.js holds ringIndex(), ms(), reopenGuard() and remember(), which
were written out several times; listeners are released through
AbortController; tooltip.js's hoverPopover() serves the rich tooltip too.

CSS: every rule for an element inside the navigation rail queries
`--md-navigation-rail-value` instead of repeating the seven collapsed
conditions under five media branches; badge, alert, progress, slider and
button read one non-inheriting colour-role table (components/color.css);
the dialog chrome, the submenu's popover chrome, the chip's state layer
and touch target, and the visually-hidden inputs use the shared rules
they copied; foundation/tokens.css is folded into foundation.css.

Views: Support\Field and Support\Link replace the error-key, bound-value
and link-attribute blocks copied into the fields and link components;
the timepicker period group, the menu filter and the showcase head are
partials; the datepicker's steppers and entry fields are loops; component
docblocks no longer restate SKILL.md.

Tests and tooling: one dataset-driven ComponentStylesheetsTest replaces
four per-group files, DesignGuardTest and the layout-component tests use
datasets, browser tests share one ready() helper, CSS parsing lives in
ComponentStylesheet alone. docs/audits and the finding IDs citing it are
removed, as are pestphp/pest-plugin-laravel, the unused composer scripts
and check:font; the lint job runs in the feature job, which now installs
node packages so the prebuilt-stylesheet staleness test runs in CI.

Feature suite 1177 passed, Chrome browser suite 299 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andreas Reinhold / reini
2026-09-17 19:29:21 +02:00
co-authored by Claude Opus 5
parent 471d927e64
commit 247c596c3a
233 changed files with 16635 additions and 10579 deletions
+19 -11
View File
@@ -20,8 +20,8 @@
*
* `[data-md-menu]` is `<x-menu>`'s root, holding the trigger and the popover; the popover itself
* is `[data-md-menu-popover]`, capped at 288px so a long menu scrolls instead of running off the
* top layer's edge (ACT-04), and transitions in by growing from its trigger's corner while it
* fades, on the spatial and effects springs respectively (ACT-26). `data-md-vibrant` swaps its
* top layer's edge, and transitions in by growing from its trigger's corner while it
* fades, on the spatial and effects springs respectively. `data-md-vibrant` swaps its
* container for tertiary-container; a nested submenu inherits the colour through
* `--material-menu-surface`/`--material-menu-ink`, which the sheet's own copy of the list falls
* back to instead (it is not a descendant of the popover).
@@ -50,13 +50,14 @@
display: inline-flex;
}
[data-md-menu-popover] {
--material-menu-surface: var(--md-sys-color-surface-container-low);
--material-menu-ink: var(--md-sys-color-on-surface);
/* The popover chrome a submenu shares (menu-item.css, which imports this file for it): size
limits, the surface's own colour (a submenu with no ancestor popover falls back to the
standard menu's own), radius, padding, shadow, and the pop-and-fade entry/exit — M3's
effects-fast fade behind the spatial-fast scale. Each writes its own whole `margin`, so no
rule here depends on which file a bundler puts first. */
[data-md-menu-popover],
[data-md-submenu] {
inset: auto;
margin: 0;
margin-block: var(--md-sys-measurement-space50);
min-inline-size: 112px;
max-inline-size: 280px;
max-block-size: min(288px, calc(100dvh - 32px));
@@ -64,10 +65,9 @@
border-width: 0;
border-radius: var(--md-sys-shape-corner-lg);
padding: var(--md-sys-measurement-space50);
background-color: var(--material-menu-surface);
color: var(--material-menu-ink);
background-color: var(--material-menu-surface, var(--md-sys-color-surface-container-low));
color: var(--material-menu-ink, var(--md-sys-color-on-surface));
box-shadow: var(--md-sys-elevation-2);
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
opacity: 0;
scale: 0.95;
transition-property: opacity, scale;
@@ -87,6 +87,14 @@
}
}
[data-md-menu-popover] {
--material-menu-surface: var(--md-sys-color-surface-container-low);
--material-menu-ink: var(--md-sys-color-on-surface);
margin: var(--md-sys-measurement-space50) 0;
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
}
[data-md-menu-popover]:has(> [data-md-menu-filter]) {
padding: 0;
}