@expressivecss/expressive 0.7.0 → 0.9.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 +1313 -1
- package/README.md +76 -30
- package/dist/css/expressive.css +4896 -1777
- 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/fonts/LICENSE-material-symbols +93 -0
- package/dist/fonts/LICENSE-noto-sans +93 -0
- package/dist/fonts/LICENSE-roboto +93 -0
- package/dist/fonts/material-symbols-outlined.woff2 +0 -0
- package/dist/fonts/material-symbols-rounded.woff2 +0 -0
- package/dist/fonts/material-symbols-sharp.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-400.woff2 +0 -0
- package/dist/fonts/noto-sans-latin-500.woff2 +0 -0
- package/dist/fonts/roboto-latin-400.woff2 +0 -0
- package/dist/fonts/roboto-latin-500.woff2 +0 -0
- package/dist/js/expressive.cjs +1673 -1338
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +1673 -1338
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +13 -13
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +1673 -1338
- 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/appBar.d.ts +26 -0
- package/dist/types/components/autocomplete.d.ts +15 -3
- package/dist/types/components/buttonGroup.d.ts +39 -0
- package/dist/types/components/buttons.d.ts +5 -1
- package/dist/types/components/cards.d.ts +11 -13
- 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 +23 -20
- package/dist/types/components/lightbox.d.ts +1 -0
- package/dist/types/components/menu.d.ts +11 -1
- package/dist/types/components/{sidenav.d.ts → navigationDrawer.d.ts} +16 -16
- package/dist/types/components/registry.d.ts +18 -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 -10
- package/dist/types/components/tooltip.d.ts +1 -0
- package/dist/types/core/utils.d.ts +64 -53
- package/dist/types/index.d.ts +8 -9
- package/package.json +39 -3
- package/src/sass/README.md +61 -11
- package/src/sass/abstracts/_breakpoints.scss +17 -19
- package/src/sass/abstracts/_mixins.scss +155 -21
- package/src/sass/abstracts/_variables.scss +69 -5
- package/src/sass/base/_fonts.scss +63 -0
- 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 +3 -5
- 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 +358 -0
- package/src/sass/components/_buttons.scss +245 -92
- package/src/sass/components/_cards.scss +514 -78
- 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 +226 -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 +172 -0
- package/src/sass/components/_icons-material-design.scss +22 -10
- 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 +245 -45
- package/src/sass/components/_navigation-bar.scss +22 -11
- package/src/sass/components/{_sidenav.scss → _navigation-drawer.scss} +123 -33
- package/src/sass/components/_navigation-rail.scss +31 -23
- 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/_transitions.scss +8 -1
- 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 +38 -1
- package/src/sass/components/forms/{_range.scss → _slider.scss} +8 -9
- package/src/sass/components/forms/_switches.scss +6 -7
- package/src/sass/expressive.scss +5 -0
- 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,240 @@ $_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 {
|
|
45
|
-
|
|
46
|
-
|
|
91
|
+
--md-comp-card-container-color: var(--md-comp-filled-card-container-color);
|
|
92
|
+
box-shadow: none;
|
|
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
|
+
box-shadow: none;
|
|
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. Dragged
|
|
103
|
+
// and picked-up states take precedence over retained pointer state.
|
|
104
|
+
:where(#{$_card}):not(.dragged, .picked-up):not(.filled, .outlined, .border):has(> .primary-action:hover) {
|
|
105
|
+
@include z-depth("2");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
:where(#{$_card}):not(.dragged, .picked-up):is(.filled, .outlined, .border):has(> .primary-action:hover) {
|
|
109
|
+
@include z-depth("1");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
:where(#{$_card}):not(.dragged, .picked-up):has(> .primary-action:hover)::after {
|
|
113
|
+
opacity: var(--md-comp-card-hover-state-layer-opacity);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Focus and press retain their variant elevation. Focus gets M3's external
|
|
117
|
+
// 3dp indicator at a 2dp offset; the outlined variant also darkens its stroke.
|
|
118
|
+
:where(#{$_card}):has(> .primary-action:focus-visible) {
|
|
119
|
+
outline: var(--md-comp-card-focus-indicator-thickness) solid var(--md-comp-card-focus-indicator-color);
|
|
120
|
+
outline-offset: var(--md-comp-card-focus-indicator-offset);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
:where(#{$_card}):not(.dragged, .picked-up):has(> .primary-action:focus-visible)::after {
|
|
124
|
+
opacity: var(--md-comp-card-focus-state-layer-opacity);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:where(#{$_card}):is(.outlined, .border):has(> .primary-action:focus-visible) {
|
|
128
|
+
border-color: var(--md-sys-color-on-surface);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:where(#{$_card}):not(.dragged, .picked-up):has(> .primary-action:active)::after {
|
|
132
|
+
opacity: var(--md-comp-card-pressed-state-layer-opacity);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:where(#{$_card}):not(.dragged, .picked-up):not(.filled, .outlined, .border):has(> .primary-action:active) {
|
|
136
|
+
@include z-depth("1");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:where(#{$_card}):not(.dragged, .picked-up):is(.filled, .outlined, .border):has(> .primary-action:active) {
|
|
51
140
|
@include z-depth("0");
|
|
52
|
-
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// A reorder interaction toggles `.dragged` or `.picked-up`. The elevated
|
|
144
|
+
// variant rises to level 4; filled and outlined variants rise to level 3.
|
|
145
|
+
:where(#{$_card}):not(.filled, .outlined, .border):is(.dragged, .picked-up) {
|
|
146
|
+
z-index: 4;
|
|
147
|
+
@include z-depth("4");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
:where(#{$_card}):is(.filled, .outlined, .border):is(.dragged, .picked-up) {
|
|
151
|
+
z-index: 4;
|
|
152
|
+
@include z-depth("3");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
:where(#{$_card}):is(.dragged, .picked-up)::after {
|
|
156
|
+
opacity: var(--md-comp-card-dragged-state-layer-opacity);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Disabled tokens differ by variant in M3. `aria-disabled` belongs on the
|
|
160
|
+
// primary action; `.disabled` / article[aria-disabled] cover app-controlled
|
|
161
|
+
// cards that do not use a link.
|
|
162
|
+
:where(#{$_card}):is(.disabled, [aria-disabled="true"]),
|
|
163
|
+
:where(#{$_card}):has(> .primary-action[aria-disabled="true"]) {
|
|
164
|
+
outline: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
:where(#{$_card}):not(.filled, .outlined, .border):is(.disabled, [aria-disabled="true"]),
|
|
168
|
+
:where(#{$_card}):not(.filled, .outlined, .border):has(> .primary-action[aria-disabled="true"]) {
|
|
169
|
+
@include z-depth("1");
|
|
170
|
+
background-color: color-mix(
|
|
171
|
+
in oklab,
|
|
172
|
+
var(--md-sys-color-surface) var(--md-comp-card-disabled-container-opacity),
|
|
173
|
+
transparent
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
:where(#{$_card}).filled:is(.disabled, [aria-disabled="true"]),
|
|
178
|
+
:where(#{$_card}).filled:has(> .primary-action[aria-disabled="true"]) {
|
|
179
|
+
@include z-depth("0");
|
|
180
|
+
background-color: color-mix(
|
|
181
|
+
in oklab,
|
|
182
|
+
var(--md-sys-color-surface-variant) var(--md-comp-card-disabled-container-opacity),
|
|
183
|
+
transparent
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
:where(#{$_card}):is(.outlined, .border):is(.disabled, [aria-disabled="true"]),
|
|
188
|
+
:where(#{$_card}):is(.outlined, .border):has(> .primary-action[aria-disabled="true"]) {
|
|
189
|
+
@include z-depth("0");
|
|
190
|
+
background-color: var(--md-comp-outlined-card-container-color);
|
|
191
|
+
border-color: color-mix(
|
|
192
|
+
in oklab,
|
|
193
|
+
var(--md-comp-outlined-card-disabled-outline-color) var(--md-comp-outlined-card-disabled-outline-opacity),
|
|
194
|
+
transparent
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
:where(#{$_card}):is(.disabled, [aria-disabled="true"])::after,
|
|
199
|
+
:where(#{$_card}):has(> .primary-action[aria-disabled="true"])::after {
|
|
200
|
+
opacity: 0;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
:where(#{$_card}).disabled,
|
|
204
|
+
:where(#{$_card})[aria-disabled="true"],
|
|
205
|
+
:where(#{$_card}) > .primary-action[aria-disabled="true"] {
|
|
206
|
+
pointer-events: none;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
:where(#{$_card}) .card-icon {
|
|
210
|
+
width: var(--md-comp-card-icon-size);
|
|
211
|
+
height: var(--md-comp-card-icon-size);
|
|
212
|
+
color: var(--md-comp-card-icon-color);
|
|
213
|
+
font-size: var(--md-comp-card-icon-size);
|
|
53
214
|
}
|
|
54
215
|
|
|
55
216
|
// --- Semantic children ----------------------------------------------------
|
|
56
217
|
|
|
57
218
|
article > :is(h1, h2, h3, h4, h5, h6),
|
|
58
|
-
article > header > :is(h1, h2, h3, h4, h5, h6) {
|
|
219
|
+
article > :is(header, .primary-action) > :is(h1, h2, h3, h4, h5, h6) {
|
|
59
220
|
margin: 0;
|
|
60
|
-
padding:
|
|
221
|
+
padding: var(--md-comp-card-content-padding) var(--md-comp-card-content-padding) 0;
|
|
61
222
|
font-family: var(--md-sys-typescale-title-medium-font-family-name);
|
|
62
223
|
font-size: var(--md-sys-typescale-title-medium-font-size);
|
|
63
224
|
font-weight: var(--md-sys-typescale-title-medium-font-weight);
|
|
64
225
|
line-height: var(--md-sys-typescale-title-medium-line-height);
|
|
65
226
|
letter-spacing: var(--md-sys-typescale-title-medium-letter-spacing);
|
|
66
|
-
color: var(--md-
|
|
227
|
+
color: var(--md-comp-card-headline-color);
|
|
67
228
|
}
|
|
68
229
|
|
|
69
230
|
article > p,
|
|
70
|
-
article > header > p {
|
|
231
|
+
article > :is(header, .primary-action) > p {
|
|
71
232
|
margin: 0;
|
|
72
|
-
padding:
|
|
233
|
+
padding: var(--md-comp-card-between-space) var(--md-comp-card-content-padding) var(--md-comp-card-content-padding);
|
|
73
234
|
font-family: var(--md-sys-typescale-body-medium-font-family-name);
|
|
74
235
|
font-size: var(--md-sys-typescale-body-medium-font-size);
|
|
75
236
|
font-weight: var(--md-sys-typescale-body-medium-font-weight);
|
|
76
237
|
line-height: var(--md-sys-typescale-body-medium-line-height);
|
|
77
238
|
letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing);
|
|
78
|
-
color: color
|
|
239
|
+
color: var(--md-comp-card-supporting-text-color);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Optional subhead between the headline and supporting copy. Keep the class
|
|
243
|
+
// on a paragraph so the document retains useful reading semantics.
|
|
244
|
+
article > p.subhead,
|
|
245
|
+
article > :is(header, .primary-action) > p.subhead {
|
|
246
|
+
margin: 0;
|
|
247
|
+
padding: 4px var(--md-comp-card-content-padding) 0;
|
|
248
|
+
font-family: var(--md-sys-typescale-title-small-font-family-name);
|
|
249
|
+
font-size: var(--md-sys-typescale-title-small-font-size);
|
|
250
|
+
font-weight: var(--md-sys-typescale-title-small-font-weight);
|
|
251
|
+
line-height: var(--md-sys-typescale-title-small-line-height);
|
|
252
|
+
letter-spacing: var(--md-sys-typescale-title-small-letter-spacing);
|
|
253
|
+
color: var(--md-comp-card-subhead-color);
|
|
79
254
|
}
|
|
80
255
|
|
|
81
256
|
article > :is(h1, h2, h3, h4, h5, h6) + p,
|
|
82
|
-
article > header > :is(h1, h2, h3, h4, h5, h6) + p {
|
|
257
|
+
article > :is(header, .primary-action) > :is(h1, h2, h3, h4, h5, h6) + p {
|
|
83
258
|
padding-top: 0;
|
|
84
259
|
}
|
|
85
260
|
|
|
@@ -89,63 +264,189 @@ article > header {
|
|
|
89
264
|
color: inherit;
|
|
90
265
|
}
|
|
91
266
|
|
|
92
|
-
// Action row.
|
|
93
|
-
article >
|
|
267
|
+
// Action row. A row of buttons, not destinations.
|
|
268
|
+
article > .actions {
|
|
269
|
+
position: relative;
|
|
270
|
+
z-index: 3;
|
|
94
271
|
display: flex;
|
|
95
272
|
flex-wrap: wrap;
|
|
96
273
|
align-items: center;
|
|
97
|
-
gap:
|
|
274
|
+
gap: var(--md-comp-card-between-space);
|
|
98
275
|
padding: 4px 8px 8px 8px;
|
|
99
276
|
margin: 0;
|
|
100
277
|
}
|
|
101
278
|
|
|
102
279
|
article > img,
|
|
103
280
|
article > picture,
|
|
104
|
-
article > figure
|
|
281
|
+
article > figure,
|
|
282
|
+
article > .primary-action > img,
|
|
283
|
+
article > .primary-action > picture,
|
|
284
|
+
article > .primary-action > figure {
|
|
105
285
|
display: block;
|
|
106
286
|
width: 100%;
|
|
107
287
|
margin: 0;
|
|
288
|
+
border-radius: var(--md-comp-card-media-shape);
|
|
289
|
+
overflow: hidden;
|
|
108
290
|
}
|
|
109
291
|
|
|
110
292
|
article > img,
|
|
111
293
|
article > picture img,
|
|
112
|
-
article > figure img
|
|
294
|
+
article > figure img,
|
|
295
|
+
article > .primary-action > img,
|
|
296
|
+
article > .primary-action > picture img,
|
|
297
|
+
article > .primary-action > figure img {
|
|
113
298
|
display: block;
|
|
114
299
|
width: 100%;
|
|
115
300
|
object-fit: cover;
|
|
301
|
+
border-radius: var(--md-comp-card-media-shape);
|
|
116
302
|
}
|
|
117
303
|
|
|
118
304
|
article > figure {
|
|
119
305
|
position: relative;
|
|
120
306
|
}
|
|
121
307
|
|
|
122
|
-
article >
|
|
308
|
+
article > .primary-action > figure {
|
|
309
|
+
position: relative;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
article > figure > figcaption,
|
|
313
|
+
article > .primary-action > figure > figcaption {
|
|
123
314
|
position: absolute;
|
|
124
|
-
inset-inline:
|
|
125
|
-
|
|
315
|
+
inset-inline-start: var(--md-comp-card-content-padding);
|
|
316
|
+
inset-inline-end: auto;
|
|
317
|
+
bottom: var(--md-comp-card-content-padding);
|
|
318
|
+
display: inline-flex;
|
|
319
|
+
align-items: center;
|
|
320
|
+
gap: var(--md-comp-card-between-space);
|
|
321
|
+
box-sizing: border-box;
|
|
322
|
+
width: fit-content;
|
|
323
|
+
max-width: calc(100% - (2 * var(--md-comp-card-content-padding)));
|
|
126
324
|
margin: 0;
|
|
127
|
-
padding:
|
|
128
|
-
color: var(--md-
|
|
129
|
-
background:
|
|
325
|
+
padding: 8px 12px;
|
|
326
|
+
color: var(--md-comp-card-media-overlay-ink-color);
|
|
327
|
+
background-color: var(--md-comp-card-media-overlay-container-color);
|
|
328
|
+
border-radius: var(--md-comp-card-media-overlay-shape);
|
|
130
329
|
font-family: var(--md-sys-typescale-title-medium-font-family-name);
|
|
131
330
|
font-size: var(--md-sys-typescale-title-medium-font-size);
|
|
132
331
|
font-weight: var(--md-sys-typescale-title-medium-font-weight);
|
|
133
332
|
line-height: var(--md-sys-typescale-title-medium-line-height);
|
|
134
333
|
}
|
|
135
334
|
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
335
|
+
// Keep meaningful icons on the same opaque role pair as caption text. The
|
|
336
|
+
// surface/on-surface pairing isolates both from unpredictable image colors.
|
|
337
|
+
article > figure > figcaption > :is(.material-symbols, .card-icon, svg),
|
|
338
|
+
article > .primary-action > figure > figcaption > :is(.material-symbols, .card-icon, svg) {
|
|
339
|
+
flex: 0 0 auto;
|
|
340
|
+
color: inherit;
|
|
341
|
+
font-size: var(--md-comp-card-icon-size);
|
|
342
|
+
line-height: 1;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
article > figure > figcaption > svg,
|
|
346
|
+
article > .primary-action > figure > figcaption > svg {
|
|
347
|
+
fill: currentColor;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Collections are a grid by default. The full track definition is a token so
|
|
351
|
+
// applications can supply fixed, responsive, or asymmetric columns without
|
|
352
|
+
// fighting component selectors. Each card keeps its variant-specific resting
|
|
353
|
+
// elevation; picked-up / dragged state raises each variant above its rest.
|
|
354
|
+
:where(.card-collection) {
|
|
355
|
+
--md-comp-card-collection-gap: 8px;
|
|
356
|
+
--md-comp-card-collection-min-card-width: 240px;
|
|
357
|
+
--md-comp-card-collection-grid-template-columns: repeat(
|
|
358
|
+
auto-fit,
|
|
359
|
+
minmax(min(100%, var(--md-comp-card-collection-min-card-width)), 1fr)
|
|
360
|
+
);
|
|
361
|
+
--md-comp-card-collection-mosaic-row-size: 80px;
|
|
362
|
+
--md-comp-card-collection-carousel-height: 320px;
|
|
363
|
+
--md-comp-card-collection-carousel-card-width: min(82%, 360px);
|
|
364
|
+
|
|
365
|
+
display: grid;
|
|
366
|
+
grid-template-columns: var(--md-comp-card-collection-grid-template-columns);
|
|
367
|
+
gap: var(--md-comp-card-collection-gap);
|
|
140
368
|
align-items: stretch;
|
|
369
|
+
margin: 0;
|
|
370
|
+
padding: 0;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
:where(.card-collection article):not(.horizontal) {
|
|
374
|
+
display: flex;
|
|
375
|
+
flex-direction: column;
|
|
376
|
+
min-width: 0;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
:where(.card-collection article):not(.horizontal) > .actions {
|
|
380
|
+
margin-block-start: auto;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// A list is the same collection with one column. The cards retain their own
|
|
384
|
+
// vertical / horizontal orientation.
|
|
385
|
+
.card-collection.list {
|
|
386
|
+
--md-comp-card-collection-grid-template-columns: minmax(0, 1fr);
|
|
387
|
+
|
|
388
|
+
margin: 0;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Staggered uses multicolumn flow for masonry-like intrinsic card heights.
|
|
392
|
+
:where(.card-collection.staggered) {
|
|
393
|
+
display: block;
|
|
394
|
+
columns: var(
|
|
395
|
+
--md-comp-card-collection-staggered-column-width,
|
|
396
|
+
var(--md-comp-card-collection-min-card-width)
|
|
397
|
+
);
|
|
398
|
+
column-gap: var(--md-comp-card-collection-gap);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
:where(.card-collection.staggered) > article {
|
|
402
|
+
break-inside: avoid;
|
|
403
|
+
width: 100%;
|
|
404
|
+
margin-block: 0 var(--md-comp-card-collection-gap);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Mosaic keeps source order in a dense grid. Per-card custom properties make
|
|
408
|
+
// spans data-driven instead of baking a decorative nth-child pattern into the
|
|
409
|
+
// framework.
|
|
410
|
+
:where(.card-collection.mosaic) {
|
|
411
|
+
grid-auto-flow: dense;
|
|
412
|
+
grid-auto-rows: var(--md-comp-card-collection-mosaic-row-size);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
:where(.card-collection.mosaic) > article {
|
|
416
|
+
grid-column: span var(--md-comp-card-collection-column-span, 1);
|
|
417
|
+
grid-row: span var(--md-comp-card-collection-row-span, 2);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Reuse the M3 uncontained Carousel for a horizontally scrolling collection.
|
|
421
|
+
// Carousel.Init()/AutoInit() supplies the track and interaction behavior.
|
|
422
|
+
.card-collection.carousel {
|
|
423
|
+
--carousel-height: var(--md-comp-card-collection-carousel-height);
|
|
424
|
+
--md-comp-carousel-gap: var(--md-comp-card-collection-gap);
|
|
425
|
+
--md-comp-carousel-uncontained-item-width: var(
|
|
426
|
+
--md-comp-card-collection-carousel-card-width
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
display: block;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Horizontal uses the same semantic slots as the vertical card. They may be
|
|
433
|
+
// direct children or children of the direct primary-action link.
|
|
434
|
+
@mixin horizontal-card-layout($with-actions: true) {
|
|
435
|
+
display: grid;
|
|
436
|
+
grid-template-columns:
|
|
437
|
+
minmax(0, var(--md-comp-card-horizontal-media-width))
|
|
438
|
+
minmax(0, 1fr);
|
|
439
|
+
grid-template-rows: auto auto minmax(0, 1fr) auto;
|
|
440
|
+
min-height: var(--md-comp-card-horizontal-min-height);
|
|
141
441
|
overflow: hidden;
|
|
142
442
|
|
|
143
443
|
> img,
|
|
144
444
|
> picture,
|
|
145
445
|
> figure {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
width:
|
|
446
|
+
grid-column: 1;
|
|
447
|
+
grid-row: 1 / -1;
|
|
448
|
+
width: 100%;
|
|
449
|
+
height: 100%;
|
|
149
450
|
align-self: stretch;
|
|
150
451
|
}
|
|
151
452
|
|
|
@@ -156,12 +457,45 @@ article.horizontal {
|
|
|
156
457
|
object-fit: cover;
|
|
157
458
|
}
|
|
158
459
|
|
|
159
|
-
>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
flex-direction: column;
|
|
460
|
+
> :is(h1, h2, h3, h4, h5, h6),
|
|
461
|
+
> header {
|
|
462
|
+
grid-column: 2;
|
|
463
|
+
grid-row: 1;
|
|
164
464
|
}
|
|
465
|
+
|
|
466
|
+
> p.subhead {
|
|
467
|
+
grid-column: 2;
|
|
468
|
+
grid-row: 2;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
> p:not(.subhead) {
|
|
472
|
+
grid-column: 2;
|
|
473
|
+
grid-row: 3;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
@if $with-actions {
|
|
477
|
+
> .actions {
|
|
478
|
+
grid-column: 2;
|
|
479
|
+
grid-row: 4;
|
|
480
|
+
align-self: end;
|
|
481
|
+
justify-content: flex-end;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
article.horizontal {
|
|
487
|
+
@include horizontal-card-layout;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
article.horizontal:has(> .primary-action) {
|
|
491
|
+
display: block;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
article.horizontal > .primary-action {
|
|
495
|
+
@include horizontal-card-layout(false);
|
|
496
|
+
|
|
497
|
+
width: 100%;
|
|
498
|
+
min-height: inherit;
|
|
165
499
|
}
|
|
166
500
|
|
|
167
501
|
// Fixed heights for uniform grids.
|
|
@@ -179,7 +513,7 @@ article.small, article.medium, article.large {
|
|
|
179
513
|
overflow: hidden;
|
|
180
514
|
}
|
|
181
515
|
|
|
182
|
-
> img, > figure img {
|
|
516
|
+
> img, > picture img, > figure img {
|
|
183
517
|
height: 100%;
|
|
184
518
|
}
|
|
185
519
|
|
|
@@ -189,7 +523,7 @@ article.small, article.medium, article.large {
|
|
|
189
523
|
overflow: hidden;
|
|
190
524
|
}
|
|
191
525
|
|
|
192
|
-
>
|
|
526
|
+
> .actions {
|
|
193
527
|
margin-top: auto;
|
|
194
528
|
}
|
|
195
529
|
}
|
|
@@ -197,59 +531,161 @@ article.small, article.medium, article.large {
|
|
|
197
531
|
article.horizontal.small,
|
|
198
532
|
article.horizontal.medium,
|
|
199
533
|
article.horizontal.large {
|
|
200
|
-
|
|
534
|
+
display: grid;
|
|
201
535
|
|
|
202
536
|
> img, > picture, > figure {
|
|
203
|
-
flex: 0 0 40%;
|
|
204
537
|
max-height: none;
|
|
205
538
|
}
|
|
206
539
|
}
|
|
207
540
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
// translateY(-100%): that slides the panel *off* the card, and isOpen stays
|
|
212
|
-
// true so a second click is a no-op.
|
|
213
|
-
article > aside {
|
|
214
|
-
--md-comp-card-reveal-duration: 300ms;
|
|
215
|
-
--md-comp-card-reveal-easing: ease;
|
|
541
|
+
article.horizontal:is(.small, .medium, .large):has(> .primary-action) {
|
|
542
|
+
display: block;
|
|
543
|
+
}
|
|
216
544
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
545
|
+
article.horizontal:is(.small, .medium, .large) > .primary-action {
|
|
546
|
+
height: 100%;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Compact windows use the vertical spelling. This keeps media and controls
|
|
550
|
+
// large enough to scan and operate without changing their source order.
|
|
551
|
+
@include bp-down("medium") {
|
|
552
|
+
article.horizontal,
|
|
553
|
+
article.horizontal.small,
|
|
554
|
+
article.horizontal.medium,
|
|
555
|
+
article.horizontal.large {
|
|
556
|
+
display: flex;
|
|
557
|
+
flex-direction: column;
|
|
558
|
+
height: auto;
|
|
559
|
+
min-height: auto;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
article.horizontal > .primary-action,
|
|
563
|
+
article.horizontal:is(.small, .medium, .large) > .primary-action {
|
|
564
|
+
display: flex;
|
|
565
|
+
flex-direction: column;
|
|
566
|
+
height: auto;
|
|
567
|
+
min-height: auto;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Reveal panel. Panels stay available until Cards confirms the disclosure
|
|
572
|
+
// contract and adds its runtime marker. The summary and media remain in place
|
|
573
|
+
// while the initialized card grows downward to expose additional actions.
|
|
574
|
+
// `interpolate-size` lets intrinsic content height animate without a fixed cap;
|
|
575
|
+
// the @supports fallback keeps the interaction functional.
|
|
576
|
+
:where(#{$_card}.card-reveal-initialized) {
|
|
577
|
+
interpolate-size: allow-keywords;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
article.card-reveal-initialized > aside {
|
|
581
|
+
--md-comp-card-reveal-duration: 500ms;
|
|
582
|
+
--md-comp-card-reveal-easing: cubic-bezier(0.2, 0, 0, 1);
|
|
583
|
+
|
|
584
|
+
position: relative;
|
|
585
|
+
inset: auto;
|
|
586
|
+
z-index: 1;
|
|
220
587
|
box-sizing: border-box;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
588
|
+
height: 0;
|
|
589
|
+
min-height: 0;
|
|
590
|
+
padding: 0 var(--md-comp-card-content-padding);
|
|
591
|
+
overflow: clip;
|
|
592
|
+
background-color: inherit;
|
|
224
593
|
color: var(--md-sys-color-on-surface);
|
|
225
|
-
|
|
594
|
+
opacity: 0;
|
|
226
595
|
visibility: hidden;
|
|
227
596
|
pointer-events: none;
|
|
228
597
|
transition:
|
|
229
|
-
|
|
598
|
+
height var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
599
|
+
padding-block var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
600
|
+
opacity 150ms ease-out,
|
|
230
601
|
visibility 0s var(--md-comp-card-reveal-duration);
|
|
231
602
|
}
|
|
232
603
|
|
|
233
|
-
article > aside
|
|
234
|
-
|
|
604
|
+
article.card-reveal-initialized > aside.open {
|
|
605
|
+
height: auto;
|
|
606
|
+
padding-block: 0 var(--md-comp-card-content-padding);
|
|
607
|
+
opacity: 1;
|
|
235
608
|
visibility: visible;
|
|
236
609
|
pointer-events: auto;
|
|
237
|
-
transition:
|
|
610
|
+
transition:
|
|
611
|
+
height var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
612
|
+
padding-block var(--md-comp-card-reveal-duration) var(--md-comp-card-reveal-easing),
|
|
613
|
+
opacity 200ms 100ms ease-out,
|
|
614
|
+
visibility 0s;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
@supports not (interpolate-size: allow-keywords) {
|
|
618
|
+
article.card-reveal-initialized > aside {
|
|
619
|
+
display: none;
|
|
620
|
+
height: auto;
|
|
621
|
+
transition: none;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
article.card-reveal-initialized > aside.open {
|
|
625
|
+
display: block;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// A media-sized button supplies the repeated open/close target and carries the
|
|
630
|
+
// state layer for the tap feedback shown by the M3 example.
|
|
631
|
+
article > figure > .card-reveal-trigger {
|
|
632
|
+
@include card-media-trigger;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
article > header.card-reveal-summary {
|
|
636
|
+
padding-bottom: var(--md-comp-card-content-padding);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
article > aside > .reveal-actions {
|
|
640
|
+
display: grid;
|
|
641
|
+
gap: 0;
|
|
642
|
+
margin: 0;
|
|
643
|
+
font-style: normal;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
article > aside > .reveal-actions > .reveal-action {
|
|
647
|
+
display: grid;
|
|
648
|
+
grid-template-columns: var(--md-comp-card-icon-size) minmax(0, 1fr);
|
|
649
|
+
align-items: center;
|
|
650
|
+
gap: var(--md-comp-card-content-padding);
|
|
651
|
+
min-height: 48px;
|
|
652
|
+
padding-inline: 0;
|
|
653
|
+
color: var(--md-sys-color-on-surface);
|
|
654
|
+
border-radius: 8px;
|
|
655
|
+
font-family: var(--md-sys-typescale-body-medium-font-family-name);
|
|
656
|
+
font-size: var(--md-sys-typescale-body-medium-font-size);
|
|
657
|
+
font-weight: var(--md-sys-typescale-body-medium-font-weight);
|
|
658
|
+
line-height: var(--md-sys-typescale-body-medium-line-height);
|
|
659
|
+
letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
article > aside > .reveal-actions > .reveal-action:hover {
|
|
663
|
+
background-color: color-mix(
|
|
664
|
+
in oklab,
|
|
665
|
+
var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover-state-layer-opacity) * 100%),
|
|
666
|
+
transparent
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
article > aside > .reveal-actions > .reveal-action > :is(.material-symbols, .card-icon, svg) {
|
|
671
|
+
width: var(--md-comp-card-icon-size);
|
|
672
|
+
height: var(--md-comp-card-icon-size);
|
|
673
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
674
|
+
font-size: var(--md-comp-card-icon-size);
|
|
675
|
+
fill: currentColor;
|
|
238
676
|
}
|
|
239
677
|
|
|
240
678
|
@media (prefers-reduced-motion: reduce) {
|
|
241
|
-
|
|
679
|
+
:where(#{$_card}),
|
|
680
|
+
:where(#{$_card})::after,
|
|
681
|
+
article > figure > .card-reveal-trigger,
|
|
682
|
+
article.card-reveal-initialized > aside {
|
|
242
683
|
transition: none;
|
|
243
684
|
}
|
|
244
685
|
}
|
|
245
686
|
|
|
246
|
-
article.sticky >
|
|
687
|
+
article.sticky > .actions {
|
|
247
688
|
position: relative;
|
|
248
689
|
z-index: 4;
|
|
249
690
|
background-color: inherit;
|
|
250
691
|
}
|
|
251
|
-
|
|
252
|
-
article.sticky > aside {
|
|
253
|
-
bottom: auto;
|
|
254
|
-
height: calc(100% - 52px);
|
|
255
|
-
}
|