@expressivecss/expressive 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +1266 -1
  2. package/README.md +14 -11
  3. package/dist/css/expressive.css +4215 -1668
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/js/expressive.cjs +1231 -1253
  8. package/dist/js/expressive.cjs.map +4 -4
  9. package/dist/js/expressive.js +1231 -1253
  10. package/dist/js/expressive.js.map +4 -4
  11. package/dist/js/expressive.min.js +12 -12
  12. package/dist/js/expressive.min.js.map +4 -4
  13. package/dist/js/expressive.mjs +1231 -1253
  14. package/dist/js/expressive.mjs.map +4 -4
  15. package/dist/types/behaviors/bottomSheets.d.ts +19 -11
  16. package/dist/types/behaviors/sheetDrag.d.ts +40 -0
  17. package/dist/types/behaviors/sideSheets.d.ts +2 -9
  18. package/dist/types/components/autocomplete.d.ts +15 -3
  19. package/dist/types/components/buttons.d.ts +5 -1
  20. package/dist/types/components/carousel.d.ts +87 -53
  21. package/dist/types/components/chips.d.ts +21 -1
  22. package/dist/types/components/expandingCard.d.ts +31 -0
  23. package/dist/types/components/index.d.ts +21 -20
  24. package/dist/types/components/lightbox.d.ts +1 -0
  25. package/dist/types/components/menu.d.ts +7 -1
  26. package/dist/types/components/{sidenav.d.ts → navigationDrawer.d.ts} +16 -16
  27. package/dist/types/components/registry.d.ts +8 -8
  28. package/dist/types/components/slider.d.ts +26 -85
  29. package/dist/types/components/snackbar.d.ts +20 -5
  30. package/dist/types/components/tabs.d.ts +12 -0
  31. package/dist/types/components/timepicker.d.ts +12 -9
  32. package/dist/types/core/utils.d.ts +64 -53
  33. package/dist/types/index.d.ts +8 -9
  34. package/package.json +15 -1
  35. package/src/sass/README.md +61 -11
  36. package/src/sass/abstracts/_breakpoints.scss +17 -19
  37. package/src/sass/abstracts/_mixins.scss +103 -21
  38. package/src/sass/abstracts/_variables.scss +50 -5
  39. package/src/sass/base/_global.scss +6 -24
  40. package/src/sass/base/_grid.scss +15 -12
  41. package/src/sass/base/_normalize.scss +34 -38
  42. package/src/sass/base/_typography.scss +4 -18
  43. package/src/sass/components/_badges.scss +2 -3
  44. package/src/sass/components/_banners.scss +298 -0
  45. package/src/sass/components/_bottom-app-bar.scss +180 -0
  46. package/src/sass/components/_bottom-sheet.scss +12 -4
  47. package/src/sass/components/_button-groups.scss +186 -0
  48. package/src/sass/components/_buttons.scss +245 -92
  49. package/src/sass/components/_cards.scss +494 -73
  50. package/src/sass/components/_carousel.scss +562 -68
  51. package/src/sass/components/_chips.scss +64 -5
  52. package/src/sass/components/_datepicker.scss +24 -24
  53. package/src/sass/components/_dialog.scss +17 -11
  54. package/src/sass/components/_drag-handle.scss +130 -0
  55. package/src/sass/components/_expanding-card.scss +260 -0
  56. package/src/sass/components/_fab-menu.scss +232 -0
  57. package/src/sass/components/_floating-sheet.scss +86 -0
  58. package/src/sass/components/_icon-buttons.scss +194 -0
  59. package/src/sass/components/_icons-material-design.scss +16 -4
  60. package/src/sass/components/_index.scss +22 -6
  61. package/src/sass/components/_list.scss +16 -13
  62. package/src/sass/components/_loading-indicator.scss +106 -0
  63. package/src/sass/components/_menu.scss +335 -61
  64. package/src/sass/components/_navbar.scss +71 -24
  65. package/src/sass/components/_navigation-bar.scss +13 -10
  66. package/src/sass/components/{_sidenav.scss → _navigation-drawer.scss} +123 -33
  67. package/src/sass/components/_navigation-rail.scss +22 -22
  68. package/src/sass/components/_page-footer.scss +19 -16
  69. package/src/sass/components/_pagination.scss +24 -6
  70. package/src/sass/components/_panes.scss +52 -11
  71. package/src/sass/components/{_preloader.scss → _progress.scss} +11 -3
  72. package/src/sass/components/_scrim.scss +37 -0
  73. package/src/sass/components/_search.scss +259 -0
  74. package/src/sass/components/_segmented-buttons.scss +188 -0
  75. package/src/sass/components/_side-sheet.scss +2 -2
  76. package/src/sass/components/_snackbar.scss +20 -15
  77. package/src/sass/components/_split-button.scss +196 -0
  78. package/src/sass/components/_tabs.scss +7 -8
  79. package/src/sass/components/_timepicker.scss +67 -58
  80. package/src/sass/components/_toolbar.scss +206 -80
  81. package/src/sass/components/forms/_checkboxes.scss +49 -12
  82. package/src/sass/components/forms/_fieldset.scss +4 -4
  83. package/src/sass/components/forms/_file-input.scss +8 -1
  84. package/src/sass/components/forms/_index.scss +1 -1
  85. package/src/sass/components/forms/_input-fields.scss +50 -44
  86. package/src/sass/components/forms/_radio-buttons.scss +42 -10
  87. package/src/sass/components/forms/_select.scss +0 -1
  88. package/src/sass/components/forms/{_range.scss → _slider.scss} +8 -9
  89. package/src/sass/components/forms/_switches.scss +6 -7
  90. package/src/sass/tokens/_index.scss +4 -1
  91. package/src/sass/tokens/_reference.scss +70 -61
  92. package/src/sass/tokens/_state.scss +24 -0
  93. package/src/sass/tokens/_theme.scss +6 -3
  94. package/src/sass/tokens/_vibrant.scss +76 -0
  95. package/src/sass/utilities/_colors.scss +14 -1
  96. package/src/sass/utilities/_helpers.scss +5 -5
  97. package/src/sass/utilities/_visibility.scss +48 -26
  98. package/dist/types/behaviors/waves.d.ts +0 -15
  99. package/dist/types/components/parallax.d.ts +0 -16
  100. package/dist/types/components/range.d.ts +0 -43
  101. package/dist/types/core/bounding.d.ts +0 -6
  102. package/dist/types/core/edges.d.ts +0 -6
  103. package/src/sass/components/_parallax.scss +0 -104
  104. package/src/sass/components/_pulse.scss +0 -37
  105. package/src/sass/components/_slider.scss +0 -129
@@ -1,14 +1,36 @@
1
+ @use "sass:list";
2
+ @use "sass:map";
1
3
  @use "./elevation" as *;
2
4
  @use "./variables" as *;
3
5
 
6
+ $_state-layers: ("hover", "focus", "pressed", "dragged");
7
+
8
+ /// A state layer opacity, as the percentage `color-mix()` wants.
9
+ ///
10
+ /// The tokens hold numbers (0.08), because an overlay uses one as `opacity`
11
+ /// directly. A tint mixed with `color-mix()` needs a percentage, so it is
12
+ /// multiplied here rather than at forty-odd call sites.
13
+ ///
14
+ /// Validated for the same reason `z-depth()` validates: a typo would produce a
15
+ /// `var()` naming a token nothing declares, which invalidates the whole
16
+ /// declaration at computed-value time - silently, and in a way nothing but the
17
+ /// rendered page would show.
18
+ @function state-opacity($state) {
19
+ @if not list.index($_state-layers, $state) {
20
+ @error "Unknown state layer #{$state}. Expected one of #{$_state-layers}.";
21
+ }
22
+ @return calc(var(--md-sys-state-#{$state}-state-layer-opacity) * 100%);
23
+ }
4
24
 
5
- // Common-button geometry. M3 default is 40dp, label-large, 20dp corners
6
- // (a stadium), 24dp inset, 8dp icon gap. Variants only change color/elevation.
25
+
26
+ // Common-button geometry. M3 Expressive's default size is small: 40dp,
27
+ // label-large, corner.full, 16dp inset, 8dp icon gap. The size axis moves
28
+ // those tokens; the style mixins only change color and elevation.
7
29
  @mixin btn(
8
30
  $height: var(--md-comp-filled-button-container-height, 40px),
9
- $border-radius: var(--md-comp-filled-button-container-shape, 20px),
10
- $padding-left: var(--md-comp-filled-button-leading-space, 24px),
11
- $padding-right: var(--md-comp-filled-button-trailing-space, 24px),
31
+ $border-radius: var(--md-comp-filled-button-container-shape, 9999px),
32
+ $padding-left: var(--md-comp-filled-button-leading-space, 16px),
33
+ $padding-right: var(--md-comp-filled-button-trailing-space, 16px),
12
34
  $font-size: var(--md-sys-typescale-label-large-font-size),
13
35
  ) {
14
36
  box-sizing: border-box;
@@ -36,8 +58,8 @@
36
58
  transition: background-color .2s ease-out, box-shadow .2s ease-out;
37
59
  }
38
60
 
39
- // State layers are 8% hover / 10% focus+press of the on-color, mixed in oklab
40
- // onto the container. Filled and tonal have no elevation.
61
+ // State layers mix the on-color into the container in oklab; the opacities come
62
+ // from md.sys.state via `state-opacity()`. Filled and tonal have no elevation.
41
63
 
42
64
  @mixin btn-filled {
43
65
  color: var(--md-comp-filled-button-label-text-color, var(--md-sys-color-on-primary));
@@ -46,7 +68,7 @@
46
68
  &:hover {
47
69
  background-color: color-mix(
48
70
  in oklab,
49
- var(--md-sys-color-on-primary) 8%,
71
+ var(--md-sys-color-on-primary) state-opacity("hover"),
50
72
  var(--md-sys-color-primary)
51
73
  );
52
74
  }
@@ -55,7 +77,7 @@
55
77
  &:focus {
56
78
  background-color: color-mix(
57
79
  in oklab,
58
- var(--md-sys-color-on-primary) 10%,
80
+ var(--md-sys-color-on-primary) state-opacity("focus"),
59
81
  var(--md-sys-color-primary)
60
82
  );
61
83
  }
@@ -70,7 +92,7 @@
70
92
  &:hover {
71
93
  background-color: color-mix(
72
94
  in oklab,
73
- var(--md-sys-color-on-secondary-container) 8%,
95
+ var(--md-sys-color-on-secondary-container) state-opacity("hover"),
74
96
  var(--md-sys-color-secondary-container)
75
97
  );
76
98
  }
@@ -79,7 +101,7 @@
79
101
  &:focus {
80
102
  background-color: color-mix(
81
103
  in oklab,
82
- var(--md-sys-color-on-secondary-container) 10%,
104
+ var(--md-sys-color-on-secondary-container) state-opacity("focus"),
83
105
  var(--md-sys-color-secondary-container)
84
106
  );
85
107
  }
@@ -94,13 +116,13 @@
94
116
 
95
117
  &:hover {
96
118
  @include z-depth("2");
97
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 8%, var(--md-sys-color-surface-container-low));
119
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("hover"), var(--md-sys-color-surface-container-low));
98
120
  }
99
121
 
100
122
  &:active,
101
123
  &:focus {
102
124
  @include z-depth("1");
103
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 10%, var(--md-sys-color-surface-container-low));
125
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("focus"), var(--md-sys-color-surface-container-low));
104
126
  }
105
127
 
106
128
  @include focus-visible();
@@ -109,15 +131,19 @@
109
131
  @mixin btn-outlined {
110
132
  background-color: transparent;
111
133
  color: var(--md-sys-color-primary);
112
- border: 1px solid var(--md-sys-color-outline);
134
+ // The width is not subtracted from the inset the way `.icon-button.outlined`
135
+ // subtracts it: there it keeps a round control as wide as it is tall, and a
136
+ // common button's width is its content's. `border-box` already keeps the
137
+ // height right.
138
+ border: var(--md-comp-filled-button-outline-width, 1px) solid var(--md-sys-color-outline);
113
139
 
114
140
  &:hover {
115
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 8%, transparent);
141
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("hover"), transparent);
116
142
  }
117
143
 
118
144
  &:active,
119
145
  &:focus {
120
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 10%, transparent);
146
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("focus"), transparent);
121
147
  }
122
148
 
123
149
  @include focus-visible();
@@ -130,12 +156,12 @@
130
156
  border-color: transparent;
131
157
 
132
158
  &:hover {
133
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 8%, transparent);
159
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("hover"), transparent);
134
160
  }
135
161
 
136
162
  &:active,
137
163
  &:focus {
138
- background-color: color-mix(in oklab, var(--md-sys-color-primary) 10%, transparent);
164
+ background-color: color-mix(in oklab, var(--md-sys-color-primary) state-opacity("focus"), transparent);
139
165
  }
140
166
 
141
167
  @include focus-visible();
@@ -151,21 +177,77 @@
151
177
  cursor: default;
152
178
  }
153
179
 
180
+ // Off the screen but not out of the document: still focusable, still read, and
181
+ // still a form control. `display: none` and `visibility: hidden` both take the
182
+ // element out of the tab order, which is the wrong trade for a control whose
183
+ // label is drawn elsewhere - a hidden radio that cannot be focused has no
184
+ // arrow-key model left.
185
+ //
186
+ // _chips.scss and _navigation-rail.scss each carry their own copy of this and
187
+ // predate the mixin; fold them in when either is next touched.
188
+ @mixin visually-hidden {
189
+ position: absolute;
190
+ width: 1px;
191
+ height: 1px;
192
+ margin: -1px;
193
+ padding: 0;
194
+ overflow: hidden;
195
+ clip-path: inset(50%);
196
+ white-space: nowrap;
197
+ }
198
+
154
199
  // Focus with Keyboard
200
+ // The ring itself, for the rare selector that cannot be written as
201
+ // `&:focus-visible` on the focused element - a filter chip draws its ring on
202
+ // the <label>, but the focus is on the checkbox before it.
203
+ @mixin focus-ring {
204
+ outline: 3px solid var(--md-sys-color-secondary);
205
+ outline-offset: 2px;
206
+ }
207
+
155
208
  @mixin focus-visible {
156
209
  &:focus-visible {
157
- outline: 3px solid var(--md-sys-color-secondary);
158
- outline-offset: 2px;
210
+ @include focus-ring();
159
211
  }
160
212
  }
161
213
 
162
214
  // M3 type role. Every property must name a token tokens/_reference.scss
163
215
  // actually defines — a missing var() drops the whole declaration.
164
216
  @mixin typescale($role) {
165
- font-family: var(--md-sys-typescale-#{$role}-font-family-name), #{$font-stack};
217
+ font-family: var(--md-sys-typescale-#{$role}-font-family-name);
166
218
  font-size: var(--md-sys-typescale-#{$role}-font-size);
167
219
  font-weight: var(--md-sys-typescale-#{$role}-font-weight);
168
220
  line-height: var(--md-sys-typescale-#{$role}-line-height);
169
221
  letter-spacing: var(--md-sys-typescale-#{$role}-letter-spacing);
170
222
  }
171
223
 
224
+ /// The state layer some controls draw as a ring rather than an overlay.
225
+ ///
226
+ /// Checkboxes and radio buttons have no room for an overlay pseudo-element, so
227
+ /// they grow a `box-shadow` from the control's edge out to the state layer
228
+ /// size. `color-mix()` wants a percentage where the token is a number, hence
229
+ /// the `* 100%`.
230
+ @mixin state-layer-ring($outer, $inner, $color, $state) {
231
+ box-shadow: 0 0 0 calc((#{$outer} - #{$inner}) / 2)
232
+ color-mix(
233
+ in oklab,
234
+ #{$color} state-opacity($state),
235
+ transparent
236
+ );
237
+ }
238
+
239
+ /// The button size tokens for one rung of `$button-sizes`.
240
+ ///
241
+ /// Tokens only. The type role is emitted beside the call, never from here:
242
+ /// `:root` takes this mixin for the default size, and a typescale on :root
243
+ /// would set the page's font.
244
+ @mixin button-size($name) {
245
+ $s: map.get($button-sizes, $name);
246
+
247
+ --md-comp-filled-button-container-height: #{map.get($s, height)};
248
+ --md-comp-filled-button-icon-size: #{map.get($s, icon)};
249
+ --md-comp-filled-button-leading-space: #{map.get($s, space)};
250
+ --md-comp-filled-button-trailing-space: #{map.get($s, space)};
251
+ --md-comp-filled-button-icon-label-space: #{map.get($s, gap)};
252
+ --md-comp-filled-button-outline-width: #{map.get($s, outline)};
253
+ }
@@ -1,5 +1,20 @@
1
1
  @use "sass:math";
2
2
 
3
+ // "Is this child an icon, or is it the label?" - a question several components
4
+ // ask, and every one of them used to answer it by element: <i> was the icon,
5
+ // <span> was the label. That broke the day the canonical icon became a <span>,
6
+ // silently, in five selectors at once: icon+label buttons lost their leading
7
+ // inset, icon-only toolbar actions stopped being 48dp circles and picked up the
8
+ // text-action pill instead.
9
+ //
10
+ // So the answer lives in one place. `i` stays in the list for markup written
11
+ // before 0.8.0. Interpolate it inside :is() - never as a bare comma list, which
12
+ // breaks out of its context (see $_bar in components/_navbar).
13
+ $icon: ":is(i, .material-symbols, .material-symbols-outlined, .material-symbols-rounded, .material-symbols-sharp, .material-icons)" !default;
14
+
15
+ // The label beside an icon: any span that is not itself an icon.
16
+ $icon-label: "span:not(.material-symbols):not(.material-symbols-outlined):not(.material-symbols-rounded):not(.material-symbols-sharp):not(.material-icons)" !default;
17
+
3
18
  // Colors
4
19
  //
5
20
  // The 2014 Material palette ($colors + colorFunc()) is gone. It generated 532
@@ -38,7 +53,7 @@ $menu-item-height: 50px !default;
38
53
 
39
54
  // Media query ranges now live in abstracts/_breakpoints.scss, which states
40
55
  // each boundary once and emits range syntax - see the note there about why
41
- // the 600.99px / 992.99px / 1200.99px values are gone.
56
+ // the old fractional max-width values are gone.
42
57
 
43
58
  // Grid
44
59
  $gutter-width: 1.5rem !default;
@@ -46,12 +61,14 @@ $element-top-margin: math.div($gutter-width, 3) !default;
46
61
  $element-bottom-margin: math.div($gutter-width * 2, 3) !default;
47
62
 
48
63
  // Typography
49
- $font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !default;
64
+ // M3's typeface tokens choose Roboto by default. Noto Sans is the first
65
+ // fallback so unsupported scripts keep a compatible visual style.
66
+ $font-stack: var(--md-ref-typeface-plain), var(--md-ref-typeface-fallback) !default;
50
67
  $text-color: var(--md-sys-color-on-background) !default;
51
68
 
52
- // Base of the html font-size ladder in base/_typography.scss. Flow text is
53
- // derived from it, so the two cannot drift.
54
- $root-font-size: 14px !default;
69
+ // Modern browsers default to 16px. M3's web conversion is SP_SIZE / 16 = rem;
70
+ // flow text uses the same basis without overriding the user's browser setting.
71
+ $root-font-size: 16px !default;
55
72
 
56
73
  // Flow text: font-size interpolates between these two across the viewport
57
74
  // range below. This used to be a @while loop emitting 21 media queries.
@@ -59,3 +76,31 @@ $flow-text-min: 1.2rem !default;
59
76
  $flow-text-max: 1.68rem !default; // the old loop's ceiling: 1.2rem * (1 + .02 * 20)
60
77
  $flow-text-from: 360px !default;
61
78
  $flow-text-to: 960px !default; // the old loop's last step: 360px + 20 * 30px
79
+
80
+ // The common-button size axis, md.comp.button.{xsmall…xlarge} (DSP 34.0.21).
81
+ //
82
+ // size height icon space gap label outline
83
+ // xsmall 32 20 12 8 label-large 1
84
+ // small 40 20 16 8 label-large 1 <- default
85
+ // medium 56 24 24 8 title-medium 1
86
+ // large 96 32 48 12 headline-small 2
87
+ // xlarge 136 40 64 16 headline-large 3
88
+ //
89
+ // `space` is both the leading and the trailing inset. Expressive dropped the
90
+ // old "24dp, but 16dp next to an icon" asymmetry, so a button is symmetric at
91
+ // every size, whatever is inside it. The round shape is corner.full at every
92
+ // size, so it is declared once by the component rather than five times here.
93
+ // `outline` is the one number the style axis reads back: M3 thickens an
94
+ // outlined button's border with its size.
95
+ //
96
+ // It lives in abstracts because two components read it - `_buttons.scss` for
97
+ // the size classes, `_button-groups.scss` to size the items of a group from
98
+ // the group itself. A partial may not @use another partial, so a table two of
99
+ // them share has to be here.
100
+ $button-sizes: (
101
+ "xsmall": (height: 32px, icon: 20px, space: 12px, gap: 8px, outline: 1px, label: "label-large"),
102
+ "small": (height: 40px, icon: 20px, space: 16px, gap: 8px, outline: 1px, label: "label-large"),
103
+ "medium": (height: 56px, icon: 24px, space: 24px, gap: 8px, outline: 1px, label: "title-medium"),
104
+ "large": (height: 96px, icon: 32px, space: 48px, gap: 12px, outline: 2px, label: "headline-small"),
105
+ "xlarge": (height: 136px, icon: 40px, space: 64px, gap: 16px, outline: 3px, label: "headline-large"),
106
+ );
@@ -35,30 +35,13 @@ a {
35
35
  // Blockquote
36
36
  blockquote { margin: 20px 0; padding-left: 1.5rem; border-left: 5px solid var(--md-sys-color-primary); }
37
37
 
38
- // Icon Styles
38
+ // <i> as an element - italics. The icon modifiers (.left, .right, .tiny ..)
39
+ // used to live here, keyed on `i`, which silently tied them to one element:
40
+ // writing an icon as the canonical <span class="material-symbols"> dropped
41
+ // them. They now hang off the icon class list in components/_icons-material-design,
42
+ // where the size modifiers already were, so they follow the class instead.
39
43
  i {
40
44
  line-height: inherit;
41
- &.left {
42
- float: left;
43
- margin-left: -8px;
44
- // margin-right: 15px;
45
- }
46
- &.right {
47
- float: right;
48
- // margin-left: 15px;
49
- }
50
- &.tiny {
51
- font-size: 1rem;
52
- }
53
- &.small {
54
- font-size: 2rem;
55
- }
56
- &.medium {
57
- font-size: 4rem;
58
- }
59
- &.large {
60
- font-size: 6rem;
61
- }
62
45
  }
63
46
 
64
47
  // Tables
@@ -113,7 +96,7 @@ td, th {
113
96
  }
114
97
 
115
98
  // Responsive Table
116
- @include bp-down("large") {
99
+ @include bp-down("expanded") {
117
100
 
118
101
  table.responsive-table {
119
102
  width: 100%;
@@ -178,4 +161,3 @@ td, th {
178
161
  }
179
162
  }
180
163
  }
181
-
@@ -1,15 +1,16 @@
1
1
  @use "../abstracts" as *;
2
2
 
3
- // 12-column CSS Grid. Prefixes map onto $breakpoints; s is the mobile
4
- // default (no query). xxl is M3 extra-large — the class that actually
5
- // sees a 4K or ultrawide window, since xlarge starts at 1201px.
3
+ // 12-column CSS Grid. The historical prefixes remain public markup, but each
4
+ // now maps exactly to an M3 window size class: s = Compact, m = Medium,
5
+ // l = Expanded, xl = Large, xxl = Extra-large. Compact is the default and
6
+ // therefore needs no media query.
6
7
  $grid-columns: 12;
7
8
  $grid-prefixes: (
8
9
  "s": null,
9
- "m": "small",
10
- "l": "large",
11
- "xl": "xlarge",
12
- "xxl": "xxlarge",
10
+ "m": "medium",
11
+ "l": "expanded",
12
+ "xl": "large",
13
+ "xxl": "extra-large",
13
14
  );
14
15
 
15
16
  @mixin grid-spans($prefix) {
@@ -33,13 +34,13 @@ $grid-prefixes: (
33
34
  max-width: var(--md-comp-container-max-width);
34
35
  }
35
36
 
36
- @include bp-up("small") {
37
+ @include bp-up("medium") {
37
38
  .container {
38
39
  --md-comp-container-width: 85%;
39
40
  }
40
41
  }
41
42
 
42
- @include bp-up("large") {
43
+ @include bp-up("expanded") {
43
44
  .container {
44
45
  --md-comp-container-width: 70%;
45
46
  }
@@ -49,7 +50,7 @@ $grid-prefixes: (
49
50
  // max-width snapped it back to 1280. Extra-large lifts the cap to 1920
50
51
  // (binds once 75% of the viewport exceeds it, around 2560) and opens
51
52
  // the measure a little so QHD lands on that cap instead of 1792.
52
- @include bp-up("xxlarge") {
53
+ @include bp-up("extra-large") {
53
54
  .container {
54
55
  --md-comp-container-width: 75%;
55
56
  --md-comp-container-max-width: 1920px;
@@ -70,10 +71,12 @@ $grid-prefixes: (
70
71
  padding: 1rem 0;
71
72
  }
72
73
 
73
- body {
74
+ // `:host` because a shadow tree has no `body` to hang this on, and `.row` reads
75
+ // it without a fallback - see adr/0002-shadow-only-stylesheet-adoption.md.
76
+ body, :host {
74
77
  --gap-size: #{$gutter-width};
75
78
 
76
- @include bp-up("xxlarge") {
79
+ @include bp-up("extra-large") {
77
80
  --gap-size: 2rem;
78
81
  }
79
82
  }
@@ -26,7 +26,36 @@
26
26
  //
27
27
  // Also simplified: `font-family: monospace, monospace` was a workaround for the
28
28
  // generic-family font-size quirk, which the adjacent `font-size: 1em` already
29
- // handles; and abbr's doubled text-decoration dropped its non-dotted fallback.
29
+ // handles.
30
+ //
31
+ // A second pass removed four more whose declarations both baseline engines now
32
+ // supply themselves, verbatim:
33
+ // abbr[title] { text-decoration: underline dotted } - already the UA value
34
+ // button, select { text-transform: none } - already `none` in both
35
+ // fieldset { padding: .35em .75em .625em } - restates the UA padding
36
+ // summary { display: list-item } - already list-item
37
+ //
38
+ // The rest of this file was measured against a bare page in both engines rather
39
+ // than assumed, and these are the results that keep a rule here. Do not remove
40
+ // them again without re-measuring - each one *looks* redundant and is not:
41
+ // b, strong { font-weight: bolder } UA is `bold` (700). `bolder` is relative,
42
+ // so it reaches 900 inside an already-bold
43
+ // parent where the UA value would stay 700.
44
+ // small { font-size: 80% } UA is `smaller`, which computes to
45
+ // 13.333px against a 16px parent, not 12.8.
46
+ // progress { vertical-align: baseline } UA is -3.2px, not baseline.
47
+ // legend { padding: 0 } UA has padding-left: 2px.
48
+ // [type="search"] { ... } UA is appearance:auto / outline-offset:0.
49
+ // sub, sup { ... } UA uses vertical-align: sub/super and no
50
+ // line-height reset; normalize's version is
51
+ // deliberately a different mechanism.
52
+ // code, kbd, samp, pre { font-size: 1em } UA applies the monospace font-size
53
+ // quirk (13px Chromium, 12px Firefox).
54
+ // hr { box-sizing: content-box } matches the UA, but base/_global.scss sets
55
+ // border-box globally and would override it.
56
+ // -webkit-appearance: button on the [type] selectors only - a Safari
57
+ // correction, and this file's policy is to
58
+ // keep those. `button` itself was dropped.
30
59
 
31
60
  /* Document
32
61
  ========================================================================== */
@@ -87,14 +116,6 @@ pre {
87
116
  /* Text-level semantics
88
117
  ========================================================================== */
89
118
 
90
- /**
91
- * Add the correct text decoration in Chrome, Edge, Opera, and Safari.
92
- */
93
-
94
- abbr[title] {
95
- text-decoration: underline dotted;
96
- }
97
-
98
119
  /**
99
120
  * Add the correct font weight in Chrome, Edge, and Safari.
100
121
  */
@@ -163,21 +184,15 @@ textarea {
163
184
  margin: 0; /* 2 */
164
185
  }
165
186
 
166
- /**
167
- * Remove the inheritance of text transform in Firefox.
168
- */
169
-
170
- button,
171
- select {
172
- text-transform: none;
173
- }
174
-
175
187
  /**
176
188
  * Correct the inability to style clickable types in iOS and Safari.
177
189
  * Kept prefixed: this is a WebKit correction, and Safari is what needs it.
190
+ *
191
+ * `button` is no longer in this list. The clickable *types* are what Safari
192
+ * renders unstyleable; a <button> element already renders as a button there,
193
+ * and normalize carried it out of caution.
178
194
  */
179
195
 
180
- button,
181
196
  [type="button"],
182
197
  [type="reset"],
183
198
  [type="submit"] {
@@ -193,14 +208,6 @@ legend {
193
208
  padding: 0;
194
209
  }
195
210
 
196
- /**
197
- * Correct the padding in Firefox.
198
- */
199
-
200
- fieldset {
201
- padding: 0.35em 0.75em 0.625em;
202
- }
203
-
204
211
  /**
205
212
  * Add the correct vertical alignment in Chrome, Firefox, and Opera.
206
213
  */
@@ -248,14 +255,3 @@ progress {
248
255
  -webkit-appearance: button; /* 1 */
249
256
  font: inherit; /* 2 */
250
257
  }
251
-
252
- /* Interactive
253
- ========================================================================== */
254
-
255
- /*
256
- * Add the correct display in all browsers.
257
- */
258
-
259
- summary {
260
- display: list-item;
261
- }
@@ -8,7 +8,7 @@
8
8
  // h1 display-small h2 headline-large h3 headline-medium
9
9
  // h4 headline-small h5 title-large h6 title-medium
10
10
  // p body-large small / figcaption body-small
11
- // body body-medium (matches the 14px root)
11
+ // body body-medium
12
12
  //
13
13
  // Display-large / display-medium stay as utility classes — they are too
14
14
  // large for a default <h1>. Component slots (app bar, card, dialog) set
@@ -18,23 +18,10 @@ html {
18
18
  font-family: $font-stack;
19
19
  font-weight: var(--md-sys-typescale-body-medium-font-weight);
20
20
  color: $text-color;
21
- font-size: $root-font-size;
22
-
23
- // Deliberately still a two-step ladder rather than a fluid clamp(): the root
24
- // font size is the basis of every rem in the sheet, so making it continuous
25
- // would move every computed length at every viewport width.
26
- @include bp-up("large") {
27
- font-size: 14.5px;
28
- }
29
-
30
- @include bp-up("xlarge") {
31
- font-size: 15px;
32
- }
33
21
  }
34
22
 
35
23
  body {
36
24
  @include typescale("body-medium");
37
- font-family: $font-stack;
38
25
  }
39
26
 
40
27
  h1 { @include typescale("display-small"); }
@@ -59,14 +46,12 @@ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
59
46
 
60
47
  p {
61
48
  @include typescale("body-large");
62
- font-family: $font-stack;
63
49
  margin: 0 0 1em;
64
50
  }
65
51
 
66
52
  small,
67
53
  figcaption {
68
54
  @include typescale("body-small");
69
- font-family: $font-stack;
70
55
  }
71
56
 
72
57
  em { font-style: italic; }
@@ -78,8 +63,9 @@ strong, b { font-weight: 500; }
78
63
  // 30px of viewport width from 360px to 960px. clamp() expresses the same line
79
64
  // as one declaration - and continuously, so the type no longer jumps.
80
65
  //
81
- // The whole fluid range sits below the "large" breakpoint, so 1rem is
82
- // $root-font-size throughout it and the conversion below is exact.
66
+ // M3 uses the browser's 16px default as the rem conversion basis. Do not set
67
+ // the root size here: leaving it to the browser preserves the user's preferred
68
+ // text size while the default computation remains exact.
83
69
  $_flow-min-px: math.div($flow-text-min, 1rem) * $root-font-size;
84
70
  $_flow-max-px: math.div($flow-text-max, 1rem) * $root-font-size;
85
71
  $_flow-slope: math.div($_flow-max-px - $_flow-min-px, $flow-text-to - $flow-text-from);
@@ -38,7 +38,6 @@
38
38
  white-space: nowrap;
39
39
  @include typescale("label-small");
40
40
  line-height: var(--md-comp-badge-large-size);
41
- font-family: $font-stack;
42
41
 
43
42
  // Small. No label — a 6dp dot.
44
43
  &:empty {
@@ -83,7 +82,7 @@
83
82
 
84
83
  // Trailing count in a list or drawer row stays in flow.
85
84
  .list .badge,
86
- .sidenav .badge,
85
+ :is(.sidenav, .navigation-drawer) .badge,
87
86
  menu .badge {
88
87
  position: static;
89
88
  transform: none;
@@ -93,6 +92,6 @@ menu .badge {
93
92
  margin-inline-start: auto;
94
93
  }
95
94
 
96
- .sidenav summary .badge {
95
+ :is(.sidenav, .navigation-drawer) summary .badge {
97
96
  margin-inline-start: 14px;
98
97
  }