@expressivecss/expressive 0.1.0 → 0.3.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 (40) hide show
  1. package/README.md +8 -8
  2. package/dist/css/expressive.css +1088 -356
  3. package/dist/css/expressive.css.map +1 -1
  4. package/dist/css/expressive.min.css +1 -1
  5. package/dist/css/expressive.min.css.map +1 -1
  6. package/dist/js/expressive.cjs +778 -746
  7. package/dist/js/expressive.cjs.map +4 -4
  8. package/dist/js/expressive.js +778 -746
  9. package/dist/js/expressive.js.map +4 -4
  10. package/dist/js/expressive.min.js +10 -10
  11. package/dist/js/expressive.min.js.map +4 -4
  12. package/dist/js/expressive.mjs +778 -746
  13. package/dist/js/expressive.mjs.map +4 -4
  14. package/dist/types/behaviors/dialogs.d.ts +25 -0
  15. package/dist/types/components/buttons.d.ts +17 -41
  16. package/dist/types/components/carousel.d.ts +40 -46
  17. package/dist/types/components/chips.d.ts +2 -2
  18. package/dist/types/components/collapsible.d.ts +35 -13
  19. package/dist/types/components/parallax.d.ts +7 -31
  20. package/dist/types/components/tapTarget.d.ts +23 -24
  21. package/dist/types/index.d.ts +2 -1
  22. package/package.json +1 -1
  23. package/src/sass/README.md +4 -3
  24. package/src/sass/components/_badges.scss +5 -4
  25. package/src/sass/components/_breadcrumb.scss +93 -16
  26. package/src/sass/components/_buttons.scss +195 -96
  27. package/src/sass/components/_carousel.scss +130 -63
  28. package/src/sass/components/_chips.scss +1 -1
  29. package/src/sass/components/_collapsible.scss +160 -60
  30. package/src/sass/components/_collection.scss +161 -77
  31. package/src/sass/components/_icons-material-design.scss +77 -4
  32. package/src/sass/components/_lightbox.scss +4 -0
  33. package/src/sass/components/_modal.scss +67 -3
  34. package/src/sass/components/_navbar.scss +15 -0
  35. package/src/sass/components/_pagination.scss +131 -25
  36. package/src/sass/components/_parallax.scss +116 -20
  37. package/src/sass/components/_sidenav.scss +10 -5
  38. package/src/sass/components/_slider.scss +8 -0
  39. package/src/sass/components/_tapTarget.scss +134 -47
  40. package/src/sass/utilities/_helpers.scss +10 -0
@@ -43,7 +43,7 @@
43
43
  border-radius: 12px;
44
44
  }
45
45
 
46
- .chip > .material-icons {
46
+ .chip > :is(.material-symbols, .material-symbols-outlined, .material-symbols-rounded, .material-symbols-sharp, .material-icons) {
47
47
  font-size: var(--font-size-icon);
48
48
  color: var(--md-sys-color-on-surface-variant);
49
49
  }
@@ -1,81 +1,181 @@
1
1
  @use "../abstracts" as *;
2
2
 
3
+ // Collapsible. Anatomy is the HTML: a .collapsible of <details> with
4
+ // <summary> headers. Same `name` on each <details> is an accordion;
5
+ // omit it (or add .expandable) so several can stay open. The `open`
6
+ // attribute is the preselected section.
7
+ //
8
+ // <ul>/<li> + .collapsible-header / .collapsible-body stay as aliases.
9
+ // .collapsible-accordion is the default and does nothing extra.
10
+ //
11
+ // Tokens:
12
+ // --md-comp-collapsible-shape 12px
13
+ // --md-comp-collapsible-container-color surface
14
+ // --md-comp-collapsible-outline-color outline-variant
15
+ // --md-comp-collapsible-header-padding 1rem
16
+ // --md-comp-collapsible-body-padding 0 1rem
17
+ // --md-comp-collapsible-duration 500ms
18
+ // --md-comp-collapsible-easing-open ease-in-out cubic
19
+ // --md-comp-collapsible-easing-close ease-in-out cubic
20
+ // --md-comp-collapsible-icon-size 24px
21
+ // --md-comp-collapsible-popout-inset 24px
22
+ // --md-comp-collapsible-popout-gap 16px
23
+ //
24
+ // Nest descendants inside this block. A list-suffixed selector only
25
+ // attaches the suffix to the last item (same bug as the icon sizes).
26
+
3
27
  .collapsible {
4
- padding-left: 0;
5
- list-style-type: none;
6
- border-top: 1px solid var(--md-sys-color-outline-variant);
7
- border-right: 1px solid var(--md-sys-color-outline-variant);
8
- border-left: 1px solid var(--md-sys-color-outline-variant);
9
- margin: $element-top-margin 0 $element-bottom-margin 0;
28
+ --md-comp-collapsible-shape: 12px;
29
+ --md-comp-collapsible-container-color: var(--md-sys-color-surface);
30
+ --md-comp-collapsible-outline-color: var(--md-sys-color-outline-variant);
31
+ --md-comp-collapsible-header-padding: 1rem;
32
+ --md-comp-collapsible-body-padding: 0 1rem;
33
+ --md-comp-collapsible-duration: 500ms;
34
+ --md-comp-collapsible-easing-open: cubic-bezier(0.65, 0, 0.35, 1);
35
+ --md-comp-collapsible-easing-close: cubic-bezier(0.65, 0, 0.35, 1);
36
+ --md-comp-collapsible-icon-size: 24px;
37
+ --md-comp-collapsible-popout-inset: 24px;
38
+ --md-comp-collapsible-popout-gap: 16px;
39
+
40
+ box-sizing: border-box;
41
+ padding: 0;
42
+ margin: $element-top-margin 0 $element-bottom-margin;
43
+ list-style: none;
44
+ overflow: hidden;
45
+ border: 1px solid var(--md-comp-collapsible-outline-color);
46
+ border-radius: var(--md-comp-collapsible-shape);
47
+ background-color: var(--md-comp-collapsible-container-color);
48
+ color: var(--md-sys-color-on-surface);
10
49
  @include z-depth("1");
11
- }
12
50
 
13
- .collapsible-header {
14
- display: flex;
15
- cursor: pointer;
16
- -webkit-tap-highlight-color: transparent;
17
- line-height: 1.5;
18
- padding: 1rem;
19
- border-bottom: 1px solid var(--md-sys-color-outline-variant);
51
+ > :is(details, li) + :is(details, li) {
52
+ border-top: 1px solid var(--md-comp-collapsible-outline-color);
53
+ }
54
+
55
+ :is(summary, .collapsible-header) {
56
+ display: flex;
57
+ align-items: center;
58
+ box-sizing: border-box;
59
+ width: 100%;
60
+ margin: 0;
61
+ padding: var(--md-comp-collapsible-header-padding);
62
+ border: 0;
63
+ background: none;
64
+ color: inherit;
65
+ font: inherit;
66
+ font-weight: inherit;
67
+ line-height: 1.5;
68
+ text-align: start;
69
+ list-style: none;
70
+ cursor: pointer;
71
+ -webkit-tap-highlight-color: transparent;
20
72
 
21
- &:focus {
22
- outline: 0
73
+ &::-webkit-details-marker {
74
+ display: none;
75
+ }
76
+
77
+ @include focus-visible;
78
+
79
+ > i {
80
+ width: 2rem;
81
+ margin-right: 1rem;
82
+ font-size: 1.6rem;
83
+ line-height: 1;
84
+ text-align: center;
85
+ }
86
+
87
+ &::after {
88
+ content: "expand_more";
89
+ flex-shrink: 0;
90
+ margin-inline-start: auto;
91
+ font-family: var(--md-icon-font);
92
+ font-size: var(--md-comp-collapsible-icon-size);
93
+ font-variation-settings:
94
+ "FILL" var(--md-icon-fill),
95
+ "wght" var(--md-icon-weight),
96
+ "GRAD" var(--md-icon-grade),
97
+ "opsz" var(--md-icon-optical-size);
98
+ line-height: 1;
99
+ -webkit-font-smoothing: antialiased;
100
+ transition: transform var(--md-comp-collapsible-duration)
101
+ var(--md-comp-collapsible-easing-close);
102
+ }
23
103
  }
24
104
 
25
- i {
26
- width: 2rem;
27
- font-size: 1.6rem;
28
- display: inline-block;
29
- text-align: center;
30
- margin-right: 1rem;
105
+ :is(details[open] > summary, .active > .collapsible-header)::after {
106
+ transform: rotate(180deg);
107
+ transition-timing-function: var(--md-comp-collapsible-easing-open);
31
108
  }
32
- }
33
109
 
34
- .collapsible-header::after {
35
- content: '\e5cf';
36
- margin-left: .5rem;
37
- font-family: 'Material Symbols Outlined', 'Material Symbols Rounded', 'Material Symbols Sharp', 'Material Icons';
38
- font-size: 25px;
39
- line-height: .9;
40
- -webkit-font-smoothing: antialiased;
41
- }
110
+ .collapsible-header-content {
111
+ flex-grow: 1;
112
+ }
42
113
 
43
- .active .collapsible-header::after {
44
- content: '\e5ce';
45
- }
114
+ // Shared body for the <ul> alias and for <details> (JS wraps the
115
+ // latter). Text stays painted and is clipped as the row shrinks.
116
+ .collapsible-body {
117
+ display: grid;
118
+ grid-template-rows: 0fr;
119
+ box-sizing: border-box;
120
+ padding: var(--md-comp-collapsible-body-padding);
121
+ overflow: hidden;
122
+ transition: grid-template-rows var(--md-comp-collapsible-duration)
123
+ var(--md-comp-collapsible-easing-close);
46
124
 
47
- .keyboard-focused .collapsible-header:focus {
48
- background-color: rgba(0, 0, 0, 0.12);
49
- }
125
+ > * {
126
+ min-height: 0;
127
+ overflow: hidden;
128
+ }
129
+ }
50
130
 
51
- .collapsible-header-content {
52
- flex-grow: 1;
53
- }
131
+ .active > .collapsible-body,
132
+ details[open] > .collapsible-body {
133
+ grid-template-rows: 1fr;
134
+ transition-timing-function: var(--md-comp-collapsible-easing-open);
135
+ }
54
136
 
55
- .collapsible-body {
56
- max-height: 0;
57
- border-bottom: 1px solid var(--md-sys-color-outline-variant);
58
- box-sizing: border-box;
59
- padding: 0 2rem;
60
- overflow: hidden;
61
- }
137
+ // UA `display: none` on closed details children. Keep our wrapper as
138
+ // a grid so 0fr can clip instead of popping the copy away.
139
+ details:not([open]) > .collapsible-body {
140
+ display: grid;
141
+ }
142
+
143
+ &.no-icon :is(summary, .collapsible-header)::after {
144
+ content: none;
145
+ }
146
+
147
+ &.popout {
148
+ overflow: visible;
149
+ border: 0;
150
+ background: transparent;
151
+ @include z-depth("0");
62
152
 
63
- // Popout Collapsible
153
+ > :is(details, li) {
154
+ margin-inline: var(--md-comp-collapsible-popout-inset);
155
+ overflow: hidden;
156
+ border: 0;
157
+ border-radius: var(--md-comp-collapsible-shape);
158
+ background-color: var(--md-comp-collapsible-container-color);
159
+ transition: margin var(--md-comp-collapsible-duration)
160
+ var(--md-comp-collapsible-easing-close);
161
+ @include z-depth("1");
162
+ }
64
163
 
65
- .collapsible.popout {
66
- border: none;
67
- box-shadow: none;
164
+ > :is(details, li) + :is(details, li) {
165
+ border-top: 0;
166
+ }
68
167
 
69
- > li {
70
- box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
71
- // transform: scaleX(.92);
72
- margin: 0 24px;
73
- transition: margin .35s cubic-bezier(0.250, 0.460, 0.450, 0.940);
168
+ > :is(details[open], li.active) {
169
+ margin-block: var(--md-comp-collapsible-popout-gap);
170
+ margin-inline: 0;
171
+ transition-timing-function: var(--md-comp-collapsible-easing-open);
172
+ @include z-depth("2");
173
+ }
74
174
  }
175
+ }
75
176
 
76
- > li.active {
77
- box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15);
78
- margin: 16px 0;
79
- // transform: scaleX(1);
177
+ @media (prefers-reduced-motion: reduce) {
178
+ .collapsible {
179
+ --md-comp-collapsible-duration: 0s;
80
180
  }
81
181
  }
@@ -1,114 +1,198 @@
1
1
  @use "../abstracts" as *;
2
2
 
3
+ // Collection. Anatomy is the HTML: a .collection of list items. A heading
4
+ // as the first child of an item is the header. An <a> may be the item
5
+ // (old <div class="collection"> markup) or live inside an <li>.
6
+ //
7
+ // Aliases: .collection-item, .collection-header, .with-header, .avatar,
8
+ // .title, .secondary-content. .flush drops the boxed outline.
9
+ //
10
+ // Tokens:
11
+ // --md-comp-collection-shape 12px
12
+ // --md-comp-collection-container-color surface
13
+ // --md-comp-collection-outline-color outline-variant
14
+ // --md-comp-collection-item-height 56px
15
+ // --md-comp-collection-item-padding 16px
16
+ // --md-comp-collection-avatar-size 40px
17
+ //
18
+ // Nest descendants inside this block. A list-suffixed selector only
19
+ // attaches the suffix to the last item (same bug as the icon sizes).
20
+
3
21
  .collection {
4
- padding-left: 0;
5
- list-style-type: none;
6
- margin: $element-top-margin 0 $element-bottom-margin 0;
7
- border: 1px solid var(--md-sys-color-outline-variant);
8
- border-radius: 2px;
22
+ --md-comp-collection-shape: 12px;
23
+ --md-comp-collection-container-color: var(--md-sys-color-surface);
24
+ --md-comp-collection-outline-color: var(--md-sys-color-outline-variant);
25
+ --md-comp-collection-item-height: 56px;
26
+ --md-comp-collection-item-padding: 16px;
27
+ --md-comp-collection-avatar-size: 40px;
28
+
29
+ box-sizing: border-box;
30
+ padding: 0;
31
+ margin: $element-top-margin 0 $element-bottom-margin;
9
32
  overflow: hidden;
10
- position: relative;
33
+ list-style: none;
34
+ border: 1px solid var(--md-comp-collection-outline-color);
35
+ border-radius: var(--md-comp-collection-shape);
36
+ background-color: var(--md-comp-collection-container-color);
37
+ color: var(--md-sys-color-on-surface);
38
+
39
+ > * + * {
40
+ border-top: 1px solid var(--md-comp-collection-outline-color);
41
+ }
11
42
 
12
- .collection-item {
13
- background-color: transparent;
14
- line-height: 1.5rem;
15
- padding: 10px 20px;
43
+ > :is(li, a, .collection-item, .collection-header) {
44
+ display: grid;
45
+ grid-template-columns: auto 1fr auto;
46
+ grid-template-rows: auto auto;
47
+ align-items: center;
48
+ column-gap: 16px;
49
+ box-sizing: border-box;
50
+ min-height: var(--md-comp-collection-item-height);
16
51
  margin: 0;
17
- border-bottom: 1px solid var(--md-sys-color-outline-variant);
18
-
19
- // Avatar Collection
20
- &.avatar {
21
- min-height: 84px;
22
- padding-left: 72px;
23
- position: relative;
24
-
25
- // Don't style circles inside preloader classes.
26
- &:not(.circle-clipper) > .circle,
27
- :not(.circle-clipper) > .circle {
28
- position: absolute;
29
- width: 42px;
30
- height: 42px;
31
- overflow: hidden;
32
- left: 15px;
33
- display: inline-block;
34
- vertical-align: middle;
35
- }
36
-
37
- i.circle {
38
- font-size: 18px;
39
- line-height: 42px;
40
- color: #fff;
41
- background-color: var(--md-sys-color-shadow);
42
- text-align: center;
43
- }
44
-
52
+ padding: 8px var(--md-comp-collection-item-padding);
53
+ background-color: transparent;
54
+ color: inherit;
55
+ text-decoration: none;
56
+ transition: background-color 0.2s ease-out;
57
+
58
+ > :is(img, i).circle {
59
+ grid-column: 1;
60
+ grid-row: 1 / -1;
61
+ box-sizing: border-box;
62
+ width: var(--md-comp-collection-avatar-size);
63
+ height: var(--md-comp-collection-avatar-size);
64
+ overflow: hidden;
65
+ object-fit: cover;
66
+ }
45
67
 
46
- .title {
47
- font-size: 16px;
48
- }
68
+ > i.circle {
69
+ display: inline-flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ font-size: 20px;
73
+ line-height: 1;
74
+ color: var(--md-sys-color-on-primary-container);
75
+ background-color: var(--md-sys-color-primary-container);
76
+ text-align: center;
77
+ }
49
78
 
50
- p {
51
- margin: 0;
52
- }
79
+ > .title {
80
+ grid-column: 2;
81
+ grid-row: 1;
82
+ min-width: 0;
83
+ @include typescale("title-medium");
84
+ }
53
85
 
54
- .secondary-content {
55
- position: absolute;
56
- top: 16px;
57
- right: 16px;
58
- }
86
+ > p {
87
+ grid-column: 2;
88
+ grid-row: 1;
89
+ min-width: 0;
90
+ margin: 0;
91
+ color: var(--md-sys-color-on-surface-variant);
92
+ @include typescale("body-medium");
59
93
  }
60
94
 
61
- &:last-child {
62
- border-bottom: none;
95
+ > .title ~ p {
96
+ grid-row: 2;
63
97
  }
64
98
 
65
- &.active {
66
- background-color: var(--md-sys-color-primary);
67
- color: var(--md-sys-color-on-primary);
99
+ > :is(.secondary-content, .badge) {
100
+ grid-column: 3;
101
+ grid-row: 1 / -1;
102
+ align-self: center;
103
+ justify-self: end;
104
+ }
68
105
 
69
- .secondary-content {
70
- color: var(--md-sys-color-on-primary);
106
+ > a:not(.secondary-content, .btn, .btn-floating, .badge) {
107
+ grid-column: 1 / -1;
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 16px;
111
+ min-width: 0;
112
+ color: inherit;
113
+ text-decoration: none;
114
+
115
+ > .badge {
116
+ margin-inline-start: auto;
71
117
  }
72
118
  }
73
119
  }
74
120
 
75
- a.collection-item {
76
- display: block;
77
- transition: .25s;
78
- color: var(--md-sys-color-primary);
121
+ > :is(li, .collection-item):is(.avatar, :has(> .circle)),
122
+ > a:has(> .circle) {
123
+ min-height: 72px;
124
+ }
79
125
 
80
- &:not(.active) {
81
- &:hover {
82
- background-color: rgba(0, 0, 0, 0.04);
83
- }
126
+ > :is(.collection-header, li:has(> :is(h1, h2, h3, h4, h5, h6))) {
127
+ min-height: 0;
128
+ padding-block: 12px;
129
+
130
+ > :is(h1, h2, h3, h4, h5, h6) {
131
+ grid-column: 1 / -1;
132
+ margin: 0;
133
+ @include typescale("title-medium");
84
134
  }
85
135
  }
86
136
 
87
- &.with-header {
88
- .collection-header {
89
- background-color: transparent;
90
- border-bottom: 1px solid var(--md-sys-color-outline-variant);
91
- padding: 10px 20px;
137
+ > a,
138
+ > li > a:not(.secondary-content, .btn, .btn-floating) {
139
+ @include focus-visible;
140
+ }
141
+
142
+ > a:hover,
143
+ > li:has(> a:not(.secondary-content, .btn, .btn-floating):hover) {
144
+ background-color: color-mix(in oklab, var(--md-sys-color-on-surface) 8%, transparent);
145
+ }
146
+
147
+ > :is(.active, [aria-current="page"]),
148
+ > li:has(> [aria-current="page"]) {
149
+ background-color: var(--md-sys-color-secondary-container);
150
+ color: var(--md-sys-color-on-secondary-container);
151
+
152
+ .secondary-content:not(.btn, .btn-floating) {
153
+ color: var(--md-sys-color-on-secondary-container);
92
154
  }
93
155
 
94
- .collection-item {
95
- padding-left: 30px;
156
+ span.badge:not(.new) {
157
+ color: var(--md-sys-color-on-secondary-container);
96
158
  }
159
+ }
97
160
 
98
- .collection-item.avatar {
99
- padding-left: 72px;
161
+ > :is(.disabled, [aria-disabled="true"]) {
162
+ pointer-events: none;
163
+ color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
164
+ }
165
+
166
+ .secondary-content {
167
+ float: none;
168
+ margin-inline-start: auto;
169
+ @include focus-visible;
170
+
171
+ &:not(.btn, .btn-floating) {
172
+ color: var(--md-sys-color-primary);
100
173
  }
101
174
  }
102
175
 
176
+ span.badge {
177
+ float: none;
178
+ margin-block: 0;
179
+ margin-inline-start: auto;
180
+ }
181
+
182
+ &.flush {
183
+ border: 0;
184
+ border-radius: 0;
185
+ }
103
186
  }
104
187
 
105
- // Made less specific to allow easier overriding
106
- .secondary-content {
107
- float: right;
188
+ // Keep the hook public so pages that used it outside a collection still
189
+ // color the trailing action. Layout (no float) is owned by .collection.
190
+ .secondary-content:not(.btn, .btn-floating) {
108
191
  color: var(--md-sys-color-primary);
109
192
  }
110
193
 
111
194
  .collapsible .collection {
112
195
  margin: 0;
113
196
  border: none;
114
- }
197
+ border-radius: 0;
198
+ }
@@ -1,8 +1,81 @@
1
1
  @use "../abstracts" as *;
2
2
 
3
- /* This is needed for some mobile phones to display the Google Icon font properly */
4
- .material-icons, .material-symbols-outlined,
5
- .material-symbols-rounded, .material-symbols-sharp {
3
+ // Material Symbols. The framework does not ship the font files — outlined,
4
+ // rounded, and sharp are three separate variable fonts, and pulling all
5
+ // three into the main sheet would dwarf the rest of the CSS. Load the
6
+ // families you use (see the Icons docs). Outlined with every axis:
7
+ //
8
+ // fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200
9
+ //
10
+ // Style (outlined / rounded / sharp) is the font family, not a variation
11
+ // axis. Switch it with the `icon-style` attribute (same idea as `theme`)
12
+ // or by setting --md-icon-font. Fill, weight, grade, and optical size
13
+ // are axes and inherit as custom properties.
14
+
15
+ :root {
16
+ --md-icon-font-outlined: "Material Symbols Outlined";
17
+ --md-icon-font-rounded: "Material Symbols Rounded";
18
+ --md-icon-font-sharp: "Material Symbols Sharp";
19
+ --md-icon-font: var(--md-icon-font-outlined);
20
+ --md-icon-fill: 0;
21
+ --md-icon-weight: 400;
22
+ --md-icon-grade: 0;
23
+ --md-icon-optical-size: 24;
24
+ }
25
+
26
+ [icon-style="outlined"] { --md-icon-font: var(--md-icon-font-outlined); }
27
+ [icon-style="rounded"] { --md-icon-font: var(--md-icon-font-rounded); }
28
+ [icon-style="sharp"] { --md-icon-font: var(--md-icon-font-sharp); }
29
+
30
+ $_icon: ".material-symbols, .material-symbols-outlined, .material-symbols-rounded, .material-symbols-sharp, .material-icons";
31
+
32
+ #{$_icon} {
33
+ display: inline-block;
34
+ font-family: var(--md-icon-font);
35
+ font-weight: normal;
36
+ font-style: normal;
37
+ font-size: 24px;
38
+ line-height: 1;
39
+ letter-spacing: normal;
40
+ text-transform: none;
41
+ white-space: nowrap;
42
+ word-wrap: normal;
43
+ direction: ltr;
44
+ user-select: none;
6
45
  text-rendering: optimizeLegibility;
7
- font-feature-settings: 'liga';
46
+ font-feature-settings: "liga";
47
+ -webkit-font-smoothing: antialiased;
48
+ font-variation-settings:
49
+ "FILL" var(--md-icon-fill),
50
+ "wght" var(--md-icon-weight),
51
+ "GRAD" var(--md-icon-grade),
52
+ "opsz" var(--md-icon-optical-size);
53
+
54
+ // Nest so each class in $_icon gets the suffix. `#{$_icon}.tiny` would
55
+ // only attach `.tiny` to the last item and leave every other icon
56
+ // matching the bare `.material-symbols` selector — including `.large`.
57
+ &.tiny {
58
+ font-size: 1rem;
59
+ --md-icon-optical-size: 20;
60
+ }
61
+ &.small {
62
+ font-size: 2rem;
63
+ --md-icon-optical-size: 24;
64
+ }
65
+ &.medium {
66
+ font-size: 4rem;
67
+ --md-icon-optical-size: 40;
68
+ }
69
+ &.large {
70
+ font-size: 6rem;
71
+ --md-icon-optical-size: 48;
72
+ }
8
73
  }
74
+
75
+ // One-off family overrides. These only change --md-icon-font so the
76
+ // inherited fill / weight / grade / opsz still apply.
77
+ .material-symbols-outlined { --md-icon-font: var(--md-icon-font-outlined); }
78
+ .material-symbols-rounded { --md-icon-font: var(--md-icon-font-rounded); }
79
+ .material-symbols-sharp { --md-icon-font: var(--md-icon-font-sharp); }
80
+
81
+ .icon-filled { --md-icon-fill: 1; }
@@ -6,6 +6,10 @@
6
6
  position: relative;
7
7
  transition: opacity .4s;
8
8
  backface-visibility: hidden;
9
+ // Same 12px as .responsive-img. Exclude .circle so a disc stays a disc.
10
+ &:not(.circle) {
11
+ border-radius: 12px;
12
+ }
9
13
 
10
14
  &:hover {
11
15
  &:not(.active) {