@expressivecss/expressive 0.1.0-alpha.3 → 0.2.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 (154) hide show
  1. package/LICENSE +82 -2
  2. package/README.md +153 -43
  3. package/dist/css/expressive.css +7121 -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 +7521 -0
  8. package/dist/js/expressive.cjs.map +7 -0
  9. package/dist/js/expressive.js +7383 -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 +7292 -7998
  14. package/dist/js/expressive.mjs.map +7 -1
  15. package/dist/types/behaviors/dialogs.d.ts +25 -0
  16. package/dist/{js → types}/components/autocomplete.d.ts +10 -1
  17. package/dist/{js → types}/components/buttons.d.ts +11 -1
  18. package/dist/{js → types}/components/cards.d.ts +10 -1
  19. package/dist/{js → types}/components/carousel.d.ts +4 -5
  20. package/dist/{js/forms/character-counter.d.ts → types/components/characterCounter.d.ts} +1 -1
  21. package/dist/{js → types}/components/chips.d.ts +1 -1
  22. package/dist/{js → types}/components/collapsible.d.ts +1 -1
  23. package/dist/{js → types}/components/datepicker.d.ts +63 -2
  24. package/dist/{js → types}/components/dropdown.d.ts +3 -3
  25. package/dist/types/components/index.d.ts +23 -0
  26. package/dist/{js/components/materialbox.d.ts → types/components/lightbox.d.ts} +21 -21
  27. package/dist/{js → types}/components/modal.d.ts +1 -1
  28. package/dist/{js → types}/components/parallax.d.ts +11 -5
  29. package/dist/{js → types}/components/pushpin.d.ts +1 -1
  30. package/dist/{js/forms → types/components}/range.d.ts +3 -3
  31. package/dist/types/components/registry.d.ts +107 -0
  32. package/dist/{js → types}/components/scrollspy.d.ts +6 -9
  33. package/dist/{js/forms → types/components}/select.d.ts +11 -2
  34. package/dist/{js → types}/components/sidenav.d.ts +1 -1
  35. package/dist/{js → types}/components/slider.d.ts +3 -2
  36. package/dist/{js → types}/components/tabs.d.ts +3 -2
  37. package/dist/{js/components/tap-target.d.ts → types/components/tapTarget.d.ts} +2 -2
  38. package/dist/{js → types}/components/timepicker.d.ts +13 -5
  39. package/dist/{js/components/toast.d.ts → types/components/toasts.d.ts} +28 -4
  40. package/dist/{js → types}/components/tooltip.d.ts +2 -2
  41. package/dist/types/core/bounding.d.ts +6 -0
  42. package/dist/{js/foundation → types/core}/component.d.ts +1 -1
  43. package/dist/types/core/edges.d.ts +6 -0
  44. package/dist/{js/foundation → types/core}/utils.d.ts +21 -14
  45. package/dist/types/index.d.ts +7 -0
  46. package/dist/{js/plugins/docked-display.d.ts → types/plugins/dockedDisplayPlugin.d.ts} +7 -0
  47. package/package.json +60 -36
  48. package/src/sass/README.md +200 -0
  49. package/src/sass/abstracts/_breakpoints.scss +69 -0
  50. package/src/sass/abstracts/_elevation.scss +34 -0
  51. package/src/sass/abstracts/_index.scss +7 -0
  52. package/src/sass/abstracts/_mixins.scss +171 -0
  53. package/src/sass/abstracts/_variables.scss +57 -0
  54. package/src/{scss/layout/_table.scss → sass/base/_global.scss} +64 -2
  55. package/src/{scss/layout → sass/base}/_grid.scss +6 -6
  56. package/src/sass/base/_index.scss +6 -0
  57. package/src/{scss/foundation → sass/base}/_normalize.scss +51 -139
  58. package/src/sass/base/_typography.scss +90 -0
  59. package/src/sass/components/_badges.scss +77 -0
  60. package/src/{scss → sass}/components/_breadcrumb.scss +2 -0
  61. package/src/sass/components/_buttons.scss +407 -0
  62. package/src/sass/components/_cards.scss +328 -0
  63. package/src/{scss → sass}/components/_carousel.scss +5 -3
  64. package/src/sass/components/_chips.scss +140 -0
  65. package/src/sass/components/_collapsible.scss +81 -0
  66. package/src/{scss → sass}/components/_collection.scss +2 -2
  67. package/src/{scss/components/_date-picker.scss → sass/components/_datepicker.scss} +51 -44
  68. package/src/sass/components/_docked-display.scss +11 -0
  69. package/src/sass/components/_dropdown.scss +129 -0
  70. package/src/{scss/components/_material-icons.scss → sass/components/_icons-material-design.scss} +2 -0
  71. package/src/sass/components/_index.scss +35 -0
  72. package/src/{scss/components/_material-box.scss → sass/components/_lightbox.scss} +6 -4
  73. package/src/sass/components/_modal.scss +208 -0
  74. package/src/sass/components/_navbar.scss +345 -0
  75. package/src/{scss/layout/_footer.scss → sass/components/_page-footer.scss} +7 -6
  76. package/src/{scss → sass}/components/_pagination.scss +4 -3
  77. package/src/{scss → sass}/components/_parallax.scss +4 -1
  78. package/src/{scss → sass}/components/_preloader.scss +19 -97
  79. package/src/{scss → sass}/components/_pulse.scss +2 -0
  80. package/src/sass/components/_pushpin.scss +11 -0
  81. package/src/{scss → sass}/components/_sidenav.scss +99 -82
  82. package/src/{scss → sass}/components/_slider.scss +3 -1
  83. package/src/{scss/components/_table-of-contents.scss → sass/components/_table_of_contents.scss} +2 -0
  84. package/src/sass/components/_tabs.scss +232 -0
  85. package/src/{scss/components/_tap-target.scss → sass/components/_tapTarget.scss} +24 -22
  86. package/src/{scss/components/_time-picker.scss → sass/components/_timepicker.scss} +56 -56
  87. package/src/sass/components/_toast.scss +260 -0
  88. package/src/sass/components/_toolbar.scss +192 -0
  89. package/src/sass/components/_tooltip.scss +166 -0
  90. package/src/{scss → sass}/components/_transitions.scss +4 -4
  91. package/src/sass/components/forms/_checkboxes.scss +288 -0
  92. package/src/sass/components/forms/_fieldset.scss +128 -0
  93. package/src/{scss → sass/components}/forms/_file-input.scss +11 -9
  94. package/src/{scss → sass/components}/forms/_index.scss +2 -0
  95. package/src/sass/components/forms/_input-fields.scss +326 -0
  96. package/src/sass/components/forms/_radio-buttons.scss +190 -0
  97. package/src/sass/components/forms/_range.scss +310 -0
  98. package/src/sass/components/forms/_select.scss +103 -0
  99. package/src/sass/components/forms/_switches.scss +239 -0
  100. package/src/sass/expressive.scss +60 -0
  101. package/src/sass/tokens/_index.scss +4 -0
  102. package/src/sass/tokens/_reference.scss +265 -0
  103. package/src/sass/tokens/_theme.scss +49 -0
  104. package/src/sass/utilities/_helpers.scss +63 -0
  105. package/src/sass/utilities/_index.scss +8 -0
  106. package/src/{scss → sass}/utilities/_spacing.scss +4 -3
  107. package/src/sass/utilities/_typescale.scss +45 -0
  108. package/src/sass/utilities/_visibility.scss +63 -0
  109. package/src/sass/utilities/_z-depth.scss +18 -0
  110. package/dist/js/components/index.d.ts +0 -21
  111. package/dist/js/forms/index.d.ts +0 -4
  112. package/dist/js/foundation/index.d.ts +0 -2
  113. package/dist/js/index.d.ts +0 -52
  114. package/dist/js/plugins/index.d.ts +0 -1
  115. package/src/scss/components/_appbar.scss +0 -454
  116. package/src/scss/components/_badges.scss +0 -77
  117. package/src/scss/components/_buttons.scss +0 -412
  118. package/src/scss/components/_cards.scss +0 -267
  119. package/src/scss/components/_chips.scss +0 -147
  120. package/src/scss/components/_collapsible.scss +0 -84
  121. package/src/scss/components/_dropdown.scss +0 -98
  122. package/src/scss/components/_index.scss +0 -28
  123. package/src/scss/components/_modal.scss +0 -84
  124. package/src/scss/components/_tabs.scss +0 -176
  125. package/src/scss/components/_toast.scss +0 -70
  126. package/src/scss/components/_tooltip.scss +0 -49
  127. package/src/scss/components/_video.scss +0 -15
  128. package/src/scss/expressive.scss +0 -7
  129. package/src/scss/forms/_checkboxes.scss +0 -199
  130. package/src/scss/forms/_input-fields.scss +0 -360
  131. package/src/scss/forms/_radio-buttons.scss +0 -114
  132. package/src/scss/forms/_range.scss +0 -148
  133. package/src/scss/forms/_select.scss +0 -108
  134. package/src/scss/forms/_switches.scss +0 -127
  135. package/src/scss/foundation/_base.scss +0 -71
  136. package/src/scss/foundation/_color-palette.scss +0 -402
  137. package/src/scss/foundation/_index.scss +0 -10
  138. package/src/scss/foundation/_mixins.scss +0 -198
  139. package/src/scss/foundation/_motion.scss +0 -70
  140. package/src/scss/foundation/_shape.scss +0 -30
  141. package/src/scss/foundation/_state-layers.scss +0 -68
  142. package/src/scss/foundation/_theme.scss +0 -238
  143. package/src/scss/foundation/_tokens.scss +0 -511
  144. package/src/scss/foundation/_variables.scss +0 -57
  145. package/src/scss/layout/_index.scss +0 -3
  146. package/src/scss/utilities/_a11y.scss +0 -77
  147. package/src/scss/utilities/_elevation.scss +0 -63
  148. package/src/scss/utilities/_helpers.scss +0 -50
  149. package/src/scss/utilities/_index.scss +0 -7
  150. package/src/scss/utilities/_responsive.scss +0 -62
  151. package/src/scss/utilities/_typography.scss +0 -115
  152. /package/dist/{js/forms → types/behaviors}/forms.d.ts +0 -0
  153. /package/dist/{js/components → types/behaviors}/waves.d.ts +0 -0
  154. /package/src/{scss → sass}/utilities/_colors.scss +0 -0
@@ -0,0 +1,208 @@
1
+ @use "../abstracts" as *;
2
+
3
+ // Dialogs.
4
+ //
5
+ // Anatomy is the HTML. A <dialog> is a basic dialog. A heading is the
6
+ // headline, a <p> (or a wrapping <div>) is supporting text, and the last
7
+ // child <form method="dialog"> or <nav> is the action row. .modal and
8
+ // .modal-header / .modal-content / .modal-footer stay as aliases.
9
+ //
10
+ // Tokens follow https://m3.material.io/components/dialogs/specs
11
+ // container surface, 28dp corners, 280–560dp, elevation 3
12
+ // headline headline-small / on-surface
13
+ // body body-medium / on-surface-variant
14
+ // icon 24dp, on-secondary
15
+ // actions end-aligned, 8dp gap
16
+ // scrim 32% + 12px blur
17
+ // padding 24dp
18
+
19
+ dialog,
20
+ .modal {
21
+ --md-comp-basic-dialog-container-color: var(--md-sys-color-surface);
22
+ --md-comp-basic-dialog-container-shape: 28px;
23
+ --md-comp-basic-dialog-container-min-width: 280px;
24
+ --md-comp-basic-dialog-container-max-width: 560px;
25
+ --md-comp-basic-dialog-sheet-width: 400px;
26
+ --md-comp-basic-dialog-scrim-blur: 12px;
27
+
28
+ box-sizing: border-box;
29
+ width: min(var(--md-comp-basic-dialog-container-max-width), calc(100% - 48px));
30
+ min-width: min(var(--md-comp-basic-dialog-container-min-width), calc(100% - 48px));
31
+ max-height: min(70vh, calc(100% - 48px));
32
+ margin: auto;
33
+ padding: 0;
34
+ border: none;
35
+ border-radius: var(--md-comp-basic-dialog-container-shape);
36
+ background-color: var(--md-comp-basic-dialog-container-color);
37
+ color: var(--md-sys-color-on-surface);
38
+ outline: none;
39
+ @include z-depth("3");
40
+
41
+ &::backdrop {
42
+ background-color: color-mix(in oklab, var(--md-sys-color-scrim) 32%, transparent);
43
+ backdrop-filter: blur(var(--md-comp-basic-dialog-scrim-blur));
44
+ }
45
+ }
46
+
47
+ // showModal() puts the dialog in the top layer but does not lock the
48
+ // document scroller. :modal is the modal-only match — a modeless
49
+ // dialog.show() must not freeze the page.
50
+ html:has(dialog:modal) {
51
+ overflow: hidden;
52
+ }
53
+
54
+ dialog[open],
55
+ .modal[open] {
56
+ display: flex;
57
+ flex-direction: column;
58
+ overflow: hidden;
59
+ overscroll-behavior: contain;
60
+ }
61
+
62
+ // Optional leading icon (M3 basic dialog).
63
+ dialog > i:first-child {
64
+ flex: 0 0 auto;
65
+ align-self: center;
66
+ margin: 24px 24px 0;
67
+ font-size: 24px;
68
+ width: 24px;
69
+ height: 24px;
70
+ line-height: 24px;
71
+ color: var(--md-sys-color-secondary);
72
+ }
73
+
74
+ dialog > :is(h1, h2, h3, h4, h5, h6),
75
+ .modal-header {
76
+ flex: 0 0 auto;
77
+ margin: 0;
78
+ padding: 24px 24px 16px;
79
+ font-family: var(--md-sys-typescale-headline-small-font-family-name);
80
+ font-size: var(--md-sys-typescale-headline-small-font-size);
81
+ font-weight: var(--md-sys-typescale-headline-small-font-weight);
82
+ line-height: var(--md-sys-typescale-headline-small-line-height);
83
+ letter-spacing: var(--md-sys-typescale-headline-small-letter-spacing);
84
+ color: var(--md-sys-color-on-surface);
85
+ }
86
+
87
+ dialog > i:first-child + :is(h1, h2, h3, h4, h5, h6) {
88
+ padding-top: 16px;
89
+ text-align: center;
90
+ }
91
+
92
+ dialog > p,
93
+ dialog > div,
94
+ .modal-content {
95
+ flex: 1 1 auto;
96
+ min-height: 0;
97
+ overflow: auto;
98
+ overscroll-behavior: contain;
99
+ margin: 0;
100
+ padding: 0 24px 16px;
101
+ font-family: var(--md-sys-typescale-body-medium-font-family-name);
102
+ font-size: var(--md-sys-typescale-body-medium-font-size);
103
+ font-weight: var(--md-sys-typescale-body-medium-font-weight);
104
+ line-height: var(--md-sys-typescale-body-medium-line-height);
105
+ letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing);
106
+ color: color-mix(in oklab, currentColor 72%, transparent);
107
+ }
108
+
109
+ dialog > :is(h1, h2, h3, h4, h5, h6) + p,
110
+ .modal-header + .modal-content {
111
+ padding-top: 0;
112
+ }
113
+
114
+ // Action row. form[method=dialog] is the native close mechanism.
115
+ dialog > :is(form, nav):last-child,
116
+ .modal-footer {
117
+ display: flex;
118
+ flex-wrap: wrap;
119
+ justify-content: flex-end;
120
+ align-items: center;
121
+ gap: 8px;
122
+ flex: 0 0 auto;
123
+ margin: 0;
124
+ padding: 8px 16px 16px;
125
+ border: 0;
126
+ background: none;
127
+ }
128
+
129
+ .modal-close {
130
+ cursor: pointer;
131
+ }
132
+
133
+ // Full-screen (M3). Takes the viewport; no corners.
134
+ // UA `dialog:modal` sets max-width: calc(100% - 2em - 6px). Without
135
+ // clearing it, width: 100% is capped and a strip of scrim shows on the
136
+ // right. Bottom sheet already overrides this.
137
+ dialog.max,
138
+ .modal.max {
139
+ width: 100%;
140
+ max-width: none;
141
+ height: 100%;
142
+ min-width: 0;
143
+ max-height: none;
144
+ margin: 0;
145
+ border-radius: 0;
146
+ }
147
+
148
+ // Sheets. Docked to one edge; the inner corners keep the dialog shape,
149
+ // the edge against the viewport is square. `left` / `right` also float
150
+ // via the helper utilities (`!important`), so sheets reset that.
151
+ dialog.bottom,
152
+ dialog.bottom-sheet,
153
+ .modal.bottom-sheet {
154
+ width: 100%;
155
+ min-width: 0;
156
+ max-width: none;
157
+ max-height: 50%;
158
+ margin: auto 0 0;
159
+ border-radius: var(--md-comp-basic-dialog-container-shape)
160
+ var(--md-comp-basic-dialog-container-shape) 0 0;
161
+ }
162
+
163
+ dialog.top,
164
+ dialog.top-sheet,
165
+ .modal.top-sheet {
166
+ width: 100%;
167
+ min-width: 0;
168
+ max-width: none;
169
+ max-height: 50%;
170
+ margin: 0 0 auto;
171
+ border-radius: 0 0 var(--md-comp-basic-dialog-container-shape)
172
+ var(--md-comp-basic-dialog-container-shape);
173
+ }
174
+
175
+ dialog.left,
176
+ dialog.left-sheet,
177
+ .modal.left-sheet,
178
+ dialog.right,
179
+ dialog.right-sheet,
180
+ .modal.right-sheet {
181
+ float: none !important;
182
+ width: min(var(--md-comp-basic-dialog-sheet-width), 85%);
183
+ max-width: none;
184
+ height: auto;
185
+ max-height: none;
186
+ min-width: 0;
187
+ min-height: 0;
188
+ margin: 0;
189
+ inset-block: 0;
190
+ }
191
+
192
+ dialog.left,
193
+ dialog.left-sheet,
194
+ .modal.left-sheet {
195
+ inset-inline-start: 0;
196
+ inset-inline-end: auto;
197
+ border-radius: 0 var(--md-comp-basic-dialog-container-shape)
198
+ var(--md-comp-basic-dialog-container-shape) 0;
199
+ }
200
+
201
+ dialog.right,
202
+ dialog.right-sheet,
203
+ .modal.right-sheet {
204
+ inset-inline-start: auto;
205
+ inset-inline-end: 0;
206
+ border-radius: var(--md-comp-basic-dialog-container-shape) 0 0
207
+ var(--md-comp-basic-dialog-container-shape);
208
+ }
@@ -0,0 +1,345 @@
1
+ @use "../abstracts" as *;
2
+
3
+ // Top and bottom app bars.
4
+ //
5
+ // Anatomy is the HTML. A header whose child is a nav is a top app bar; a
6
+ // footer whose child is a nav (and that is not .page-footer) is a bottom app
7
+ // bar. Headings are the headline, icon-only links/buttons are the leading and
8
+ // trailing actions, <menu> / <ul> hold text destinations. Helpers are only
9
+ // for variants the markup cannot express: .center, .medium, .large, .fixed.
10
+ //
11
+ // Tokens follow the M3 top-app-bar / bottom-app-bar specs
12
+ // (https://m3.material.io/components/app-bars/specs):
13
+ // container surface, 64dp small / 112 medium / 152 large / 80 bottom
14
+ // headline on-surface, title-large (small), headline-small/medium
15
+ // icons on-surface-variant, 24dp in a 48dp target, 4dp inset
16
+ // elevation 0 at rest; level 2 once a .fixed bar has scrolled
17
+
18
+ header:has(> nav) {
19
+ --md-comp-top-app-bar-container-color: var(--md-sys-color-surface);
20
+ --md-comp-top-app-bar-headline-color: var(--md-sys-color-on-surface);
21
+ // Inherit so a fill + on-* pair on the header recolors the icons.
22
+ // Set this to --md-sys-color-on-surface-variant for the spec mute.
23
+ --md-comp-top-app-bar-leading-icon-color: inherit;
24
+ --md-comp-top-app-bar-trailing-icon-color: inherit;
25
+ --md-comp-top-app-bar-container-height: 64px;
26
+ --md-comp-top-app-bar-leading-icon-size: 24px;
27
+ --md-comp-top-app-bar-container-shape: 0;
28
+
29
+ background-color: var(--md-comp-top-app-bar-container-color);
30
+ color: var(--md-comp-top-app-bar-headline-color);
31
+ border-radius: var(--md-comp-top-app-bar-container-shape);
32
+ width: 100%;
33
+
34
+ > nav:not(.tabs) {
35
+ display: flex;
36
+ align-items: center;
37
+ box-sizing: border-box;
38
+ width: 100%;
39
+ min-height: var(--md-comp-top-app-bar-container-height);
40
+ padding-inline: 4px;
41
+ margin: 0;
42
+ }
43
+
44
+ > nav:not(.tabs) > :is(h1, h2, h3, h4, h5, h6) {
45
+ flex: 1 1 auto;
46
+ min-width: 0;
47
+ margin: 0;
48
+ padding-inline: 4px 12px;
49
+
50
+ // 16dp from the container edge when there is no leading icon.
51
+ &:first-child {
52
+ padding-inline-start: 12px;
53
+ }
54
+ overflow: hidden;
55
+ text-overflow: ellipsis;
56
+ white-space: nowrap;
57
+ color: inherit;
58
+ font-family: var(--md-sys-typescale-title-large-font-family-name);
59
+ font-size: var(--md-sys-typescale-title-large-font-size);
60
+ font-weight: var(--md-sys-typescale-title-large-font-weight);
61
+ line-height: var(--md-sys-typescale-title-large-line-height);
62
+ letter-spacing: var(--md-sys-typescale-title-large-letter-spacing);
63
+ }
64
+
65
+ // Icon-only actions — 48dp target, 24dp glyph, 4dp from the container edge.
66
+ > nav:not(.tabs) > :is(a, button):not(.btn):not(.button):not(.btn-floating):not(.btn-large):not(.btn-small):has(> i:only-child) {
67
+ display: inline-flex;
68
+ flex: 0 0 auto;
69
+ align-items: center;
70
+ justify-content: center;
71
+ width: 48px;
72
+ height: 48px;
73
+ padding: 0;
74
+ margin: 0;
75
+ border: 0;
76
+ border-radius: 50%;
77
+ background: transparent;
78
+ color: var(--md-comp-top-app-bar-leading-icon-color);
79
+ cursor: pointer;
80
+ appearance: none;
81
+ font: inherit;
82
+ text-decoration: none;
83
+ @include focus-visible;
84
+
85
+ > i {
86
+ display: block;
87
+ font-size: var(--md-comp-top-app-bar-leading-icon-size);
88
+ width: var(--md-comp-top-app-bar-leading-icon-size);
89
+ height: var(--md-comp-top-app-bar-leading-icon-size);
90
+ line-height: var(--md-comp-top-app-bar-leading-icon-size);
91
+ }
92
+
93
+ &:hover {
94
+ background-color: color-mix(in oklab, currentColor 8%, transparent);
95
+ }
96
+
97
+ &:active {
98
+ background-color: color-mix(in oklab, currentColor 10%, transparent);
99
+ }
100
+ }
101
+
102
+ // Text destinations, either loose or grouped in a menu/list.
103
+ > nav:not(.tabs) > a:not(:has(> i:only-child)):not(.btn):not(.button):not(.btn-floating):not(.breadcrumb) {
104
+ @extend %app-bar-destination;
105
+ }
106
+
107
+ > nav:not(.tabs) > :is(menu, ul) {
108
+ display: flex;
109
+ align-items: stretch;
110
+ align-self: stretch;
111
+ list-style: none;
112
+ margin: 0;
113
+ padding: 0;
114
+
115
+ > li {
116
+ display: flex;
117
+ align-items: stretch;
118
+ }
119
+
120
+ a {
121
+ @extend %app-bar-destination;
122
+ }
123
+ }
124
+
125
+ > nav:not(.tabs) > form {
126
+ display: flex;
127
+ flex: 1 1 auto;
128
+ align-items: center;
129
+ align-self: stretch;
130
+ min-width: 0;
131
+ margin: 0;
132
+
133
+ input {
134
+ flex: 1 1 auto;
135
+ min-width: 0;
136
+ height: 100%;
137
+ margin: 0;
138
+ padding: 0 16px;
139
+ border: 0;
140
+ background: transparent;
141
+ box-shadow: none;
142
+ color: inherit;
143
+ font-family: var(--md-sys-typescale-body-large-font-family-name);
144
+ font-size: var(--md-sys-typescale-body-large-font-size);
145
+ font-weight: var(--md-sys-typescale-body-large-font-weight);
146
+ line-height: var(--md-sys-typescale-body-large-line-height);
147
+
148
+ &:focus,
149
+ &:focus-visible {
150
+ outline: none;
151
+ border: 0;
152
+ box-shadow: none;
153
+ }
154
+ }
155
+ }
156
+
157
+ // Secondary row (tabs sit under the bar, not inside it).
158
+ > .tabs {
159
+ background-color: transparent;
160
+ width: 100%;
161
+ }
162
+
163
+ @include bp-up("large") {
164
+ // Beats the icon-button display:inline-flex (higher specificity).
165
+ // Same flag the visibility utilities use for breakpoint hides.
166
+ > nav:not(.tabs) > .sidenav-trigger {
167
+ display: none !important;
168
+ }
169
+
170
+ // The trigger is still :first-child, so the title needs the no-icon inset.
171
+ > nav:not(.tabs) > .sidenav-trigger + :is(h1, h2, h3, h4, h5, h6) {
172
+ padding-inline-start: 12px;
173
+ }
174
+ }
175
+ }
176
+
177
+ %app-bar-destination {
178
+ display: inline-flex;
179
+ align-items: center;
180
+ padding: 0 12px;
181
+ color: inherit;
182
+ text-decoration: none;
183
+ font-family: var(--md-sys-typescale-label-large-font-family-name);
184
+ font-size: var(--md-sys-typescale-label-large-font-size);
185
+ font-weight: var(--md-sys-typescale-label-large-font-weight);
186
+ line-height: var(--md-sys-typescale-label-large-line-height);
187
+ letter-spacing: var(--md-sys-typescale-label-large-letter-spacing);
188
+ @include focus-visible;
189
+
190
+ &:hover:not(.active) {
191
+ background-color: color-mix(in oklab, currentColor 8%, transparent);
192
+ }
193
+
194
+ &.active {
195
+ background-color: color-mix(in oklab, currentColor 10%, transparent);
196
+ }
197
+ }
198
+
199
+ // Center-aligned small bar. The headline is taken out of flow so leading and
200
+ // trailing actions can sit on the edges without shifting the title.
201
+ header.center:has(> nav) > nav:not(.tabs) {
202
+ position: relative;
203
+ justify-content: space-between;
204
+
205
+ > :is(h1, h2, h3, h4, h5, h6) {
206
+ position: absolute;
207
+ left: 50%;
208
+ transform: translateX(-50%);
209
+ flex: 0 1 auto;
210
+ max-width: calc(100% - 96px);
211
+ padding-inline: 16px;
212
+ text-align: center;
213
+ pointer-events: none;
214
+ }
215
+ }
216
+
217
+ // Medium (112dp) and large (152dp): same markup, title wraps to a second row.
218
+ header.medium:has(> nav) > nav:not(.tabs),
219
+ header.large:has(> nav) > nav:not(.tabs) {
220
+ flex-wrap: wrap;
221
+ align-content: flex-start;
222
+ height: auto;
223
+
224
+ > :is(h1, h2, h3, h4, h5, h6) {
225
+ order: 1;
226
+ flex: 1 0 100%;
227
+ white-space: normal;
228
+ overflow: visible;
229
+ text-overflow: unset;
230
+ }
231
+ }
232
+
233
+ header.medium:has(> nav) > nav:not(.tabs) {
234
+ min-height: 112px;
235
+ padding-bottom: 16px;
236
+
237
+ > :is(h1, h2, h3, h4, h5, h6) {
238
+ padding: 4px 12px 0 16px;
239
+ font-family: var(--md-sys-typescale-headline-small-font-family-name);
240
+ font-size: var(--md-sys-typescale-headline-small-font-size);
241
+ font-weight: var(--md-sys-typescale-headline-small-font-weight);
242
+ line-height: var(--md-sys-typescale-headline-small-line-height);
243
+ letter-spacing: var(--md-sys-typescale-headline-small-letter-spacing);
244
+ }
245
+ }
246
+
247
+ header.large:has(> nav) > nav:not(.tabs) {
248
+ min-height: 152px;
249
+ padding-bottom: 28px;
250
+
251
+ > :is(h1, h2, h3, h4, h5, h6) {
252
+ padding: 12px 12px 0 16px;
253
+ font-family: var(--md-sys-typescale-headline-medium-font-family-name);
254
+ font-size: var(--md-sys-typescale-headline-medium-font-size);
255
+ font-weight: var(--md-sys-typescale-headline-medium-font-weight);
256
+ line-height: var(--md-sys-typescale-headline-medium-line-height);
257
+ letter-spacing: var(--md-sys-typescale-headline-medium-letter-spacing);
258
+ }
259
+ }
260
+
261
+ // Pin the bar. Scroll-driven elevation is progressive enhancement: without
262
+ // animation-timeline the bar stays at rest (level 0), which is the spec default.
263
+ header.fixed:has(> nav) {
264
+ position: sticky;
265
+ top: 0;
266
+ z-index: 997;
267
+ animation: top-app-bar-scroll linear both;
268
+ animation-timeline: scroll(root);
269
+ animation-range: 0 8px;
270
+ }
271
+
272
+ @keyframes top-app-bar-scroll {
273
+ to {
274
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14),
275
+ 0 1px 10px 0 rgba(0, 0, 0, 0.12),
276
+ 0 2px 4px -1px rgba(0, 0, 0, 0.3);
277
+ }
278
+ }
279
+
280
+ // Bottom app bar. 80dp row, icons on the start, a FAB (any .btn) pushed to the end.
281
+ footer:not(.page-footer):has(> nav) {
282
+ --md-comp-bottom-app-bar-container-color: var(--md-sys-color-surface);
283
+ --md-comp-bottom-app-bar-container-height: 80px;
284
+
285
+ background-color: var(--md-comp-bottom-app-bar-container-color);
286
+ color: var(--md-sys-color-on-surface);
287
+ width: 100%;
288
+ @include z-depth("2");
289
+
290
+ > nav:not(.tabs) {
291
+ display: flex;
292
+ align-items: center;
293
+ box-sizing: border-box;
294
+ width: 100%;
295
+ min-height: var(--md-comp-bottom-app-bar-container-height);
296
+ padding: 12px 4px;
297
+ margin: 0;
298
+ }
299
+
300
+ > nav:not(.tabs) > :is(a, button):not(.btn):not(.button):not(.btn-floating):not(.btn-large):not(.btn-small):has(> i:only-child) {
301
+ display: inline-flex;
302
+ flex: 0 0 auto;
303
+ align-items: center;
304
+ justify-content: center;
305
+ width: 48px;
306
+ height: 48px;
307
+ padding: 0;
308
+ margin: 0;
309
+ border: 0;
310
+ border-radius: 50%;
311
+ background: transparent;
312
+ color: var(--md-sys-color-on-surface-variant);
313
+ cursor: pointer;
314
+ appearance: none;
315
+ font: inherit;
316
+ text-decoration: none;
317
+ @include focus-visible;
318
+
319
+ > i {
320
+ display: block;
321
+ font-size: 24px;
322
+ width: 24px;
323
+ height: 24px;
324
+ line-height: 24px;
325
+ }
326
+
327
+ &:hover {
328
+ background-color: color-mix(in oklab, currentColor 8%, transparent);
329
+ }
330
+
331
+ &:active {
332
+ background-color: color-mix(in oklab, currentColor 10%, transparent);
333
+ }
334
+ }
335
+
336
+ > nav:not(.tabs) > :is(.btn, .btn-floating, .btn-large) {
337
+ margin-inline-start: auto;
338
+ }
339
+
340
+ &.fixed {
341
+ position: sticky;
342
+ bottom: 0;
343
+ z-index: 997;
344
+ }
345
+ }
@@ -1,10 +1,11 @@
1
- // Footer
1
+ @use "../abstracts" as *;
2
+
2
3
  .page-footer {
3
4
  margin-top: 5rem;
4
5
  padding-top: 3rem;
5
6
  border-top: 1px dashed var(--md-sys-color-outline-variant);
6
7
  p {
7
- color: var(--md-sys-color-outline-light);
8
+ color: var(--md-sys-color-outline);
8
9
  }
9
10
  a {
10
11
  color: var(--md-sys-color-primary);
@@ -18,9 +19,9 @@
18
19
  justify-content: space-between;
19
20
  padding: 10px 0px;
20
21
  }
22
+ }
21
23
 
22
- ul {
23
- padding-left: 0;
24
- list-style-type: none;
25
- }
24
+ .page-footer ul {
25
+ padding-left: 0;
26
+ list-style-type: none;
26
27
  }
@@ -1,5 +1,4 @@
1
- @use '../foundation/variables' as *;
2
- @use '../foundation/mixins' as *;
1
+ @use "../abstracts" as *;
3
2
 
4
3
  .pagination {
5
4
  li {
@@ -27,8 +26,10 @@
27
26
  display: inline-block;
28
27
  float: none;
29
28
  }
29
+ }
30
30
 
31
- @media #{$medium-and-down} {
31
+ @include bp-down("large") {
32
+ .pagination {
32
33
  width: 100%;
33
34
 
34
35
  li.prev,
@@ -1,4 +1,7 @@
1
- // Parallax
1
+ @use "../abstracts" as *;
2
+
3
+ // Paired with components/parallax.ts, which positions the image on scroll.
4
+
2
5
  .parallax-container {
3
6
  position: relative;
4
7
  overflow: hidden;