diff --git a/UPGRADE.md b/UPGRADE.md index 79d737c4..881cfc6c 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -138,7 +138,8 @@ component the views render, opening with the layer statement every package style either: layout components (``, ``, ``, ``, ``, the canonical layouts) take M3's spacing tokens and breakpoints as props, a small set of `md-type-*` and `md-ink-*` classes covers text on plain elements, and `--md-sys-*` custom properties serve the -rest of an application's own stylesheet. +rest of an application's own stylesheet. The foundation smooths text in grayscale, as Tailwind's +`antialiased` class did: drop the class. ### 7. New in 2.0.0 diff --git a/resources/boost/skills/livewire-material-development/SKILL.md b/resources/boost/skills/livewire-material-development/SKILL.md index 256258bf..80431369 100644 --- a/resources/boost/skills/livewire-material-development/SKILL.md +++ b/resources/boost/skills/livewire-material-development/SKILL.md @@ -90,7 +90,7 @@ Scheme::resolveProfileUsing(fn (): ?string => Setting::get('color_profile')); ## Tokens -2.0.0's vocabulary is plain CSS, without Tailwind. `resources/css/foundation.css` is the one required import, first in the entry, followed by the stylesheets of the components the views render (see Setup; 1.x's `material.css` shortcut is gone). It declares the layer order `material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility`, so an application's unlayered CSS beats every package rule, and `hidden` or `x-cloak` hides any element. It brings the reset, every `--md-sys-*` token (spacing included: `--md-sys-measurement-space25` … `space900`, 2–72px), and `md-state-layer`, `md-focus-ring`, `md-touch-target`, `md-link`. Text on plain elements takes the fixed text classes of `resources/css/text.css` and nothing else: `md-type-{display|headline|title|body|label}-{lg|md|sm}` and `md-type-emphasized-…`; `md-ink` (on-surface), `md-ink-variant`, `md-ink-quiet`, `md-ink-primary`, `md-ink-error`, `md-ink-success`, `md-ink-warning`, `md-ink-info`, `md-ink-inverse`; `md-text-start|center|end`, `md-truncate`, `md-line-clamp-2|3`, `md-nowrap`, `md-tabular`, `md-visually-hidden`. Every component is plain CSS now; the Tailwind names below stay for the showcase and an application's own views, until Tailwind itself leaves the package. +2.0.0's vocabulary is plain CSS, without Tailwind. `resources/css/foundation.css` is the one required import, first in the entry, followed by the stylesheets of the components the views render (see Setup; 1.x's `material.css` shortcut is gone). It declares the layer order `material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility`, so an application's unlayered CSS beats every package rule, and `hidden` or `x-cloak` hides any element. It brings the reset, the page's `surface` and `on-surface` in the brand typeface smoothed in grayscale (drop Tailwind's `antialiased`), every `--md-sys-*` token (spacing included: `--md-sys-measurement-space25` … `space900`, 2–72px), and `md-state-layer`, `md-focus-ring`, `md-touch-target`, `md-link`. Text on plain elements takes the fixed text classes of `resources/css/text.css` and nothing else: `md-type-{display|headline|title|body|label}-{lg|md|sm}` and `md-type-emphasized-…`; `md-ink` (on-surface), `md-ink-variant`, `md-ink-quiet`, `md-ink-primary`, `md-ink-error`, `md-ink-success`, `md-ink-warning`, `md-ink-info`, `md-ink-inverse`; `md-text-start|center|end`, `md-truncate`, `md-line-clamp-2|3`, `md-nowrap`, `md-tabular`, `md-visually-hidden`. Every component is plain CSS now; the Tailwind names below stay for the showcase and an application's own views, until Tailwind itself leaves the package. Tailwind's default palette is cleared: every colour class names an M3 role. `text-red-600`, `bg-base-200` or `text-gray-500` compile to nothing. The rules behind the names below — which role, surface container, corner, type style, elevation level, motion spring, state and window size class to use, and M3's don'ts — are the `material-3` guideline (always on) and the `material-3-design` skill (the tables and Google's source pages); activate that skill before designing a screen. diff --git a/resources/css/components/error-page.css b/resources/css/components/error-page.css index 982f4600..c43ab10e 100644 --- a/resources/css/components/error-page.css +++ b/resources/css/components/error-page.css @@ -48,7 +48,6 @@ min-height: 100dvh; background-color: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); - -webkit-font-smoothing: antialiased; } [data-md-error-page] { diff --git a/resources/css/foundation/base.css b/resources/css/foundation/base.css index bda12bcc..bbb36fd7 100644 --- a/resources/css/foundation/base.css +++ b/resources/css/foundation/base.css @@ -8,6 +8,11 @@ * `--md-ref-typeface-brand` (tokens/type.css), Google Sans Flex from tokens/font.css, whose * `@font-face` this file imports into the same layer. * + * Text is smoothed in grayscale where a platform offers the choice (macOS browsers): Google Sans + * Flex is drawn for it, and subpixel smoothing thickens its strokes on light text over a dark + * surface. Every surface the package draws — the showcase, the error pages — is set this way, + * and so is an application, which drops Tailwind's `antialiased` class with nothing to replace. + * * In `material.base`, above the reset and below every component and text class. */ @@ -20,5 +25,7 @@ background-color: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); font-family: var(--md-ref-typeface-brand); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } } diff --git a/resources/css/showcase.css b/resources/css/showcase.css index 22819aab..d1294db3 100644 --- a/resources/css/showcase.css +++ b/resources/css/showcase.css @@ -28,11 +28,6 @@ @layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility; @layer material.components { - [data-md-showcase] { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - /* The rail's wordmark: `md-type-title-lg md-truncate md-focus-ring` cover the type, the ellipsis and the ring; `display: block` gives the truncated text a width to ellipsize within, and the corner rounds the ring to match the state layer every other rail control diff --git a/src/Testing/DesignGuard.php b/src/Testing/DesignGuard.php index c67f9cbd..3fe109ce 100644 --- a/src/Testing/DesignGuard.php +++ b/src/Testing/DesignGuard.php @@ -161,8 +161,9 @@ class DesignGuard ['/^(?:cursor-[\w-]+|pointer-events-(?:none|auto)|select-(?:none|text|all|auto)|touch-[\w-]+|resize(?:-[xy]|-none)?|appearance-(?:none|auto)|scroll-(?:smooth|auto)|-?scroll-[mp][trblxyse]?-[\w.]+|snap-[\w-]+)$/', 'Tailwind interactivity utility `%s` compiles to nothing — write the rule in your own CSS'], ['/^(?:aspect-(?:auto|square|video|\d+\/\d+)|object-(?:contain|cover|fill|none|scale-down|top|bottom|center|left|right|left-top|left-bottom|right-top|right-bottom))$/', 'Tailwind media utility `%s` compiles to nothing — write `aspect-ratio`/`object-fit` in your own CSS'], ['/^font-(?:sans|serif)$/', 'Tailwind\'s `%s` compiles to nothing — the foundation already sets the brand typeface; any other `font-family` is your own CSS'], + ['/^antialiased$/', 'Tailwind\'s `%s` compiles to nothing — the foundation already smooths text in grayscale (base.css); drop it'], ['/^(?:underline|no-underline)$/', 'Tailwind\'s `%s` compiles to nothing — `md-link` draws a link (interaction.css); any other decoration is your own CSS'], - ['/^(?:uppercase|lowercase|capitalize|normal-case|italic|not-italic|overline|line-through|underline-offset-\w+|decoration-(?:\d+|solid|double|dotted|dashed|wavy|auto|from-font|clone|slice)|font-mono|antialiased|subpixel-antialiased|whitespace-(?:normal|pre|pre-line|pre-wrap|break-spaces)|break-(?:words|all|keep|normal)|wrap-(?:break-word|anywhere|normal)|text-(?:wrap|balance|pretty|ellipsis|clip|justify)|line-clamp-(?:\d+|none)|not-sr-only|list-(?:disc|decimal|none|inside|outside)|align-(?:baseline|top|middle|bottom|text-top|text-bottom|sub|super)|indent-[\w.]+|hyphens-(?:none|manual|auto)|(?:normal|lining|oldstyle|proportional)-nums|ordinal|slashed-zero|(?:diagonal|stacked)-fractions)$/', 'Tailwind text utility `%s` compiles to nothing — write the rule in your own CSS'], + ['/^(?:uppercase|lowercase|capitalize|normal-case|italic|not-italic|overline|line-through|underline-offset-\w+|decoration-(?:\d+|solid|double|dotted|dashed|wavy|auto|from-font|clone|slice)|font-mono|subpixel-antialiased|whitespace-(?:normal|pre|pre-line|pre-wrap|break-spaces)|break-(?:words|all|keep|normal)|wrap-(?:break-word|anywhere|normal)|text-(?:wrap|balance|pretty|ellipsis|clip|justify)|line-clamp-(?:\d+|none)|not-sr-only|list-(?:disc|decimal|none|inside|outside)|align-(?:baseline|top|middle|bottom|text-top|text-bottom|sub|super)|indent-[\w.]+|hyphens-(?:none|manual|auto)|(?:normal|lining|oldstyle|proportional)-nums|ordinal|slashed-zero|(?:diagonal|stacked)-fractions)$/', 'Tailwind text utility `%s` compiles to nothing — write the rule in your own CSS'], ['/^bg-(?:(?:gradient-to|linear-to)-[a-z]+|radial|conic|cover|contain|auto|center|top|bottom|left|right|no-repeat|repeat(?:-[xy])?|fixed|local|scroll|none|clip-[a-z]+|origin-[a-z]+)$/', 'Tailwind background utility `%s` compiles to nothing — write the rule in your own CSS'], ]; diff --git a/tests/Feature/DesignGuardTest.php b/tests/Feature/DesignGuardTest.php index 26562d2a..39cd7f49 100644 --- a/tests/Feature/DesignGuardTest.php +++ b/tests/Feature/DesignGuardTest.php @@ -372,6 +372,7 @@ it('reports position, border, effect, interactivity and text utilities with the 'tailwind/utilities.blade.php:3 Tailwind text utility `font-mono` compiles to nothing — write the rule in your own CSS', 'tailwind/utilities.blade.php:3 Tailwind text utility `list-disc` compiles to nothing — write the rule in your own CSS', 'tailwind/utilities.blade.php:3 Tailwind text utility `uppercase` compiles to nothing — write the rule in your own CSS', + "tailwind/utilities.blade.php:3 Tailwind's `antialiased` compiles to nothing — the foundation already smooths text in grayscale (base.css); drop it", "tailwind/utilities.blade.php:3 Tailwind's `font-sans` compiles to nothing — the foundation already sets the brand typeface; any other `font-family` is your own CSS", "tailwind/utilities.blade.php:3 Tailwind's `text-end` compiles to nothing — use `md-text-end` (text.css)", "tailwind/utilities.blade.php:3 Tailwind's `underline` compiles to nothing — `md-link` draws a link (interaction.css); any other decoration is your own CSS", diff --git a/tests/Feature/ShowcaseAssetsTest.php b/tests/Feature/ShowcaseAssetsTest.php index 2b3ee7a8..b1ab68a0 100644 --- a/tests/Feature/ShowcaseAssetsTest.php +++ b/tests/Feature/ShowcaseAssetsTest.php @@ -21,7 +21,7 @@ it('serves the bundle as long-cached CSS at the hash of its own content', functi ->assertHeader('Cache-Control', 'immutable, max-age=31536000, public'); expect($response->getContent()) - ->toContain('[data-md-showcase]') + ->toContain('[data-md-showcase-brand]') ->toContain('[data-md-pane]') ->toContain('@layer material.reset, material.tokens'); }); diff --git a/tests/Feature/StylesheetsTest.php b/tests/Feature/StylesheetsTest.php index dffe1a27..3126f740 100644 --- a/tests/Feature/StylesheetsTest.php +++ b/tests/Feature/StylesheetsTest.php @@ -212,6 +212,16 @@ it('brings every foundation file and text.css into the foundation, and nothing e ->and(array_values(preg_grep('/^components\//', $foundation)))->toBe([]); }); +it('paints the page in surface and on-surface, in the brand typeface, smoothed in grayscale', function () { + // An application drops Tailwind's `antialiased` with nothing to replace it: the showcase and the + // error pages, which set it themselves before, read it from here too. + $base = (string) preg_replace('~/\*.*?\*/~s', '', (string) file_get_contents(stylesheetPath('foundation/base.css'))); + + expect($base)->toMatch('/html \{\s*background-color: var\(--md-sys-color-surface\);\s*color: var\(--md-sys-color-on-surface\);\s*font-family: var\(--md-ref-typeface-brand\);\s*-webkit-font-smoothing: antialiased;\s*-moz-osx-font-smoothing: grayscale;\s*\}/') + ->and((string) file_get_contents(stylesheetPath('showcase.css')).file_get_contents(stylesheetPath('components/error-page.css'))) + ->not->toContain('font-smoothing'); +}); + it('leaves no stylesheet under resources/css/ outside all.css or showcase.css', function () { // The full tree now that Tailwind is gone (plan step 39): every .css file on disk, not just the // ones a bundler happens to reach — a stray or orphaned file would show up here even though diff --git a/tests/Fixtures/design-guard/tailwind/utilities.blade.php b/tests/Fixtures/design-guard/tailwind/utilities.blade.php index 8ba2ad1d..ce9a4dd2 100644 --- a/tests/Fixtures/design-guard/tailwind/utilities.blade.php +++ b/tests/Fixtures/design-guard/tailwind/utilities.blade.php @@ -1,4 +1,4 @@
- +