@expressivecss/expressive 0.7.0-rc.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.
- package/CHANGELOG.md +1311 -1
- package/README.md +14 -11
- package/dist/css/expressive.css +4215 -1668
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/js/expressive.cjs +1231 -1253
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +1231 -1253
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +12 -12
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +1231 -1253
- package/dist/js/expressive.mjs.map +4 -4
- package/dist/types/behaviors/bottomSheets.d.ts +19 -11
- package/dist/types/behaviors/sheetDrag.d.ts +40 -0
- package/dist/types/behaviors/sideSheets.d.ts +2 -9
- package/dist/types/components/autocomplete.d.ts +15 -3
- package/dist/types/components/buttons.d.ts +5 -1
- package/dist/types/components/carousel.d.ts +87 -53
- package/dist/types/components/chips.d.ts +21 -1
- package/dist/types/components/expandingCard.d.ts +31 -0
- package/dist/types/components/index.d.ts +21 -20
- package/dist/types/components/lightbox.d.ts +1 -0
- package/dist/types/components/menu.d.ts +7 -1
- package/dist/types/components/{sidenav.d.ts → navigationDrawer.d.ts} +16 -16
- package/dist/types/components/registry.d.ts +8 -8
- package/dist/types/components/slider.d.ts +26 -85
- package/dist/types/components/snackbar.d.ts +20 -5
- package/dist/types/components/tabs.d.ts +12 -0
- package/dist/types/components/timepicker.d.ts +12 -9
- package/dist/types/core/utils.d.ts +64 -53
- package/dist/types/index.d.ts +8 -9
- package/package.json +15 -1
- package/src/sass/README.md +61 -11
- package/src/sass/abstracts/_breakpoints.scss +17 -19
- package/src/sass/abstracts/_mixins.scss +103 -21
- package/src/sass/abstracts/_variables.scss +50 -5
- package/src/sass/base/_global.scss +6 -24
- package/src/sass/base/_grid.scss +15 -12
- package/src/sass/base/_normalize.scss +34 -38
- package/src/sass/base/_typography.scss +4 -18
- package/src/sass/components/_badges.scss +2 -3
- package/src/sass/components/_banners.scss +298 -0
- package/src/sass/components/_bottom-app-bar.scss +180 -0
- package/src/sass/components/_bottom-sheet.scss +12 -4
- package/src/sass/components/_button-groups.scss +186 -0
- package/src/sass/components/_buttons.scss +245 -92
- package/src/sass/components/_cards.scss +494 -73
- package/src/sass/components/_carousel.scss +562 -68
- package/src/sass/components/_chips.scss +64 -5
- package/src/sass/components/_datepicker.scss +24 -24
- package/src/sass/components/_dialog.scss +17 -11
- package/src/sass/components/_drag-handle.scss +130 -0
- package/src/sass/components/_expanding-card.scss +260 -0
- package/src/sass/components/_fab-menu.scss +232 -0
- package/src/sass/components/_floating-sheet.scss +86 -0
- package/src/sass/components/_icon-buttons.scss +194 -0
- package/src/sass/components/_icons-material-design.scss +16 -4
- package/src/sass/components/_index.scss +22 -6
- package/src/sass/components/_list.scss +16 -13
- package/src/sass/components/_loading-indicator.scss +106 -0
- package/src/sass/components/_menu.scss +335 -61
- package/src/sass/components/_navbar.scss +71 -24
- package/src/sass/components/_navigation-bar.scss +13 -10
- package/src/sass/components/{_sidenav.scss → _navigation-drawer.scss} +123 -33
- package/src/sass/components/_navigation-rail.scss +22 -22
- package/src/sass/components/_page-footer.scss +19 -16
- package/src/sass/components/_pagination.scss +24 -6
- package/src/sass/components/_panes.scss +52 -11
- package/src/sass/components/{_preloader.scss → _progress.scss} +11 -3
- package/src/sass/components/_scrim.scss +37 -0
- package/src/sass/components/_search.scss +259 -0
- package/src/sass/components/_segmented-buttons.scss +188 -0
- package/src/sass/components/_side-sheet.scss +2 -2
- package/src/sass/components/_snackbar.scss +20 -15
- package/src/sass/components/_split-button.scss +196 -0
- package/src/sass/components/_tabs.scss +7 -8
- package/src/sass/components/_timepicker.scss +67 -58
- package/src/sass/components/_toolbar.scss +206 -80
- package/src/sass/components/forms/_checkboxes.scss +49 -12
- package/src/sass/components/forms/_fieldset.scss +4 -4
- package/src/sass/components/forms/_file-input.scss +8 -1
- package/src/sass/components/forms/_index.scss +1 -1
- package/src/sass/components/forms/_input-fields.scss +50 -44
- package/src/sass/components/forms/_radio-buttons.scss +42 -10
- package/src/sass/components/forms/_select.scss +0 -1
- package/src/sass/components/forms/{_range.scss → _slider.scss} +8 -9
- package/src/sass/components/forms/_switches.scss +6 -7
- package/src/sass/tokens/_index.scss +4 -1
- package/src/sass/tokens/_reference.scss +70 -61
- package/src/sass/tokens/_state.scss +24 -0
- package/src/sass/tokens/_theme.scss +6 -3
- package/src/sass/tokens/_vibrant.scss +76 -0
- package/src/sass/utilities/_colors.scss +14 -1
- package/src/sass/utilities/_helpers.scss +5 -5
- package/src/sass/utilities/_visibility.scss +48 -26
- package/dist/types/behaviors/waves.d.ts +0 -15
- package/dist/types/components/parallax.d.ts +0 -16
- package/dist/types/components/range.d.ts +0 -43
- package/dist/types/core/bounding.d.ts +0 -6
- package/dist/types/core/edges.d.ts +0 -6
- package/src/sass/components/_parallax.scss +0 -104
- package/src/sass/components/_pulse.scss +0 -37
- package/src/sass/components/_slider.scss +0 -129
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
// Cards.
|
|
4
4
|
//
|
|
5
5
|
// Anatomy is the HTML. An <article> is an elevated card. A heading is the
|
|
6
|
-
// headline, a <p> is supporting text,
|
|
7
|
-
// action row
|
|
8
|
-
//
|
|
9
|
-
//
|
|
6
|
+
// headline, .subhead is the subhead, a <p> is supporting text, direct media
|
|
7
|
+
// is <img> / <picture> / <figure>, and direct .actions is the action row.
|
|
8
|
+
// Helpers switch the M3 variant (filled, outlined) or the layout
|
|
9
|
+
// (horizontal).
|
|
10
10
|
//
|
|
11
11
|
// Tokens follow https://m3.material.io/components/cards/specs
|
|
12
12
|
// container surface-container-low, 12dp corners
|
|
13
|
-
// elevated level 1
|
|
14
|
-
// filled surface-container-highest, level 0
|
|
15
|
-
// outlined surface + 1dp outline, level 0
|
|
13
|
+
// elevated level 1; interactive hover level 2
|
|
14
|
+
// filled surface-container-highest, level 0; interactive hover level 1
|
|
15
|
+
// outlined surface + 1dp outline, level 0; interactive hover level 1
|
|
16
16
|
// headline title-medium / on-surface
|
|
17
17
|
// body body-medium / on-surface-variant
|
|
18
18
|
// padding 16dp
|
|
@@ -21,65 +21,222 @@ $_card: "article";
|
|
|
21
21
|
|
|
22
22
|
:where(#{$_card}) {
|
|
23
23
|
--md-comp-elevated-card-container-color: var(--md-sys-color-surface-container-low);
|
|
24
|
-
--md-comp-
|
|
24
|
+
--md-comp-filled-card-container-color: var(--md-sys-color-surface-container-highest);
|
|
25
|
+
--md-comp-outlined-card-container-color: var(--md-sys-color-surface);
|
|
26
|
+
--md-comp-outlined-card-outline-color: var(--md-sys-color-outline-variant);
|
|
27
|
+
--md-comp-outlined-card-disabled-outline-color: var(--md-sys-color-outline);
|
|
28
|
+
--md-comp-card-container-color: var(--md-comp-elevated-card-container-color);
|
|
29
|
+
--md-comp-card-container-shape: 12px;
|
|
30
|
+
--md-comp-card-media-shape: var(--md-comp-card-container-shape);
|
|
31
|
+
--md-comp-card-media-overlay-container-color: var(--md-sys-color-surface);
|
|
32
|
+
--md-comp-card-media-overlay-ink-color: var(--md-sys-color-on-surface);
|
|
33
|
+
--md-comp-card-media-overlay-shape: 8px;
|
|
34
|
+
--md-comp-card-headline-color: var(--md-sys-color-on-surface);
|
|
35
|
+
--md-comp-card-subhead-color: var(--md-sys-color-on-surface);
|
|
36
|
+
--md-comp-card-supporting-text-color: var(--md-sys-color-on-surface-variant);
|
|
37
|
+
--md-comp-card-content-padding: 16px;
|
|
38
|
+
--md-comp-card-between-space: 8px;
|
|
39
|
+
--md-comp-card-icon-color: var(--md-sys-color-primary);
|
|
40
|
+
--md-comp-card-icon-size: 24px;
|
|
41
|
+
--md-comp-card-state-layer-color: var(--md-sys-color-on-surface);
|
|
42
|
+
--md-comp-card-hover-state-layer-opacity: var(--md-sys-state-hover-state-layer-opacity);
|
|
43
|
+
--md-comp-card-focus-state-layer-opacity: var(--md-sys-state-focus-state-layer-opacity);
|
|
44
|
+
--md-comp-card-pressed-state-layer-opacity: var(--md-sys-state-pressed-state-layer-opacity);
|
|
45
|
+
--md-comp-card-dragged-state-layer-opacity: var(--md-sys-state-dragged-state-layer-opacity);
|
|
46
|
+
--md-comp-card-disabled-container-opacity: 38%;
|
|
47
|
+
--md-comp-outlined-card-disabled-outline-opacity: 12%;
|
|
48
|
+
--md-comp-card-focus-indicator-color: var(--md-sys-color-secondary);
|
|
49
|
+
--md-comp-card-focus-indicator-thickness: 3px;
|
|
50
|
+
--md-comp-card-focus-indicator-offset: 2px;
|
|
51
|
+
--md-comp-card-horizontal-media-width: 40%;
|
|
52
|
+
--md-comp-card-horizontal-min-height: 240px;
|
|
25
53
|
|
|
26
54
|
position: relative;
|
|
27
55
|
box-sizing: border-box;
|
|
28
|
-
background-color: var(--md-comp-
|
|
56
|
+
background-color: var(--md-comp-card-container-color);
|
|
29
57
|
color: var(--md-sys-color-on-surface);
|
|
30
|
-
border-radius: var(--md-comp-
|
|
58
|
+
border-radius: var(--md-comp-card-container-shape);
|
|
31
59
|
overflow: hidden;
|
|
32
|
-
transition: box-shadow .2s ease-out;
|
|
60
|
+
transition: background-color .2s ease-out, box-shadow .2s ease-out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// M3 state layers belong only to an interactive card. A direct
|
|
64
|
+
// `.primary-action` link supplies the card's large action area without making
|
|
65
|
+
// secondary buttons invalid nested controls.
|
|
66
|
+
:where(#{$_card})::after {
|
|
67
|
+
content: "";
|
|
68
|
+
position: absolute;
|
|
69
|
+
inset: 0;
|
|
70
|
+
z-index: 2;
|
|
71
|
+
border-radius: inherit;
|
|
72
|
+
background-color: var(--md-comp-card-state-layer-color);
|
|
73
|
+
opacity: 0;
|
|
74
|
+
pointer-events: none;
|
|
75
|
+
transition: opacity .2s ease-out;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
:where(#{$_card}) > .primary-action {
|
|
79
|
+
display: block;
|
|
80
|
+
color: inherit;
|
|
81
|
+
border-radius: inherit;
|
|
82
|
+
outline: 0;
|
|
33
83
|
}
|
|
34
84
|
|
|
35
85
|
// Default is elevated. :where() keeps specificity at zero so .outlined wins.
|
|
36
86
|
:where(#{$_card}):not(.filled, .outlined, .border) {
|
|
37
87
|
@include z-depth("1");
|
|
38
|
-
|
|
39
|
-
&:hover {
|
|
40
|
-
@include z-depth("2");
|
|
41
|
-
}
|
|
42
88
|
}
|
|
43
89
|
|
|
44
90
|
:where(#{$_card}).filled {
|
|
91
|
+
--md-comp-card-container-color: var(--md-comp-filled-card-container-color);
|
|
45
92
|
@include z-depth("0");
|
|
46
|
-
background-color: var(--md-sys-color-surface-container-highest);
|
|
47
93
|
}
|
|
48
94
|
|
|
49
95
|
:where(#{$_card}).outlined,
|
|
50
96
|
:where(#{$_card}).border {
|
|
97
|
+
--md-comp-card-container-color: var(--md-comp-outlined-card-container-color);
|
|
98
|
+
@include z-depth("0");
|
|
99
|
+
border: 1px solid var(--md-comp-outlined-card-outline-color);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Hovered cards lift one level and apply an 8% on-surface state layer.
|
|
103
|
+
:where(#{$_card}):not(.filled, .outlined, .border):has(> .primary-action:hover) {
|
|
104
|
+
@include z-depth("2");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
:where(#{$_card}):is(.filled, .outlined, .border):has(> .primary-action:hover) {
|
|
108
|
+
@include z-depth("1");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
:where(#{$_card}):has(> .primary-action:hover)::after {
|
|
112
|
+
opacity: var(--md-comp-card-hover-state-layer-opacity);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Focus and press retain their variant elevation. Focus gets M3's external
|
|
116
|
+
// 3dp indicator at a 2dp offset; the outlined variant also darkens its stroke.
|
|
117
|
+
:where(#{$_card}):has(> .primary-action:focus-visible) {
|
|
118
|
+
outline: var(--md-comp-card-focus-indicator-thickness) solid var(--md-comp-card-focus-indicator-color);
|
|
119
|
+
outline-offset: var(--md-comp-card-focus-indicator-offset);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
:where(#{$_card}):has(> .primary-action:focus-visible)::after {
|
|
123
|
+
opacity: var(--md-comp-card-focus-state-layer-opacity);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
:where(#{$_card}):is(.outlined, .border):has(> .primary-action:focus-visible) {
|
|
127
|
+
border-color: var(--md-sys-color-on-surface);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
:where(#{$_card}):has(> .primary-action:active)::after {
|
|
131
|
+
opacity: var(--md-comp-card-pressed-state-layer-opacity);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// A reorder interaction toggles `.dragged`; every variant rises to level 3.
|
|
135
|
+
:where(#{$_card}).dragged {
|
|
136
|
+
@include z-depth("3");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:where(#{$_card}).dragged::after {
|
|
140
|
+
opacity: var(--md-comp-card-dragged-state-layer-opacity);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Disabled tokens differ by variant in M3. `aria-disabled` belongs on the
|
|
144
|
+
// primary action; `.disabled` / article[aria-disabled] cover app-controlled
|
|
145
|
+
// cards that do not use a link.
|
|
146
|
+
:where(#{$_card}):is(.disabled, [aria-disabled="true"]),
|
|
147
|
+
:where(#{$_card}):has(> .primary-action[aria-disabled="true"]) {
|
|
51
148
|
@include z-depth("0");
|
|
52
|
-
|
|
149
|
+
outline: 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
:where(#{$_card}):not(.filled, .outlined, .border):is(.disabled, [aria-disabled="true"]),
|
|
153
|
+
:where(#{$_card}):not(.filled, .outlined, .border):has(> .primary-action[aria-disabled="true"]) {
|
|
154
|
+
background-color: color-mix(
|
|
155
|
+
in oklab,
|
|
156
|
+
var(--md-sys-color-surface) var(--md-comp-card-disabled-container-opacity),
|
|
157
|
+
transparent
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
:where(#{$_card}).filled:is(.disabled, [aria-disabled="true"]),
|
|
162
|
+
:where(#{$_card}).filled:has(> .primary-action[aria-disabled="true"]) {
|
|
163
|
+
background-color: color-mix(
|
|
164
|
+
in oklab,
|
|
165
|
+
var(--md-sys-color-on-surface) var(--md-comp-card-disabled-container-opacity),
|
|
166
|
+
transparent
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
:where(#{$_card}):is(.outlined, .border):is(.disabled, [aria-disabled="true"]),
|
|
171
|
+
:where(#{$_card}):is(.outlined, .border):has(> .primary-action[aria-disabled="true"]) {
|
|
172
|
+
background-color: var(--md-comp-outlined-card-container-color);
|
|
173
|
+
border-color: color-mix(
|
|
174
|
+
in oklab,
|
|
175
|
+
var(--md-comp-outlined-card-disabled-outline-color) var(--md-comp-outlined-card-disabled-outline-opacity),
|
|
176
|
+
transparent
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
:where(#{$_card}):is(.disabled, [aria-disabled="true"])::after,
|
|
181
|
+
:where(#{$_card}):has(> .primary-action[aria-disabled="true"])::after {
|
|
182
|
+
opacity: 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
:where(#{$_card}).disabled,
|
|
186
|
+
:where(#{$_card})[aria-disabled="true"],
|
|
187
|
+
:where(#{$_card}) > .primary-action[aria-disabled="true"] {
|
|
188
|
+
pointer-events: none;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
:where(#{$_card}) .card-icon {
|
|
192
|
+
width: var(--md-comp-card-icon-size);
|
|
193
|
+
height: var(--md-comp-card-icon-size);
|
|
194
|
+
color: var(--md-comp-card-icon-color);
|
|
195
|
+
font-size: var(--md-comp-card-icon-size);
|
|
53
196
|
}
|
|
54
197
|
|
|
55
198
|
// --- Semantic children ----------------------------------------------------
|
|
56
199
|
|
|
57
200
|
article > :is(h1, h2, h3, h4, h5, h6),
|
|
58
|
-
article > header > :is(h1, h2, h3, h4, h5, h6) {
|
|
201
|
+
article > :is(header, .primary-action) > :is(h1, h2, h3, h4, h5, h6) {
|
|
59
202
|
margin: 0;
|
|
60
|
-
padding:
|
|
203
|
+
padding: var(--md-comp-card-content-padding) var(--md-comp-card-content-padding) 0;
|
|
61
204
|
font-family: var(--md-sys-typescale-title-medium-font-family-name);
|
|
62
205
|
font-size: var(--md-sys-typescale-title-medium-font-size);
|
|
63
206
|
font-weight: var(--md-sys-typescale-title-medium-font-weight);
|
|
64
207
|
line-height: var(--md-sys-typescale-title-medium-line-height);
|
|
65
208
|
letter-spacing: var(--md-sys-typescale-title-medium-letter-spacing);
|
|
66
|
-
color: var(--md-
|
|
209
|
+
color: var(--md-comp-card-headline-color);
|
|
67
210
|
}
|
|
68
211
|
|
|
69
212
|
article > p,
|
|
70
|
-
article > header > p {
|
|
213
|
+
article > :is(header, .primary-action) > p {
|
|
71
214
|
margin: 0;
|
|
72
|
-
padding:
|
|
215
|
+
padding: var(--md-comp-card-between-space) var(--md-comp-card-content-padding) var(--md-comp-card-content-padding);
|
|
73
216
|
font-family: var(--md-sys-typescale-body-medium-font-family-name);
|
|
74
217
|
font-size: var(--md-sys-typescale-body-medium-font-size);
|
|
75
218
|
font-weight: var(--md-sys-typescale-body-medium-font-weight);
|
|
76
219
|
line-height: var(--md-sys-typescale-body-medium-line-height);
|
|
77
220
|
letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing);
|
|
78
|
-
color: color
|
|
221
|
+
color: var(--md-comp-card-supporting-text-color);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Optional subhead between the headline and supporting copy. Keep the class
|
|
225
|
+
// on a paragraph so the document retains useful reading semantics.
|
|
226
|
+
article > p.subhead,
|
|
227
|
+
article > :is(header, .primary-action) > p.subhead {
|
|
228
|
+
margin: 0;
|
|
229
|
+
padding: 4px var(--md-comp-card-content-padding) 0;
|
|
230
|
+
font-family: var(--md-sys-typescale-title-small-font-family-name);
|
|
231
|
+
font-size: var(--md-sys-typescale-title-small-font-size);
|
|
232
|
+
font-weight: var(--md-sys-typescale-title-small-font-weight);
|
|
233
|
+
line-height: var(--md-sys-typescale-title-small-line-height);
|
|
234
|
+
letter-spacing: var(--md-sys-typescale-title-small-letter-spacing);
|
|
235
|
+
color: var(--md-comp-card-subhead-color);
|
|
79
236
|
}
|
|
80
237
|
|
|
81
238
|
article > :is(h1, h2, h3, h4, h5, h6) + p,
|
|
82
|
-
article > header > :is(h1, h2, h3, h4, h5, h6) + p {
|
|
239
|
+
article > :is(header, .primary-action) > :is(h1, h2, h3, h4, h5, h6) + p {
|
|
83
240
|
padding-top: 0;
|
|
84
241
|
}
|
|
85
242
|
|
|
@@ -89,63 +246,204 @@ article > header {
|
|
|
89
246
|
color: inherit;
|
|
90
247
|
}
|
|
91
248
|
|
|
92
|
-
// Action row.
|
|
93
|
-
article >
|
|
249
|
+
// Action row. A row of buttons, not destinations.
|
|
250
|
+
article > .actions {
|
|
251
|
+
position: relative;
|
|
252
|
+
z-index: 3;
|
|
94
253
|
display: flex;
|
|
95
254
|
flex-wrap: wrap;
|
|
96
255
|
align-items: center;
|
|
97
|
-
gap:
|
|
256
|
+
gap: var(--md-comp-card-between-space);
|
|
98
257
|
padding: 4px 8px 8px 8px;
|
|
99
258
|
margin: 0;
|
|
100
259
|
}
|
|
101
260
|
|
|
102
261
|
article > img,
|
|
103
262
|
article > picture,
|
|
104
|
-
article > figure
|
|
263
|
+
article > figure,
|
|
264
|
+
article > .primary-action > img,
|
|
265
|
+
article > .primary-action > picture,
|
|
266
|
+
article > .primary-action > figure {
|
|
105
267
|
display: block;
|
|
106
268
|
width: 100%;
|
|
107
269
|
margin: 0;
|
|
270
|
+
border-radius: var(--md-comp-card-media-shape);
|
|
271
|
+
overflow: hidden;
|
|
108
272
|
}
|
|
109
273
|
|
|
110
274
|
article > img,
|
|
111
275
|
article > picture img,
|
|
112
|
-
article > figure img
|
|
276
|
+
article > figure img,
|
|
277
|
+
article > .primary-action > img,
|
|
278
|
+
article > .primary-action > picture img,
|
|
279
|
+
article > .primary-action > figure img {
|
|
113
280
|
display: block;
|
|
114
281
|
width: 100%;
|
|
115
282
|
object-fit: cover;
|
|
283
|
+
border-radius: var(--md-comp-card-media-shape);
|
|
116
284
|
}
|
|
117
285
|
|
|
118
286
|
article > figure {
|
|
119
287
|
position: relative;
|
|
120
288
|
}
|
|
121
289
|
|
|
122
|
-
article >
|
|
290
|
+
article > .primary-action > figure {
|
|
291
|
+
position: relative;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
article > figure > figcaption,
|
|
295
|
+
article > .primary-action > figure > figcaption {
|
|
123
296
|
position: absolute;
|
|
124
|
-
inset-inline:
|
|
125
|
-
|
|
297
|
+
inset-inline-start: var(--md-comp-card-content-padding);
|
|
298
|
+
inset-inline-end: auto;
|
|
299
|
+
bottom: var(--md-comp-card-content-padding);
|
|
300
|
+
display: inline-flex;
|
|
301
|
+
align-items: center;
|
|
302
|
+
gap: var(--md-comp-card-between-space);
|
|
303
|
+
box-sizing: border-box;
|
|
304
|
+
width: fit-content;
|
|
305
|
+
max-width: calc(100% - (2 * var(--md-comp-card-content-padding)));
|
|
126
306
|
margin: 0;
|
|
127
|
-
padding:
|
|
128
|
-
color: var(--md-
|
|
129
|
-
background:
|
|
307
|
+
padding: 8px 12px;
|
|
308
|
+
color: var(--md-comp-card-media-overlay-ink-color);
|
|
309
|
+
background-color: var(--md-comp-card-media-overlay-container-color);
|
|
310
|
+
border-radius: var(--md-comp-card-media-overlay-shape);
|
|
130
311
|
font-family: var(--md-sys-typescale-title-medium-font-family-name);
|
|
131
312
|
font-size: var(--md-sys-typescale-title-medium-font-size);
|
|
132
313
|
font-weight: var(--md-sys-typescale-title-medium-font-weight);
|
|
133
314
|
line-height: var(--md-sys-typescale-title-medium-line-height);
|
|
134
315
|
}
|
|
135
316
|
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
317
|
+
// Keep meaningful icons on the same opaque role pair as caption text. The
|
|
318
|
+
// surface/on-surface pairing isolates both from unpredictable image colors.
|
|
319
|
+
article > figure > figcaption > :is(.material-symbols, .card-icon, svg),
|
|
320
|
+
article > .primary-action > figure > figcaption > :is(.material-symbols, .card-icon, svg) {
|
|
321
|
+
flex: 0 0 auto;
|
|
322
|
+
color: inherit;
|
|
323
|
+
font-size: var(--md-comp-card-icon-size);
|
|
324
|
+
line-height: 1;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
article > figure > figcaption > svg,
|
|
328
|
+
article > .primary-action > figure > figcaption > svg {
|
|
329
|
+
fill: currentColor;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Collections are a grid by default. The full track definition is a token so
|
|
333
|
+
// applications can supply fixed, responsive, or asymmetric columns without
|
|
334
|
+
// fighting component selectors. Every card rests on the same plane; only the
|
|
335
|
+
// picked-up / dragged state rises above its neighbours.
|
|
336
|
+
:where(.card-collection) {
|
|
337
|
+
--md-comp-card-collection-gap: 8px;
|
|
338
|
+
--md-comp-card-collection-min-card-width: 240px;
|
|
339
|
+
--md-comp-card-collection-grid-template-columns: repeat(
|
|
340
|
+
auto-fit,
|
|
341
|
+
minmax(min(100%, var(--md-comp-card-collection-min-card-width)), 1fr)
|
|
342
|
+
);
|
|
343
|
+
--md-comp-card-collection-resting-shadow: none;
|
|
344
|
+
--md-comp-card-collection-picked-up-shadow:
|
|
345
|
+
0 8px 17px 2px rgba(0, 0, 0, 0.14),
|
|
346
|
+
0 3px 14px 2px rgba(0, 0, 0, 0.12),
|
|
347
|
+
0 5px 5px -3px rgba(0, 0, 0, 0.2);
|
|
348
|
+
--md-comp-card-collection-mosaic-row-size: 80px;
|
|
349
|
+
--md-comp-card-collection-carousel-height: 320px;
|
|
350
|
+
--md-comp-card-collection-carousel-card-width: min(82%, 360px);
|
|
351
|
+
|
|
352
|
+
display: grid;
|
|
353
|
+
grid-template-columns: var(--md-comp-card-collection-grid-template-columns);
|
|
354
|
+
gap: var(--md-comp-card-collection-gap);
|
|
140
355
|
align-items: stretch;
|
|
356
|
+
margin: 0;
|
|
357
|
+
padding: 0;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
:where(.card-collection article):not(.dragged, .picked-up) {
|
|
361
|
+
box-shadow: var(--md-comp-card-collection-resting-shadow) !important;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
:where(.card-collection article):is(.dragged, .picked-up) {
|
|
365
|
+
z-index: 4;
|
|
366
|
+
box-shadow: var(--md-comp-card-collection-picked-up-shadow) !important;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
:where(.card-collection article):not(.horizontal) {
|
|
370
|
+
display: flex;
|
|
371
|
+
flex-direction: column;
|
|
372
|
+
min-width: 0;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
:where(.card-collection article):not(.horizontal) > .actions {
|
|
376
|
+
margin-block-start: auto;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// A list is the same collection with one column. The cards retain their own
|
|
380
|
+
// vertical / horizontal orientation.
|
|
381
|
+
.card-collection.list {
|
|
382
|
+
--md-comp-card-collection-grid-template-columns: minmax(0, 1fr);
|
|
383
|
+
|
|
384
|
+
margin: 0;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Staggered uses multicolumn flow for masonry-like intrinsic card heights.
|
|
388
|
+
:where(.card-collection.staggered) {
|
|
389
|
+
display: block;
|
|
390
|
+
columns: var(
|
|
391
|
+
--md-comp-card-collection-staggered-column-width,
|
|
392
|
+
var(--md-comp-card-collection-min-card-width)
|
|
393
|
+
);
|
|
394
|
+
column-gap: var(--md-comp-card-collection-gap);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
:where(.card-collection.staggered) > article {
|
|
398
|
+
break-inside: avoid;
|
|
399
|
+
width: 100%;
|
|
400
|
+
margin-block: 0 var(--md-comp-card-collection-gap);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Mosaic keeps source order in a dense grid. Per-card custom properties make
|
|
404
|
+
// spans data-driven instead of baking a decorative nth-child pattern into the
|
|
405
|
+
// framework.
|
|
406
|
+
:where(.card-collection.mosaic) {
|
|
407
|
+
grid-auto-flow: dense;
|
|
408
|
+
grid-auto-rows: var(--md-comp-card-collection-mosaic-row-size);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
:where(.card-collection.mosaic) > article {
|
|
412
|
+
grid-column: span var(--md-comp-card-collection-column-span, 1);
|
|
413
|
+
grid-row: span var(--md-comp-card-collection-row-span, 2);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Reuse the M3 uncontained Carousel for a horizontally scrolling collection.
|
|
417
|
+
// Carousel.Init()/AutoInit() supplies the track and interaction behavior.
|
|
418
|
+
.card-collection.carousel {
|
|
419
|
+
--carousel-height: var(--md-comp-card-collection-carousel-height);
|
|
420
|
+
--md-comp-carousel-gap: var(--md-comp-card-collection-gap);
|
|
421
|
+
--md-comp-carousel-uncontained-item-width: var(
|
|
422
|
+
--md-comp-card-collection-carousel-card-width
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
display: block;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Horizontal uses the same direct semantic slots as the vertical card. Grid
|
|
429
|
+
// moves the media to the start and stacks headline, subhead, supporting text,
|
|
430
|
+
// and actions beside it without requiring a second content wrapper.
|
|
431
|
+
article.horizontal {
|
|
432
|
+
display: grid;
|
|
433
|
+
grid-template-columns:
|
|
434
|
+
minmax(0, var(--md-comp-card-horizontal-media-width))
|
|
435
|
+
minmax(0, 1fr);
|
|
436
|
+
grid-template-rows: auto auto minmax(0, 1fr) auto;
|
|
437
|
+
min-height: var(--md-comp-card-horizontal-min-height);
|
|
141
438
|
overflow: hidden;
|
|
142
439
|
|
|
143
440
|
> img,
|
|
144
441
|
> picture,
|
|
145
442
|
> figure {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
width:
|
|
443
|
+
grid-column: 1;
|
|
444
|
+
grid-row: 1 / -1;
|
|
445
|
+
width: 100%;
|
|
446
|
+
height: 100%;
|
|
149
447
|
align-self: stretch;
|
|
150
448
|
}
|
|
151
449
|
|
|
@@ -156,11 +454,27 @@ article.horizontal {
|
|
|
156
454
|
object-fit: cover;
|
|
157
455
|
}
|
|
158
456
|
|
|
159
|
-
>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
457
|
+
> :is(h1, h2, h3, h4, h5, h6),
|
|
458
|
+
> header {
|
|
459
|
+
grid-column: 2;
|
|
460
|
+
grid-row: 1;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
> p.subhead {
|
|
464
|
+
grid-column: 2;
|
|
465
|
+
grid-row: 2;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
> p:not(.subhead) {
|
|
469
|
+
grid-column: 2;
|
|
470
|
+
grid-row: 3;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
> .actions {
|
|
474
|
+
grid-column: 2;
|
|
475
|
+
grid-row: 4;
|
|
476
|
+
align-self: end;
|
|
477
|
+
justify-content: flex-end;
|
|
164
478
|
}
|
|
165
479
|
}
|
|
166
480
|
|
|
@@ -189,7 +503,7 @@ article.small, article.medium, article.large {
|
|
|
189
503
|
overflow: hidden;
|
|
190
504
|
}
|
|
191
505
|
|
|
192
|
-
>
|
|
506
|
+
> .actions {
|
|
193
507
|
margin-top: auto;
|
|
194
508
|
}
|
|
195
509
|
}
|
|
@@ -197,44 +511,156 @@ article.small, article.medium, article.large {
|
|
|
197
511
|
article.horizontal.small,
|
|
198
512
|
article.horizontal.medium,
|
|
199
513
|
article.horizontal.large {
|
|
200
|
-
|
|
514
|
+
display: grid;
|
|
201
515
|
|
|
202
516
|
> img, > picture, > figure {
|
|
203
|
-
flex: 0 0 40%;
|
|
204
517
|
max-height: none;
|
|
205
518
|
}
|
|
206
519
|
}
|
|
207
520
|
|
|
208
|
-
// Reveal
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
|
|
521
|
+
// Reveal panel. The summary and media remain in place while the card grows
|
|
522
|
+
// downward to expose additional actions, matching the M3 expand/collapse
|
|
523
|
+
// example. `interpolate-size` lets intrinsic content height animate without a
|
|
524
|
+
// fixed cap; the @supports fallback keeps the interaction functional.
|
|
525
|
+
:where(#{$_card}):has(> aside) {
|
|
526
|
+
interpolate-size: allow-keywords;
|
|
527
|
+
}
|
|
528
|
+
|
|
213
529
|
article > aside {
|
|
214
|
-
--md-comp-card-reveal-duration:
|
|
215
|
-
--md-comp-card-reveal-easing:
|
|
530
|
+
--md-comp-card-reveal-duration: 500ms;
|
|
531
|
+
--md-comp-card-reveal-easing: cubic-bezier(0.2, 0, 0, 1);
|
|
216
532
|
|
|
217
|
-
position:
|
|
218
|
-
inset:
|
|
219
|
-
z-index:
|
|
533
|
+
position: relative;
|
|
534
|
+
inset: auto;
|
|
535
|
+
z-index: 1;
|
|
220
536
|
box-sizing: border-box;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
537
|
+
height: 0;
|
|
538
|
+
min-height: 0;
|
|
539
|
+
padding: 0 var(--md-comp-card-content-padding);
|
|
540
|
+
overflow: clip;
|
|
541
|
+
background-color: inherit;
|
|
224
542
|
color: var(--md-sys-color-on-surface);
|
|
225
|
-
|
|
543
|
+
opacity: 0;
|
|
226
544
|
visibility: hidden;
|
|
227
545
|
pointer-events: none;
|
|
228
546
|
transition:
|
|
229
|
-
|
|
547
|
+
height var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
548
|
+
padding-block var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
549
|
+
opacity 150ms ease-out,
|
|
230
550
|
visibility 0s var(--md-comp-card-reveal-duration);
|
|
231
551
|
}
|
|
232
552
|
|
|
233
553
|
article > aside[aria-expanded="true"] {
|
|
234
|
-
|
|
554
|
+
height: auto;
|
|
555
|
+
padding-block: 0 var(--md-comp-card-content-padding);
|
|
556
|
+
opacity: 1;
|
|
235
557
|
visibility: visible;
|
|
236
558
|
pointer-events: auto;
|
|
237
|
-
transition:
|
|
559
|
+
transition:
|
|
560
|
+
height var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
561
|
+
padding-block var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
562
|
+
opacity 200ms 100ms ease-out,
|
|
563
|
+
visibility 0s;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
@supports not (interpolate-size: allow-keywords) {
|
|
567
|
+
article > aside {
|
|
568
|
+
height: auto;
|
|
569
|
+
max-height: 0;
|
|
570
|
+
transition:
|
|
571
|
+
max-height var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
572
|
+
padding-block var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
573
|
+
opacity 150ms ease-out,
|
|
574
|
+
visibility 0s var(--md-comp-card-reveal-duration);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
article > aside[aria-expanded="true"] {
|
|
578
|
+
max-height: var(--md-comp-card-reveal-fallback-height, 320px);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// A media-sized button supplies the repeated open/close target and carries the
|
|
583
|
+
// state layer for the tap feedback shown by the M3 example.
|
|
584
|
+
article > figure > .card-reveal-trigger {
|
|
585
|
+
position: absolute;
|
|
586
|
+
inset: 0;
|
|
587
|
+
z-index: 1;
|
|
588
|
+
display: block;
|
|
589
|
+
width: 100%;
|
|
590
|
+
height: 100%;
|
|
591
|
+
min-width: 0;
|
|
592
|
+
min-height: 0;
|
|
593
|
+
margin: 0;
|
|
594
|
+
padding: 0;
|
|
595
|
+
background: none;
|
|
596
|
+
border: 0;
|
|
597
|
+
border-radius: inherit;
|
|
598
|
+
box-shadow: none;
|
|
599
|
+
color: transparent;
|
|
600
|
+
cursor: pointer;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// The trigger paints its own state layer: the card's `::after` keys on
|
|
604
|
+
// `> .primary-action`, which this is not. It reads the same `--md-comp-card-*`
|
|
605
|
+
// opacities, so tuning one card still reaches it.
|
|
606
|
+
article > figure > .card-reveal-trigger:hover {
|
|
607
|
+
background-color: color-mix(in oklab, var(--md-comp-card-state-layer-color) calc(var(--md-comp-card-hover-state-layer-opacity) * 100%), transparent);
|
|
608
|
+
box-shadow: none;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
article > figure > .card-reveal-trigger:focus-visible {
|
|
612
|
+
background-color: color-mix(in oklab, var(--md-comp-card-state-layer-color) calc(var(--md-comp-card-focus-state-layer-opacity) * 100%), transparent);
|
|
613
|
+
box-shadow: none;
|
|
614
|
+
outline: var(--md-comp-card-focus-indicator-thickness) solid var(--md-comp-card-focus-indicator-color);
|
|
615
|
+
outline-offset: calc(-1 * var(--md-comp-card-focus-indicator-thickness));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
article > figure > .card-reveal-trigger:active {
|
|
619
|
+
background-color: color-mix(in oklab, var(--md-comp-card-state-layer-color) calc(var(--md-comp-card-pressed-state-layer-opacity) * 100%), transparent);
|
|
620
|
+
box-shadow: none;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
article > header.card-reveal-summary {
|
|
624
|
+
padding-bottom: var(--md-comp-card-content-padding);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
article > aside > .reveal-actions {
|
|
628
|
+
display: grid;
|
|
629
|
+
gap: 0;
|
|
630
|
+
margin: 0;
|
|
631
|
+
font-style: normal;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
article > aside > .reveal-actions > .reveal-action {
|
|
635
|
+
display: grid;
|
|
636
|
+
grid-template-columns: var(--md-comp-card-icon-size) minmax(0, 1fr);
|
|
637
|
+
align-items: center;
|
|
638
|
+
gap: var(--md-comp-card-content-padding);
|
|
639
|
+
min-height: 48px;
|
|
640
|
+
padding-inline: 0;
|
|
641
|
+
color: var(--md-sys-color-on-surface);
|
|
642
|
+
border-radius: 8px;
|
|
643
|
+
font-family: var(--md-sys-typescale-body-medium-font-family-name);
|
|
644
|
+
font-size: var(--md-sys-typescale-body-medium-font-size);
|
|
645
|
+
font-weight: var(--md-sys-typescale-body-medium-font-weight);
|
|
646
|
+
line-height: var(--md-sys-typescale-body-medium-line-height);
|
|
647
|
+
letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
article > aside > .reveal-actions > .reveal-action:hover {
|
|
651
|
+
background-color: color-mix(
|
|
652
|
+
in oklab,
|
|
653
|
+
var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover-state-layer-opacity) * 100%),
|
|
654
|
+
transparent
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
article > aside > .reveal-actions > .reveal-action > :is(.material-symbols, .card-icon, svg) {
|
|
659
|
+
width: var(--md-comp-card-icon-size);
|
|
660
|
+
height: var(--md-comp-card-icon-size);
|
|
661
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
662
|
+
font-size: var(--md-comp-card-icon-size);
|
|
663
|
+
fill: currentColor;
|
|
238
664
|
}
|
|
239
665
|
|
|
240
666
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -243,13 +669,8 @@ article > aside[aria-expanded="true"] {
|
|
|
243
669
|
}
|
|
244
670
|
}
|
|
245
671
|
|
|
246
|
-
article.sticky > nav {
|
|
672
|
+
article.sticky > :is(nav, .actions) {
|
|
247
673
|
position: relative;
|
|
248
674
|
z-index: 4;
|
|
249
675
|
background-color: inherit;
|
|
250
676
|
}
|
|
251
|
-
|
|
252
|
-
article.sticky > aside {
|
|
253
|
-
bottom: auto;
|
|
254
|
-
height: calc(100% - 52px);
|
|
255
|
-
}
|