@expressivecss/expressive 0.1.0-alpha.3 → 0.1.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 (152) hide show
  1. package/LICENSE +82 -2
  2. package/README.md +153 -43
  3. package/dist/css/expressive.css +7066 -9658
  4. package/dist/css/expressive.css.map +1 -0
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -0
  7. package/dist/js/expressive.cjs +7451 -0
  8. package/dist/js/expressive.cjs.map +7 -0
  9. package/dist/js/expressive.js +7313 -8099
  10. package/dist/js/expressive.js.map +7 -1
  11. package/dist/js/expressive.min.js +75 -1
  12. package/dist/js/expressive.min.js.map +7 -1
  13. package/dist/js/expressive.mjs +7222 -7998
  14. package/dist/js/expressive.mjs.map +7 -1
  15. package/dist/{js → types}/components/autocomplete.d.ts +10 -1
  16. package/dist/{js → types}/components/buttons.d.ts +11 -1
  17. package/dist/{js → types}/components/cards.d.ts +10 -1
  18. package/dist/{js → types}/components/carousel.d.ts +4 -5
  19. package/dist/{js/forms/character-counter.d.ts → types/components/characterCounter.d.ts} +1 -1
  20. package/dist/{js → types}/components/chips.d.ts +1 -1
  21. package/dist/{js → types}/components/collapsible.d.ts +1 -1
  22. package/dist/{js → types}/components/datepicker.d.ts +63 -2
  23. package/dist/{js → types}/components/dropdown.d.ts +3 -3
  24. package/dist/types/components/index.d.ts +23 -0
  25. package/dist/{js/components/materialbox.d.ts → types/components/lightbox.d.ts} +21 -21
  26. package/dist/{js → types}/components/modal.d.ts +1 -1
  27. package/dist/{js → types}/components/parallax.d.ts +11 -5
  28. package/dist/{js → types}/components/pushpin.d.ts +1 -1
  29. package/dist/{js/forms → types/components}/range.d.ts +3 -3
  30. package/dist/types/components/registry.d.ts +107 -0
  31. package/dist/{js → types}/components/scrollspy.d.ts +6 -9
  32. package/dist/{js/forms → types/components}/select.d.ts +11 -2
  33. package/dist/{js → types}/components/sidenav.d.ts +1 -1
  34. package/dist/{js → types}/components/slider.d.ts +3 -2
  35. package/dist/{js → types}/components/tabs.d.ts +3 -2
  36. package/dist/{js/components/tap-target.d.ts → types/components/tapTarget.d.ts} +2 -2
  37. package/dist/{js → types}/components/timepicker.d.ts +13 -5
  38. package/dist/{js/components/toast.d.ts → types/components/toasts.d.ts} +28 -4
  39. package/dist/{js → types}/components/tooltip.d.ts +2 -2
  40. package/dist/types/core/bounding.d.ts +6 -0
  41. package/dist/{js/foundation → types/core}/component.d.ts +1 -1
  42. package/dist/types/core/edges.d.ts +6 -0
  43. package/dist/{js/foundation → types/core}/utils.d.ts +21 -14
  44. package/dist/types/index.d.ts +6 -0
  45. package/dist/{js/plugins/docked-display.d.ts → types/plugins/dockedDisplayPlugin.d.ts} +7 -0
  46. package/package.json +60 -36
  47. package/src/sass/README.md +200 -0
  48. package/src/sass/abstracts/_breakpoints.scss +69 -0
  49. package/src/sass/abstracts/_elevation.scss +34 -0
  50. package/src/sass/abstracts/_index.scss +7 -0
  51. package/src/sass/abstracts/_mixins.scss +171 -0
  52. package/src/sass/abstracts/_variables.scss +57 -0
  53. package/src/{scss/layout/_table.scss → sass/base/_global.scss} +64 -2
  54. package/src/{scss/layout → sass/base}/_grid.scss +6 -6
  55. package/src/sass/base/_index.scss +6 -0
  56. package/src/{scss/foundation → sass/base}/_normalize.scss +51 -139
  57. package/src/sass/base/_typography.scss +90 -0
  58. package/src/sass/components/_badges.scss +77 -0
  59. package/src/{scss → sass}/components/_breadcrumb.scss +2 -0
  60. package/src/sass/components/_buttons.scss +407 -0
  61. package/src/sass/components/_cards.scss +328 -0
  62. package/src/{scss → sass}/components/_carousel.scss +5 -3
  63. package/src/sass/components/_chips.scss +140 -0
  64. package/src/sass/components/_collapsible.scss +81 -0
  65. package/src/{scss → sass}/components/_collection.scss +2 -2
  66. package/src/{scss/components/_date-picker.scss → sass/components/_datepicker.scss} +51 -44
  67. package/src/sass/components/_docked-display.scss +11 -0
  68. package/src/sass/components/_dropdown.scss +129 -0
  69. package/src/{scss/components/_material-icons.scss → sass/components/_icons-material-design.scss} +2 -0
  70. package/src/sass/components/_index.scss +35 -0
  71. package/src/{scss/components/_material-box.scss → sass/components/_lightbox.scss} +6 -4
  72. package/src/sass/components/_modal.scss +144 -0
  73. package/src/sass/components/_navbar.scss +345 -0
  74. package/src/{scss/layout/_footer.scss → sass/components/_page-footer.scss} +7 -6
  75. package/src/{scss → sass}/components/_pagination.scss +4 -3
  76. package/src/{scss → sass}/components/_parallax.scss +4 -1
  77. package/src/{scss → sass}/components/_preloader.scss +19 -97
  78. package/src/{scss → sass}/components/_pulse.scss +2 -0
  79. package/src/sass/components/_pushpin.scss +11 -0
  80. package/src/{scss → sass}/components/_sidenav.scss +99 -82
  81. package/src/{scss → sass}/components/_slider.scss +3 -1
  82. package/src/{scss/components/_table-of-contents.scss → sass/components/_table_of_contents.scss} +2 -0
  83. package/src/sass/components/_tabs.scss +232 -0
  84. package/src/{scss/components/_tap-target.scss → sass/components/_tapTarget.scss} +24 -22
  85. package/src/{scss/components/_time-picker.scss → sass/components/_timepicker.scss} +56 -56
  86. package/src/sass/components/_toast.scss +260 -0
  87. package/src/sass/components/_toolbar.scss +192 -0
  88. package/src/sass/components/_tooltip.scss +166 -0
  89. package/src/{scss → sass}/components/_transitions.scss +4 -4
  90. package/src/sass/components/forms/_checkboxes.scss +288 -0
  91. package/src/sass/components/forms/_fieldset.scss +128 -0
  92. package/src/{scss → sass/components}/forms/_file-input.scss +11 -9
  93. package/src/{scss → sass/components}/forms/_index.scss +2 -0
  94. package/src/sass/components/forms/_input-fields.scss +326 -0
  95. package/src/sass/components/forms/_radio-buttons.scss +190 -0
  96. package/src/sass/components/forms/_range.scss +310 -0
  97. package/src/sass/components/forms/_select.scss +103 -0
  98. package/src/sass/components/forms/_switches.scss +239 -0
  99. package/src/sass/expressive.scss +60 -0
  100. package/src/sass/tokens/_index.scss +4 -0
  101. package/src/sass/tokens/_reference.scss +265 -0
  102. package/src/sass/tokens/_theme.scss +49 -0
  103. package/src/{scss → sass}/utilities/_helpers.scss +33 -30
  104. package/src/sass/utilities/_index.scss +8 -0
  105. package/src/{scss → sass}/utilities/_spacing.scss +4 -3
  106. package/src/sass/utilities/_typescale.scss +45 -0
  107. package/src/sass/utilities/_visibility.scss +63 -0
  108. package/src/sass/utilities/_z-depth.scss +18 -0
  109. package/dist/js/components/index.d.ts +0 -21
  110. package/dist/js/forms/index.d.ts +0 -4
  111. package/dist/js/foundation/index.d.ts +0 -2
  112. package/dist/js/index.d.ts +0 -52
  113. package/dist/js/plugins/index.d.ts +0 -1
  114. package/src/scss/components/_appbar.scss +0 -454
  115. package/src/scss/components/_badges.scss +0 -77
  116. package/src/scss/components/_buttons.scss +0 -412
  117. package/src/scss/components/_cards.scss +0 -267
  118. package/src/scss/components/_chips.scss +0 -147
  119. package/src/scss/components/_collapsible.scss +0 -84
  120. package/src/scss/components/_dropdown.scss +0 -98
  121. package/src/scss/components/_index.scss +0 -28
  122. package/src/scss/components/_modal.scss +0 -84
  123. package/src/scss/components/_tabs.scss +0 -176
  124. package/src/scss/components/_toast.scss +0 -70
  125. package/src/scss/components/_tooltip.scss +0 -49
  126. package/src/scss/components/_video.scss +0 -15
  127. package/src/scss/expressive.scss +0 -7
  128. package/src/scss/forms/_checkboxes.scss +0 -199
  129. package/src/scss/forms/_input-fields.scss +0 -360
  130. package/src/scss/forms/_radio-buttons.scss +0 -114
  131. package/src/scss/forms/_range.scss +0 -148
  132. package/src/scss/forms/_select.scss +0 -108
  133. package/src/scss/forms/_switches.scss +0 -127
  134. package/src/scss/foundation/_base.scss +0 -71
  135. package/src/scss/foundation/_color-palette.scss +0 -402
  136. package/src/scss/foundation/_index.scss +0 -10
  137. package/src/scss/foundation/_mixins.scss +0 -198
  138. package/src/scss/foundation/_motion.scss +0 -70
  139. package/src/scss/foundation/_shape.scss +0 -30
  140. package/src/scss/foundation/_state-layers.scss +0 -68
  141. package/src/scss/foundation/_theme.scss +0 -238
  142. package/src/scss/foundation/_tokens.scss +0 -511
  143. package/src/scss/foundation/_variables.scss +0 -57
  144. package/src/scss/layout/_index.scss +0 -3
  145. package/src/scss/utilities/_a11y.scss +0 -77
  146. package/src/scss/utilities/_elevation.scss +0 -63
  147. package/src/scss/utilities/_index.scss +0 -7
  148. package/src/scss/utilities/_responsive.scss +0 -62
  149. package/src/scss/utilities/_typography.scss +0 -115
  150. /package/dist/{js/forms → types/behaviors}/forms.d.ts +0 -0
  151. /package/dist/{js/components → types/behaviors}/waves.d.ts +0 -0
  152. /package/src/{scss → sass}/utilities/_colors.scss +0 -0
@@ -0,0 +1,260 @@
1
+ @use "../abstracts" as *;
2
+
3
+ // Snackbars (toasts).
4
+ //
5
+ // Anatomy is the HTML. A .snackbar / .toast is the container. A <p> (or
6
+ // <span>, or loose text) is the supporting text. A trailing <button> is
7
+ // the action; a .circle button is the optional close. An optional leading
8
+ // <i> is an icon. .toast-action stays as an alias on the action control.
9
+ //
10
+ // Tokens follow https://m3.material.io/components/snackbar/specs
11
+ // container inverse-surface, 4dp corners, elevation 3, min 48dp
12
+ // width hug, min 344 / max 672 (full-bleed inset on compact)
13
+ // text body-medium / inverse-on-surface, two lines max
14
+ // action label-large / inverse-primary text button
15
+ // close 24dp icon, inverse-on-surface
16
+ // inset 8dp compact, 24dp from start+bottom on larger screens
17
+ //
18
+ // The constructor always adds both .toast and .snackbar. A static
19
+ // .snackbar is in-flow (docs previews). .active pins it to the viewport.
20
+ // There is no AutoInit and no toast() helper.
21
+
22
+ $_bar: ":is(.toast, .snackbar)";
23
+
24
+ #toast-container {
25
+ --md-comp-snackbar-container-margin-leading: 8px;
26
+ --md-comp-snackbar-container-margin-trailing: 8px;
27
+ --md-comp-snackbar-container-margin-bottom: 8px;
28
+ --md-comp-snackbar-container-margin-top: 8px;
29
+
30
+ display: flex;
31
+ flex-direction: column;
32
+ align-items: stretch;
33
+ gap: 8px;
34
+ position: fixed;
35
+ z-index: 10000;
36
+ inset: auto var(--md-comp-snackbar-container-margin-trailing)
37
+ var(--md-comp-snackbar-container-margin-bottom)
38
+ var(--md-comp-snackbar-container-margin-leading);
39
+ width: auto;
40
+ max-width: calc(100% - var(--md-comp-snackbar-container-margin-leading) - var(--md-comp-snackbar-container-margin-trailing));
41
+ pointer-events: none;
42
+
43
+ > * {
44
+ pointer-events: auto;
45
+ }
46
+
47
+ @include bp-up("small") {
48
+ --md-comp-snackbar-container-margin-leading: 24px;
49
+ --md-comp-snackbar-container-margin-trailing: 24px;
50
+ --md-comp-snackbar-container-margin-bottom: 24px;
51
+ --md-comp-snackbar-container-margin-top: 24px;
52
+ align-items: flex-start;
53
+ width: max-content;
54
+ min-width: min(344px, calc(100% - 48px));
55
+ max-width: min(672px, calc(100% - 48px));
56
+ }
57
+
58
+ // Position helpers on the container, or on a child via :has().
59
+ &:has(> .top),
60
+ &.top {
61
+ inset: var(--md-comp-snackbar-container-margin-top)
62
+ var(--md-comp-snackbar-container-margin-trailing)
63
+ auto
64
+ var(--md-comp-snackbar-container-margin-leading);
65
+ }
66
+
67
+ &:has(> .center),
68
+ &.center {
69
+ left: 50%;
70
+ right: auto;
71
+ transform: translateX(-50%);
72
+ }
73
+ }
74
+
75
+ #{$_bar} {
76
+ --md-comp-snackbar-container-color: var(--md-sys-color-inverse-surface);
77
+ --md-comp-snackbar-container-shape: 4px;
78
+ --md-comp-snackbar-supporting-text-color: var(--md-sys-color-inverse-on-surface);
79
+ --md-comp-snackbar-action-label-text-color: var(--md-sys-color-inverse-primary);
80
+ --md-comp-snackbar-icon-color: var(--md-sys-color-inverse-on-surface);
81
+
82
+ box-sizing: border-box;
83
+ display: flex;
84
+ align-items: center;
85
+ gap: 8px;
86
+ width: 100%;
87
+ min-width: 0;
88
+ max-width: 672px;
89
+ min-height: 48px;
90
+ margin: 0;
91
+ padding: 4px 8px 4px 16px;
92
+ border: none;
93
+ border-radius: var(--md-comp-snackbar-container-shape);
94
+ background-color: var(--md-comp-snackbar-container-color);
95
+ color: var(--md-comp-snackbar-supporting-text-color);
96
+ @include typescale("body-medium");
97
+ @include z-depth("3");
98
+ cursor: default;
99
+
100
+ @include bp-up("small") {
101
+ width: max-content;
102
+ min-width: min(344px, 100%);
103
+ }
104
+
105
+ // Supporting text. A bare <p> is body-large in the type layer — reset it.
106
+ > p,
107
+ > span {
108
+ flex: 1 1 auto;
109
+ min-width: 0;
110
+ margin: 0;
111
+ padding-block: 10px;
112
+ color: var(--md-comp-snackbar-supporting-text-color);
113
+ @include typescale("body-medium");
114
+ display: -webkit-box;
115
+ -webkit-box-orient: vertical;
116
+ -webkit-line-clamp: 2;
117
+ overflow: hidden;
118
+ }
119
+
120
+ // Optional leading icon (BeerCSS). M3 snackbars have no leading icon.
121
+ > i:first-child {
122
+ flex: 0 0 auto;
123
+ font-size: 24px;
124
+ width: 24px;
125
+ height: 24px;
126
+ line-height: 24px;
127
+ color: var(--md-comp-snackbar-icon-color);
128
+ }
129
+
130
+ // Inline links in the supporting text use the action color.
131
+ a:not(.button, .toast-action) {
132
+ color: var(--md-comp-snackbar-action-label-text-color);
133
+ }
134
+
135
+ // Action row. A bare <nav> just groups the action and close.
136
+ > nav {
137
+ display: flex;
138
+ flex: 0 0 auto;
139
+ align-items: center;
140
+ gap: 0;
141
+ margin: 0;
142
+ padding: 0;
143
+ min-height: 0;
144
+ height: auto;
145
+ background: none;
146
+ box-shadow: none;
147
+ }
148
+
149
+ // Text action — inverse-primary, not the filled common-button default.
150
+ > :is(button, a.button, a.toast-action, .toast-action):not(.circle),
151
+ > nav > :is(button, a.button, a.toast-action, .toast-action):not(.circle) {
152
+ flex: 0 0 auto;
153
+ height: 40px;
154
+ min-width: 48px;
155
+ padding: 0 12px;
156
+ border: none;
157
+ border-radius: 20px;
158
+ background-color: transparent;
159
+ color: var(--md-comp-snackbar-action-label-text-color);
160
+ box-shadow: none;
161
+ @include typescale("label-large");
162
+
163
+ &:hover {
164
+ background-color: color-mix(in oklab, var(--md-sys-color-inverse-primary) 8%, transparent);
165
+ }
166
+
167
+ &:active,
168
+ &:focus {
169
+ background-color: color-mix(in oklab, var(--md-sys-color-inverse-primary) 10%, transparent);
170
+ }
171
+
172
+ &:focus-visible {
173
+ outline: 3px solid var(--md-sys-color-inverse-primary);
174
+ outline-offset: 2px;
175
+ }
176
+ }
177
+
178
+ // Close — 40dp icon button so it sits in the 48dp single-line bar.
179
+ > :is(button, a).circle,
180
+ > nav > :is(button, a).circle {
181
+ flex: 0 0 auto;
182
+ width: 40px;
183
+ height: 40px;
184
+ padding: 0;
185
+ border: none;
186
+ border-radius: 50%;
187
+ background-color: transparent;
188
+ color: var(--md-comp-snackbar-icon-color);
189
+ box-shadow: none;
190
+
191
+ > i {
192
+ font-size: 24px;
193
+ width: 24px;
194
+ height: 24px;
195
+ line-height: 24px;
196
+ }
197
+
198
+ &:hover {
199
+ background-color: color-mix(in oklab, var(--md-sys-color-inverse-on-surface) 8%, transparent);
200
+ }
201
+
202
+ &:active,
203
+ &:focus {
204
+ background-color: color-mix(in oklab, var(--md-sys-color-inverse-on-surface) 10%, transparent);
205
+ }
206
+
207
+ &:focus-visible {
208
+ outline: 3px solid var(--md-sys-color-inverse-on-surface);
209
+ outline-offset: 2px;
210
+ }
211
+ }
212
+
213
+ // Optional stadium. M3 default is extra-small (4dp).
214
+ &.rounded {
215
+ border-radius: 24px;
216
+ }
217
+ }
218
+
219
+ // Stacked in-flow previews. JS toasts use the container gap instead.
220
+ #{$_bar} + #{$_bar} {
221
+ margin-top: 8px;
222
+ }
223
+
224
+ // JS enter animation starts the bar 35px below its rest position.
225
+ #toast-container #{$_bar} {
226
+ position: relative;
227
+ top: 35px;
228
+ margin-top: 0;
229
+ }
230
+
231
+ // Static overlay. In-flow without this (docs previews). Not AutoInit —
232
+ // add and remove the class yourself, or use the constructor for timing.
233
+ #{$_bar}.active {
234
+ position: fixed;
235
+ z-index: 10000;
236
+ inset: auto auto 16px 16px;
237
+ top: auto;
238
+ width: max-content;
239
+ max-width: min(672px, calc(100% - 32px));
240
+
241
+ @include bp-down("small") {
242
+ inset: auto 8px 8px 8px;
243
+ width: auto;
244
+ max-width: none;
245
+ }
246
+
247
+ &.top {
248
+ inset: 16px auto auto 16px;
249
+
250
+ @include bp-down("small") {
251
+ inset: 8px 8px auto 8px;
252
+ }
253
+ }
254
+
255
+ &.center {
256
+ left: 50%;
257
+ right: auto;
258
+ transform: translateX(-50%);
259
+ }
260
+ }
@@ -0,0 +1,192 @@
1
+ @use "../abstracts" as *;
2
+
3
+ // Toolbars.
4
+ //
5
+ // Anatomy is the HTML. A <nav class="toolbar"> is the bar. Direct
6
+ // <button> / <a> children are the actions. An <i> is the icon; wrap a
7
+ // label in <span>. .active marks the selected action. Helpers are only
8
+ // for variants markup cannot express: .filled, .vertical, .max / .docked,
9
+ // .fixed, .top, .bottom.
10
+ //
11
+ // Tokens follow https://m3.material.io/components/toolbars/specs
12
+ // floating hug, 64dp, 32dp stadium, surface-variant, elevation 2
13
+ // docked full width, 64dp, 0 radius, surface-variant, no elevation
14
+ // (M3 replacement for the bottom app bar)
15
+ // vibrant primary-container / on-primary-container (.filled)
16
+ // action 48dp target, 24dp icon, transparent at rest
17
+ // selected secondary-container / on-secondary-container
18
+ //
19
+ // nav.toolbar only — do not style every <nav> (app bars, card actions,
20
+ // radio rows). div.fixed-action-btn.toolbar is the FAB-to-toolbar
21
+ // transition, not this component.
22
+
23
+ nav.toolbar {
24
+ --md-comp-toolbar-container-color: var(--md-sys-color-surface-variant);
25
+ --md-comp-toolbar-container-shape: 32px;
26
+ --md-comp-toolbar-container-height: 64px;
27
+ --md-comp-toolbar-leading-space: 12px;
28
+ --md-comp-toolbar-action-size: 48px;
29
+ --md-comp-toolbar-icon-size: 24px;
30
+
31
+ box-sizing: border-box;
32
+ display: inline-flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ gap: 4px;
36
+ min-height: var(--md-comp-toolbar-container-height);
37
+ min-width: var(--md-comp-toolbar-container-height);
38
+ margin: 0;
39
+ padding: 8px var(--md-comp-toolbar-leading-space);
40
+ border: none;
41
+ border-radius: var(--md-comp-toolbar-container-shape);
42
+ background-color: var(--md-comp-toolbar-container-color);
43
+ color: var(--md-sys-color-on-surface);
44
+ @include z-depth("2");
45
+
46
+ & + & {
47
+ margin-block-start: 16px;
48
+ }
49
+
50
+ // Actions — transparent at rest so they sit on the container, not filled.
51
+ // .extra is the 56dp FAB; leave it alone so a docked bar can embed one.
52
+ > :is(a, button):not(.btn-floating, .extra) {
53
+ box-sizing: border-box;
54
+ display: inline-flex;
55
+ flex: 0 0 auto;
56
+ align-items: center;
57
+ justify-content: center;
58
+ gap: 8px;
59
+ min-width: var(--md-comp-toolbar-action-size);
60
+ min-height: var(--md-comp-toolbar-action-size);
61
+ height: var(--md-comp-toolbar-action-size);
62
+ margin: 0;
63
+ padding: 0 12px;
64
+ border: none;
65
+ border-radius: calc(var(--md-comp-toolbar-action-size) / 2);
66
+ background-color: transparent;
67
+ color: inherit;
68
+ box-shadow: none;
69
+ text-decoration: none;
70
+ cursor: pointer;
71
+ appearance: none;
72
+ @include typescale("label-large");
73
+ font-family: $font-stack;
74
+ @include focus-visible;
75
+
76
+ > i {
77
+ flex: 0 0 auto;
78
+ font-size: var(--md-comp-toolbar-icon-size);
79
+ width: var(--md-comp-toolbar-icon-size);
80
+ height: var(--md-comp-toolbar-icon-size);
81
+ line-height: var(--md-comp-toolbar-icon-size);
82
+ }
83
+
84
+ &:hover:not(.active) {
85
+ background-color: color-mix(in oklab, currentColor 8%, transparent);
86
+ }
87
+
88
+ &:active:not(.active) {
89
+ background-color: color-mix(in oklab, currentColor 10%, transparent);
90
+ }
91
+
92
+ &.active {
93
+ background-color: var(--md-sys-color-secondary-container);
94
+ color: var(--md-sys-color-on-secondary-container);
95
+ }
96
+
97
+ &:disabled {
98
+ color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
99
+ background-color: transparent;
100
+ box-shadow: none;
101
+ cursor: default;
102
+ }
103
+ }
104
+
105
+ // Icon-only — .circle, or an <i> with no <span> sibling.
106
+ > :is(a, button):not(.btn-floating, .extra):is(.circle, :has(> i):not(:has(> span))) {
107
+ width: var(--md-comp-toolbar-action-size);
108
+ padding: 0;
109
+ border-radius: 50%;
110
+ }
111
+
112
+ // Spacer between leading and trailing actions.
113
+ > .max {
114
+ flex: 1 1 auto;
115
+ align-self: stretch;
116
+ min-width: 0;
117
+ min-height: 0;
118
+ }
119
+ }
120
+
121
+ // Vibrant. Pair with .active using the inverse of the container.
122
+ nav.toolbar.filled {
123
+ --md-comp-toolbar-container-color: var(--md-sys-color-primary-container);
124
+ color: var(--md-sys-color-on-primary-container);
125
+
126
+ > :is(a, button).active {
127
+ background-color: var(--md-sys-color-surface-variant);
128
+ color: var(--md-sys-color-on-surface);
129
+ }
130
+ }
131
+
132
+ // Vertical floating bar.
133
+ nav.toolbar.vertical {
134
+ flex-direction: column;
135
+ min-width: var(--md-comp-toolbar-container-height);
136
+ min-height: var(--md-comp-toolbar-container-height);
137
+ padding: var(--md-comp-toolbar-leading-space) 8px;
138
+
139
+ > .max {
140
+ min-width: 0;
141
+ min-height: 0;
142
+ width: 100%;
143
+ }
144
+ }
145
+
146
+ // Docked — full width, square, no lift. M3's replacement for the bottom
147
+ // app bar. .max is the BeerCSS name; .docked is the M3 name.
148
+ nav.toolbar.max,
149
+ nav.toolbar.docked {
150
+ display: flex;
151
+ width: 100%;
152
+ --md-comp-toolbar-container-shape: 0;
153
+ justify-content: space-around;
154
+ @include z-depth("0");
155
+ }
156
+
157
+ // Pin to the viewport. Floating defaults to bottom-center; docked
158
+ // defaults to the bottom edge.
159
+ nav.toolbar.fixed {
160
+ position: fixed;
161
+ z-index: 996;
162
+ inset: auto auto 16px 50%;
163
+ transform: translateX(-50%);
164
+ }
165
+
166
+ nav.toolbar.fixed.top {
167
+ inset: 16px auto auto 50%;
168
+ }
169
+
170
+ nav.toolbar.fixed.bottom {
171
+ inset: auto auto 16px 50%;
172
+ }
173
+
174
+ nav.toolbar.vertical.fixed {
175
+ inset: 50% auto auto 16px;
176
+ transform: translateY(-50%);
177
+ }
178
+
179
+ nav.toolbar.vertical.fixed.right {
180
+ inset: 50% 16px auto auto;
181
+ }
182
+
183
+ nav.toolbar:is(.max, .docked).fixed,
184
+ nav.toolbar:is(.max, .docked).fixed.bottom {
185
+ inset: auto 0 0 0;
186
+ transform: none;
187
+ }
188
+
189
+ nav.toolbar:is(.max, .docked).fixed.top {
190
+ inset: 0 0 auto 0;
191
+ transform: none;
192
+ }
@@ -0,0 +1,166 @@
1
+ @use "../abstracts" as *;
2
+
3
+ // Tooltips.
4
+ //
5
+ // Anatomy is the HTML. A child .tooltip is the bubble — no .tooltipped
6
+ // required. Helpers are only for placement and the rich variant:
7
+ // .top (default), .bottom, .left, .right, .rich / .max.
8
+ //
9
+ // Tokens follow https://m3.material.io/components/tooltips/specs
10
+ // plain inverse-surface / inverse-on-surface, 4dp, body-small
11
+ // min 24dp, pad 4/8, max 200dp, no elevation, no caret
12
+ // rich surface, elevation 2, 12dp, title-small + body-medium
13
+ // pad 12/16, max 320dp, optional action
14
+ // gap 4dp from the activator
15
+ //
16
+ // The JS plugin still exists: .tooltipped + data-tooltip, AutoInit,
17
+ // class .tooltip.material-tooltip appended to <body>. .material-tooltip
18
+ // is an alias. There is no data-html / unsafeHTML.
19
+
20
+ .tooltip,
21
+ .material-tooltip {
22
+ --md-comp-plain-tooltip-container-color: var(--md-sys-color-inverse-surface);
23
+ --md-comp-plain-tooltip-supporting-text-color: var(--md-sys-color-inverse-on-surface);
24
+ --md-comp-plain-tooltip-container-shape: 4px;
25
+ --md-comp-tooltip-anchor-gap: 4px;
26
+
27
+ box-sizing: border-box;
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ gap: 8px;
32
+ min-height: 24px;
33
+ max-width: 200px;
34
+ margin: 0;
35
+ padding: 4px 8px;
36
+ border: none;
37
+ border-radius: var(--md-comp-plain-tooltip-container-shape);
38
+ background-color: var(--md-comp-plain-tooltip-container-color);
39
+ color: var(--md-comp-plain-tooltip-supporting-text-color);
40
+ @include typescale("body-small");
41
+ text-align: center;
42
+ white-space: nowrap;
43
+ pointer-events: none;
44
+ z-index: 2000;
45
+ }
46
+
47
+ // CSS-only: a child of the activator. Default sits above (M3 preferred).
48
+ :not(body):has(> .tooltip) {
49
+ position: relative;
50
+ }
51
+
52
+ // Only shrink-wrap typical activators. A stray .tooltip as a section
53
+ // child must not turn the section into inline-flex (invalid <p><div>
54
+ // gets hoisted and would match).
55
+ :is(button, a, span, label, i):has(> .tooltip) {
56
+ display: inline-flex;
57
+ }
58
+
59
+ :not(body) > .tooltip {
60
+ position: absolute;
61
+ visibility: hidden;
62
+ opacity: 0;
63
+ inset: 0 auto auto 50%;
64
+ transform: translate(-50%, calc(-100% - var(--md-comp-tooltip-anchor-gap))) scale(0.96);
65
+ transition: opacity .15s ease-out, transform .15s ease-out, visibility 0s linear .15s;
66
+ }
67
+
68
+ :not(body) > .tooltip.bottom {
69
+ inset: auto auto 0 50%;
70
+ transform: translate(-50%, calc(100% + var(--md-comp-tooltip-anchor-gap))) scale(0.96);
71
+ }
72
+
73
+ :not(body) > .tooltip.left {
74
+ inset: 50% auto auto 0;
75
+ transform: translate(calc(-100% - var(--md-comp-tooltip-anchor-gap)), -50%) scale(0.96);
76
+ }
77
+
78
+ :not(body) > .tooltip.right {
79
+ inset: 50% 0 auto auto;
80
+ transform: translate(calc(100% + var(--md-comp-tooltip-anchor-gap)), -50%) scale(0.96);
81
+ }
82
+
83
+ :is(:hover, :focus-visible, :focus-within):not(body) > .tooltip,
84
+ :not(body) > .tooltip:hover {
85
+ visibility: visible;
86
+ opacity: 1;
87
+ transition-delay: 0s;
88
+ }
89
+
90
+ :is(:hover, :focus-visible, :focus-within):not(body) > .tooltip:not(.left, .right, .bottom),
91
+ :not(body) > .tooltip:not(.left, .right, .bottom):hover {
92
+ transform: translate(-50%, calc(-100% - var(--md-comp-tooltip-anchor-gap))) scale(1);
93
+ }
94
+
95
+ :is(:hover, :focus-visible, :focus-within):not(body) > .tooltip.bottom,
96
+ :not(body) > .tooltip.bottom:hover {
97
+ transform: translate(-50%, calc(100% + var(--md-comp-tooltip-anchor-gap))) scale(1);
98
+ }
99
+
100
+ :is(:hover, :focus-visible, :focus-within):not(body) > .tooltip.left,
101
+ :not(body) > .tooltip.left:hover {
102
+ transform: translate(calc(-100% - var(--md-comp-tooltip-anchor-gap)), -50%) scale(1);
103
+ }
104
+
105
+ :is(:hover, :focus-visible, :focus-within):not(body) > .tooltip.right,
106
+ :not(body) > .tooltip.right:hover {
107
+ transform: translate(calc(100% + var(--md-comp-tooltip-anchor-gap)), -50%) scale(1);
108
+ }
109
+
110
+ // JS plugin: appended to <body>, top/left set in script. Do not use the
111
+ // child-positioning rules; they would fight the inline transform.
112
+ body > .tooltip,
113
+ .material-tooltip {
114
+ position: absolute;
115
+ left: 0;
116
+ top: 0;
117
+ visibility: hidden;
118
+ opacity: 0;
119
+ overflow: hidden;
120
+ }
121
+
122
+ // Rich tooltip — title, supporting text, optional action.
123
+ .tooltip.rich,
124
+ .tooltip.max,
125
+ .material-tooltip.rich,
126
+ .material-tooltip.max {
127
+ --md-comp-rich-tooltip-container-color: var(--md-sys-color-surface);
128
+ --md-comp-rich-tooltip-container-shape: 12px;
129
+
130
+ display: flex;
131
+ flex-direction: column;
132
+ align-items: stretch;
133
+ gap: 4px;
134
+ min-width: 160px;
135
+ max-width: 320px;
136
+ padding: 12px 16px;
137
+ border-radius: var(--md-comp-rich-tooltip-container-shape);
138
+ background-color: var(--md-comp-rich-tooltip-container-color);
139
+ color: var(--md-sys-color-on-surface);
140
+ text-align: start;
141
+ white-space: normal;
142
+ pointer-events: auto;
143
+ @include z-depth("2");
144
+
145
+ > :is(h1, h2, h3, h4, h5, h6) {
146
+ margin: 0;
147
+ color: var(--md-sys-color-on-surface);
148
+ @include typescale("title-small");
149
+ }
150
+
151
+ > p {
152
+ margin: 0;
153
+ color: var(--md-sys-color-on-surface-variant);
154
+ @include typescale("body-medium");
155
+ }
156
+
157
+ > :is(nav, form) {
158
+ display: flex;
159
+ justify-content: flex-end;
160
+ gap: 8px;
161
+ margin: 4px -8px -4px 0;
162
+ padding: 0;
163
+ background: none;
164
+ box-shadow: none;
165
+ }
166
+ }
@@ -1,7 +1,7 @@
1
- /*********************
2
- Transition Classes
3
- **********************/
1
+ @use "../abstracts" as *;
4
2
 
3
+ // Starting states for JS-driven animations: Sidenav staggers its list items in,
4
+ // and .fade-in is applied before an element is animated into view.
5
5
  ul.staggered-list li { opacity: 0; }
6
6
  .fade-in { opacity: 0; transform-origin: 0 50%; }
7
7
 
@@ -16,4 +16,4 @@ ul.staggered-list li { opacity: 0; }
16
16
  &.scale-in {
17
17
  transform: scale(1);
18
18
  }
19
- }
19
+ }