Add the Material 3 Expressive foundation
tests / lint (push) Successful in 1m0s
tests / feature (8.4) (push) Successful in 1m0s
tests / feature (8.5) (push) Successful in 1m1s
tests / browser (safari, webkit) (push) Successful in 1m59s
tests / browser (chrome, chromium) (push) Successful in 1m49s
tests / browser (firefox, firefox) (push) Successful in 1m54s

Colour, shape, type, elevation and motion as tokens and Tailwind
utilities; `php artisan material:scheme`, which generates an app's colour
roles with Google's material-color-utilities (spec 2025); the theme head
script with light, dark and system and its Alpine store; Google Sans Flex;
every Material Symbol (4,135, outlined and filled) drawn by <x-icon>
without blade-icons; all 35 M3 Expressive shapes, ported from androidx, as
<x-shape>; the x-figure directive; the Toasts concern; DesignGuard for
applications' tests; and a showcase with every token, both themes side by
side and an icon search.

Colour utilities are `@theme inline`, so a section with its own
data-theme repaints; without it they resolve once on :root.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
Andreas Reinhold / reini
2026-09-13 05:24:11 +02:00
co-authored by Claude Opus 5
parent 9b53891a8e
commit b48e879254
8364 changed files with 12720 additions and 28 deletions
+143
View File
@@ -0,0 +1,143 @@
/*
* The Tailwind theme: every token as a utility.
*
* `--color-*: initial` clears Tailwind's default palette, so every colour a template can name
* is an M3 role (bg-primary, text-on-surface-variant, border-outline-variant…) and a
* `text-red-600` compiles to nothing. White and black come back as the two absolutes. An
* application that wants more colours adds them in its own @theme after importing this file.
*
* The colour blocks are `@theme inline`: `bg-primary` compiles to
* `background-color: var(--md-sys-color-primary)`, resolved on the element itself. Without
* `inline` it compiles to `var(--color-primary)`, a variable computed once on :root — the
* page-wide theme still switches, but a `data-theme="dark"` section inside a light page keeps
* the light colours. Only blocks whose values are variables may be inline; a literal value in
* an inline block would be copied into every utility and lose its variable.
*/
@theme {
--color-*: initial;
--color-white: #ffffff;
--color-black: #000000;
--font-sans: var(--md-ref-typeface-brand);
}
/* The colour roles, as generated by `php artisan material:scheme`. */
@theme inline {
--color-background: var(--md-sys-color-background);
--color-on-background: var(--md-sys-color-on-background);
--color-surface: var(--md-sys-color-surface);
--color-surface-dim: var(--md-sys-color-surface-dim);
--color-surface-bright: var(--md-sys-color-surface-bright);
--color-surface-container-lowest: var(--md-sys-color-surface-container-lowest);
--color-surface-container-low: var(--md-sys-color-surface-container-low);
--color-surface-container: var(--md-sys-color-surface-container);
--color-surface-container-high: var(--md-sys-color-surface-container-high);
--color-surface-container-highest: var(--md-sys-color-surface-container-highest);
--color-on-surface: var(--md-sys-color-on-surface);
--color-on-surface-variant: var(--md-sys-color-on-surface-variant);
--color-outline: var(--md-sys-color-outline);
--color-outline-variant: var(--md-sys-color-outline-variant);
--color-inverse-surface: var(--md-sys-color-inverse-surface);
--color-inverse-on-surface: var(--md-sys-color-inverse-on-surface);
--color-primary: var(--md-sys-color-primary);
--color-primary-dim: var(--md-sys-color-primary-dim);
--color-on-primary: var(--md-sys-color-on-primary);
--color-primary-container: var(--md-sys-color-primary-container);
--color-on-primary-container: var(--md-sys-color-on-primary-container);
--color-primary-fixed: var(--md-sys-color-primary-fixed);
--color-primary-fixed-dim: var(--md-sys-color-primary-fixed-dim);
--color-on-primary-fixed: var(--md-sys-color-on-primary-fixed);
--color-on-primary-fixed-variant: var(--md-sys-color-on-primary-fixed-variant);
--color-inverse-primary: var(--md-sys-color-inverse-primary);
--color-secondary: var(--md-sys-color-secondary);
--color-secondary-dim: var(--md-sys-color-secondary-dim);
--color-on-secondary: var(--md-sys-color-on-secondary);
--color-secondary-container: var(--md-sys-color-secondary-container);
--color-on-secondary-container: var(--md-sys-color-on-secondary-container);
--color-secondary-fixed: var(--md-sys-color-secondary-fixed);
--color-secondary-fixed-dim: var(--md-sys-color-secondary-fixed-dim);
--color-on-secondary-fixed: var(--md-sys-color-on-secondary-fixed);
--color-on-secondary-fixed-variant: var(--md-sys-color-on-secondary-fixed-variant);
--color-tertiary: var(--md-sys-color-tertiary);
--color-tertiary-dim: var(--md-sys-color-tertiary-dim);
--color-on-tertiary: var(--md-sys-color-on-tertiary);
--color-tertiary-container: var(--md-sys-color-tertiary-container);
--color-on-tertiary-container: var(--md-sys-color-on-tertiary-container);
--color-tertiary-fixed: var(--md-sys-color-tertiary-fixed);
--color-tertiary-fixed-dim: var(--md-sys-color-tertiary-fixed-dim);
--color-on-tertiary-fixed: var(--md-sys-color-on-tertiary-fixed);
--color-on-tertiary-fixed-variant: var(--md-sys-color-on-tertiary-fixed-variant);
--color-error: var(--md-sys-color-error);
--color-error-dim: var(--md-sys-color-error-dim);
--color-on-error: var(--md-sys-color-on-error);
--color-error-container: var(--md-sys-color-error-container);
--color-on-error-container: var(--md-sys-color-on-error-container);
--color-success: var(--md-sys-color-success);
--color-on-success: var(--md-sys-color-on-success);
--color-success-container: var(--md-sys-color-success-container);
--color-on-success-container: var(--md-sys-color-on-success-container);
--color-warning: var(--md-sys-color-warning);
--color-on-warning: var(--md-sys-color-on-warning);
--color-warning-container: var(--md-sys-color-warning-container);
--color-on-warning-container: var(--md-sys-color-on-warning-container);
--color-info: var(--md-sys-color-info);
--color-on-info: var(--md-sys-color-on-info);
--color-info-container: var(--md-sys-color-info-container);
--color-on-info-container: var(--md-sys-color-on-info-container);
--color-inverse-error: var(--md-sys-color-inverse-error);
--color-inverse-success: var(--md-sys-color-inverse-success);
--color-inverse-warning: var(--md-sys-color-inverse-warning);
--color-inverse-info: var(--md-sys-color-inverse-info);
--color-shadow: var(--md-sys-color-shadow);
--color-scrim: var(--md-sys-color-scrim);
}
/*
* Ink and lines by what they are, rather than by an opacity number that means nothing out of
* context: body copy, metadata, decoration; a structural line, a line around chrome, a divider.
*/
@theme inline {
--color-body: var(--md-sys-color-on-surface-variant);
--color-meta: color-mix(in oklab, var(--md-sys-color-on-surface) 60%, transparent);
--color-quiet: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
--color-structure: var(--md-sys-color-outline-variant);
--color-chrome: color-mix(in oklab, var(--md-sys-color-outline-variant) 60%, transparent);
--color-divider: color-mix(in oklab, var(--md-sys-color-outline-variant) 40%, transparent);
}
@theme {
--radius-corner-none: var(--md-sys-shape-corner-none);
--radius-corner-xs: var(--md-sys-shape-corner-xs);
--radius-corner-sm: var(--md-sys-shape-corner-sm);
--radius-corner-md: var(--md-sys-shape-corner-md);
--radius-corner-lg: var(--md-sys-shape-corner-lg);
--radius-corner-lg-increased: var(--md-sys-shape-corner-lg-increased);
--radius-corner-xl: var(--md-sys-shape-corner-xl);
--radius-corner-xl-increased: var(--md-sys-shape-corner-xl-increased);
--radius-corner-xxl: var(--md-sys-shape-corner-xxl);
--radius-corner-full: var(--md-sys-shape-corner-full);
--shadow-elevation-1: var(--md-sys-elevation-1);
--shadow-elevation-2: var(--md-sys-elevation-2);
--shadow-elevation-3: var(--md-sys-elevation-3);
--shadow-elevation-4: var(--md-sys-elevation-4);
--shadow-elevation-5: var(--md-sys-elevation-5);
--ease-spatial-fast: var(--md-sys-motion-spatial-fast);
--ease-spatial-default: var(--md-sys-motion-spatial-default);
--ease-spatial-slow: var(--md-sys-motion-spatial-slow);
--ease-effects-fast: var(--md-sys-motion-effects-fast);
--ease-effects-default: var(--md-sys-motion-effects-default);
--ease-effects-slow: var(--md-sys-motion-effects-slow);
--ease-standard: var(--md-sys-motion-easing-standard);
--ease-emphasized: var(--md-sys-motion-easing-emphasized);
--ease-emphasized-decelerate: var(--md-sys-motion-easing-emphasized-decelerate);
--ease-emphasized-accelerate: var(--md-sys-motion-easing-emphasized-accelerate);
}
/*
* `dark:` follows the page's theme, not the operating system: <x-theme-script> has already
* resolved `system` into data-theme, and the OS was never meant to be a second voice.
*/
@custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *));