@stackific/md3 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 (116) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +17 -0
  3. package/README.md +316 -0
  4. package/THIRD-PARTY-NOTICES +40 -0
  5. package/dist/fonts/material-symbols-outlined.woff2 +0 -0
  6. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  7. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  8. package/dist/fonts/material-symbols-subset.woff2 +0 -0
  9. package/dist/md3.css +1 -0
  10. package/dist/md3.js +621 -0
  11. package/dist/shapes/arch.svg +1 -0
  12. package/dist/shapes/arrow.svg +1 -0
  13. package/dist/shapes/boom.svg +1 -0
  14. package/dist/shapes/bun.svg +1 -0
  15. package/dist/shapes/burst.svg +1 -0
  16. package/dist/shapes/circle.svg +1 -0
  17. package/dist/shapes/clamshell.svg +1 -0
  18. package/dist/shapes/diamond.svg +1 -0
  19. package/dist/shapes/fan.svg +1 -0
  20. package/dist/shapes/flower.svg +1 -0
  21. package/dist/shapes/gem.svg +1 -0
  22. package/dist/shapes/ghost-ish.svg +1 -0
  23. package/dist/shapes/heart.svg +1 -0
  24. package/dist/shapes/leaf-clover4.svg +1 -0
  25. package/dist/shapes/leaf-clover8.svg +1 -0
  26. package/dist/shapes/loading-indicator.svg +1 -0
  27. package/dist/shapes/oval.svg +1 -0
  28. package/dist/shapes/pentagon.svg +1 -0
  29. package/dist/shapes/pill.svg +1 -0
  30. package/dist/shapes/pixel-circle.svg +1 -0
  31. package/dist/shapes/pixel-triangle.svg +1 -0
  32. package/dist/shapes/puffy-diamond.svg +1 -0
  33. package/dist/shapes/puffy.svg +1 -0
  34. package/dist/shapes/semicircle.svg +1 -0
  35. package/dist/shapes/sided-cookie12.svg +1 -0
  36. package/dist/shapes/sided-cookie4.svg +1 -0
  37. package/dist/shapes/sided-cookie6.svg +1 -0
  38. package/dist/shapes/sided-cookie7.svg +1 -0
  39. package/dist/shapes/sided-cookie9.svg +1 -0
  40. package/dist/shapes/slanted.svg +1 -0
  41. package/dist/shapes/soft-boom.svg +1 -0
  42. package/dist/shapes/soft-burst.svg +1 -0
  43. package/dist/shapes/square.svg +1 -0
  44. package/dist/shapes/sunny.svg +1 -0
  45. package/dist/shapes/triangle.svg +1 -0
  46. package/dist/shapes/very-sunny.svg +1 -0
  47. package/dist/shapes/wavy-circle.svg +1 -0
  48. package/dist/shapes/wavy.svg +1 -0
  49. package/package.json +63 -0
  50. package/src/main.js +5 -0
  51. package/src/runtime/elements/dialogs.js +72 -0
  52. package/src/runtime/elements/fields.js +181 -0
  53. package/src/runtime/elements/menus.js +42 -0
  54. package/src/runtime/elements/pages.js +7 -0
  55. package/src/runtime/elements/progress.js +35 -0
  56. package/src/runtime/elements/sliders.js +78 -0
  57. package/src/runtime/elements/snackbars.js +27 -0
  58. package/src/runtime/helpers/ripples.js +46 -0
  59. package/src/runtime/md3.js +141 -0
  60. package/src/runtime/palette.js +64 -0
  61. package/src/runtime/settings/theme.js +194 -0
  62. package/src/runtime/utils.js +165 -0
  63. package/src/styles/_config.scss +142 -0
  64. package/src/styles/_mixins.scss +80 -0
  65. package/src/styles/elements/_badges.scss +65 -0
  66. package/src/styles/elements/_bars.scss +83 -0
  67. package/src/styles/elements/_buttons.scss +119 -0
  68. package/src/styles/elements/_cards.scss +32 -0
  69. package/src/styles/elements/_chips.scss +46 -0
  70. package/src/styles/elements/_dialogs.scss +143 -0
  71. package/src/styles/elements/_dividers.scss +46 -0
  72. package/src/styles/elements/_expansions.scss +19 -0
  73. package/src/styles/elements/_fields.scss +458 -0
  74. package/src/styles/elements/_grids.scss +35 -0
  75. package/src/styles/elements/_icons.scss +70 -0
  76. package/src/styles/elements/_layouts.scss +24 -0
  77. package/src/styles/elements/_lists.scss +76 -0
  78. package/src/styles/elements/_main-layouts.scss +45 -0
  79. package/src/styles/elements/_media.scss +104 -0
  80. package/src/styles/elements/_menus.scss +289 -0
  81. package/src/styles/elements/_navigations.scss +450 -0
  82. package/src/styles/elements/_overlays.scss +34 -0
  83. package/src/styles/elements/_pages.scss +28 -0
  84. package/src/styles/elements/_progress.scss +141 -0
  85. package/src/styles/elements/_selections.scss +248 -0
  86. package/src/styles/elements/_shapes.scss +151 -0
  87. package/src/styles/elements/_sliders.scss +336 -0
  88. package/src/styles/elements/_snackbars.scss +44 -0
  89. package/src/styles/elements/_tables.scss +67 -0
  90. package/src/styles/elements/_tabs.scss +49 -0
  91. package/src/styles/elements/_tooltips.scss +125 -0
  92. package/src/styles/helpers/_alignments.scss +29 -0
  93. package/src/styles/helpers/_blurs.scss +26 -0
  94. package/src/styles/helpers/_colors.scss +39 -0
  95. package/src/styles/helpers/_directions.scss +30 -0
  96. package/src/styles/helpers/_elevates.scss +20 -0
  97. package/src/styles/helpers/_forms.scss +76 -0
  98. package/src/styles/helpers/_margins.scss +39 -0
  99. package/src/styles/helpers/_opacities.scss +18 -0
  100. package/src/styles/helpers/_paddings.scss +35 -0
  101. package/src/styles/helpers/_positions.scss +44 -0
  102. package/src/styles/helpers/_responsive.scss +24 -0
  103. package/src/styles/helpers/_ripples.scss +40 -0
  104. package/src/styles/helpers/_scrolls.scss +7 -0
  105. package/src/styles/helpers/_shadows.scss +22 -0
  106. package/src/styles/helpers/_sizes.scss +34 -0
  107. package/src/styles/helpers/_spaces.scss +22 -0
  108. package/src/styles/helpers/_typography.scss +132 -0
  109. package/src/styles/helpers/_waves.scss +52 -0
  110. package/src/styles/helpers/_zoom.scss +18 -0
  111. package/src/styles/md3.scss +61 -0
  112. package/src/styles/settings/_fonts.scss +42 -0
  113. package/src/styles/settings/_globals.scss +104 -0
  114. package/src/styles/settings/_reset.scss +82 -0
  115. package/src/styles/settings/_theme.scss +126 -0
  116. package/src/styles/settings/_themes.scss +1525 -0
@@ -0,0 +1,70 @@
1
+ // Material-Symbols glyph base + size variants + filled variation axis.
2
+
3
+ i,
4
+ :is(.checkbox, .radio, .switch) > span::before,
5
+ :is(.checkbox, .radio, .switch) > span > i {
6
+ --_size: 1.5rem;
7
+ font-family: var(--font-icon);
8
+ font-weight: normal;
9
+ font-style: normal;
10
+ font-size: var(--_size);
11
+ letter-spacing: normal;
12
+ text-transform: none;
13
+ display: inline-flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ white-space: nowrap;
17
+ word-wrap: normal;
18
+ direction: ltr;
19
+ font-feature-settings: "liga";
20
+ -webkit-font-smoothing: antialiased;
21
+ vertical-align: middle;
22
+ text-align: center;
23
+ overflow: hidden;
24
+ inline-size: var(--_size);
25
+ min-inline-size: var(--_size);
26
+ block-size: var(--_size);
27
+ min-block-size: var(--_size);
28
+ box-sizing: content-box;
29
+ line-height: normal;
30
+ border-radius: 0;
31
+ }
32
+
33
+ i:has(.badge) { overflow: unset; }
34
+
35
+ $-icon-sizes: (
36
+ "tiny": 1rem,
37
+ "small": 1.25rem,
38
+ "medium": 1.5rem,
39
+ "large": 1.75rem,
40
+ "extra": 2rem,
41
+ );
42
+
43
+ @each $name, $value in $-icon-sizes {
44
+ i.#{$name} { --_size: #{$value}; }
45
+ }
46
+
47
+ .chip > i { --_size: 1.25rem; }
48
+
49
+ i.fill,
50
+ a.active > i,
51
+ button.active > i {
52
+ font-variation-settings: "FILL" 1;
53
+ }
54
+
55
+ i > :is(img, svg) {
56
+ inline-size: 100%;
57
+ block-size: 100%;
58
+ background-size: 100%;
59
+ border-radius: inherit;
60
+ position: absolute;
61
+ inset: 0 auto auto 0;
62
+ padding: inherit;
63
+ }
64
+
65
+ i[class*="fa-"] {
66
+ font-size: calc(var(--_size, 0) * 0.85);
67
+ line-height: normal;
68
+ block-size: auto;
69
+ min-block-size: auto;
70
+ }
@@ -0,0 +1,24 @@
1
+ // .absolute / .fixed positioning bundles with size variants.
2
+
3
+ .absolute { position: absolute; }
4
+ .fixed { position: fixed; }
5
+
6
+ :is(.absolute, .fixed).left.right {
7
+ inline-size: auto;
8
+ }
9
+
10
+ $-layout-sizes: (
11
+ "small": 20rem,
12
+ "medium": 28rem,
13
+ "large": 44rem,
14
+ );
15
+
16
+ @each $name, $value in $-layout-sizes {
17
+ :is(.absolute, .fixed).left.right.#{$name} {
18
+ block-size: $value;
19
+ }
20
+
21
+ :is(.absolute, .fixed).top.bottom.#{$name} {
22
+ inline-size: $value;
23
+ }
24
+ }
@@ -0,0 +1,76 @@
1
+ // .list — vertical row container with spacing tiers and optional borders.
2
+
3
+ .list {
4
+ display: flex;
5
+ flex-direction: column;
6
+ padding: 0;
7
+ margin: 0;
8
+ flex: 1;
9
+
10
+ > li,
11
+ > li > details > summary,
12
+ > li > a:only-child {
13
+ all: unset;
14
+ box-sizing: border-box;
15
+ position: relative;
16
+ display: flex;
17
+ align-items: center;
18
+ align-self: normal;
19
+ text-align: start;
20
+ justify-content: flex-start;
21
+ white-space: nowrap;
22
+ gap: 1rem;
23
+ min-block-size: 3.5rem;
24
+ padding: 0.5rem 1rem;
25
+ cursor: pointer;
26
+ flex: 1;
27
+ }
28
+
29
+ > li:has(ul, ol, details[open], a:only-child) {
30
+ padding: 0;
31
+ }
32
+
33
+ > li > .list {
34
+ padding: 0 0 0 1rem;
35
+ }
36
+
37
+ > li > *,
38
+ > li > a:only-child > * {
39
+ margin: 0;
40
+ }
41
+
42
+ > li > :is(details, .max),
43
+ > li > a:only-child > .max,
44
+ > li > details > summary > .max {
45
+ flex: 1;
46
+ }
47
+
48
+ &.border > li:not(:last-child)::before,
49
+ &.border > li > details[open] > summary::before {
50
+ content: "";
51
+ position: absolute;
52
+ background-color: var(--outline-variant);
53
+ inset: auto 0 0 0;
54
+ block-size: 0.0625rem;
55
+ inline-size: auto;
56
+ }
57
+
58
+ > li:focus-visible,
59
+ > li > a:only-child:focus-visible {
60
+ outline: 0.125rem solid var(--primary);
61
+ outline-offset: -0.25rem;
62
+ }
63
+ }
64
+
65
+ $-list-spacing: (
66
+ "no": 2.5rem,
67
+ "medium": 4.5rem,
68
+ "large": 5.5rem,
69
+ );
70
+
71
+ @each $name, $value in $-list-spacing {
72
+ .list.#{$name}-space > li,
73
+ .list.#{$name}-space > li > details > summary {
74
+ min-block-size: $value;
75
+ }
76
+ }
@@ -0,0 +1,45 @@
1
+ // Page-level grid that wires <header>, <main>, <footer>, and edge <nav> slots.
2
+
3
+ :has(> main) {
4
+ display: grid;
5
+ grid-template-columns: auto minmax(0, 1fr) auto;
6
+ grid-template-rows: auto auto minmax(0, 1fr) auto auto;
7
+ grid-template-areas:
8
+ "left top right"
9
+ "left header right"
10
+ "left main right"
11
+ "left footer right"
12
+ "left bottom right";
13
+ min-block-size: 100dvh;
14
+ box-sizing: border-box;
15
+ background-color: var(--surface);
16
+ }
17
+
18
+ $-grid-areas: (
19
+ "nav.left": left,
20
+ "nav.right": right,
21
+ "nav.top": top,
22
+ "nav.bottom": bottom,
23
+ "header": header,
24
+ "footer": footer,
25
+ );
26
+
27
+ @each $selector, $area in $-grid-areas {
28
+ #{$selector} {
29
+ grid-area: $area;
30
+ }
31
+ }
32
+
33
+ main {
34
+ --_padding: 0.5rem;
35
+ grid-area: main;
36
+ padding: var(--_padding);
37
+ overflow: clip;
38
+ }
39
+
40
+ aside {
41
+ z-index: 1;
42
+
43
+ &:not(.fixed, .absolute).right { float: right; }
44
+ &:not(.fixed, .absolute).left { float: left; }
45
+ }
@@ -0,0 +1,104 @@
1
+ // img/svg/video sizing for icons, avatars, hero images, and inline media.
2
+
3
+ svg {
4
+ fill: currentcolor;
5
+ }
6
+
7
+ :is(img, svg, video):is(.small, .medium, .large, .tiny, .extra, .round, .circle, .square, .responsive) {
8
+ --_size: 3rem;
9
+ object-fit: cover;
10
+ object-position: center;
11
+ transition:
12
+ transform var(--speed3),
13
+ border-radius var(--speed3),
14
+ padding var(--speed3);
15
+ block-size: var(--_size);
16
+ inline-size: var(--_size);
17
+ }
18
+
19
+ :is(img, svg, video).round {
20
+ --_round: 0.5rem;
21
+ }
22
+
23
+ $-media-sizes: (
24
+ "tiny": 2rem,
25
+ "small": 2.5rem,
26
+ "large": 3.5rem,
27
+ "extra": 4rem,
28
+ );
29
+
30
+ @each $name, $value in $-media-sizes {
31
+ :is(img, svg, video).#{$name} {
32
+ --_size: #{$value};
33
+ }
34
+ }
35
+
36
+ :is(img, svg, video).responsive {
37
+ --_size: 100%;
38
+ margin: 0 auto;
39
+ }
40
+
41
+ $-responsive-heights: (
42
+ "tiny": 4rem,
43
+ "small": 8rem,
44
+ "medium": 12rem,
45
+ "large": 16rem,
46
+ "extra": 20rem,
47
+ );
48
+
49
+ @each $name, $value in $-responsive-heights {
50
+ :is(img, svg, video).responsive.#{$name} {
51
+ inline-size: 100%;
52
+ block-size: $value;
53
+ }
54
+ }
55
+
56
+ :is(img, svg, video).responsive.round {
57
+ --_round: 2rem;
58
+ }
59
+
60
+ :is(img, svg, video).empty-state {
61
+ max-inline-size: 100%;
62
+ inline-size: 24rem;
63
+ }
64
+
65
+ :is(button, .button, .chip):not(.transparent) > .responsive {
66
+ border: 0.25rem solid transparent;
67
+ }
68
+
69
+ :is(button, .button, .chip, .field) > :is(img, svg):not(.responsive),
70
+ .tabs :is(img, svg):not(.responsive) {
71
+ min-inline-size: 1.5rem;
72
+ max-inline-size: 1.5rem;
73
+ min-block-size: 1.5rem;
74
+ max-block-size: 1.5rem;
75
+ }
76
+
77
+ :is(button, .button, .chip):not(.extend) > .responsive:first-child {
78
+ margin-inline-start: calc(-1 * var(--_padding, 0));
79
+ }
80
+
81
+ :is(button, .button, .chip):not(.extend) > .responsive:not(:first-child) {
82
+ margin-inline-end: calc(-1 * var(--_padding, 0));
83
+ }
84
+
85
+ :is(button, .button, .chip, .circle, .square, .extend) > .responsive {
86
+ --_size: inherit;
87
+ margin: 0 auto;
88
+ }
89
+
90
+ .extend > :is(.responsive, i) {
91
+ margin: 0;
92
+ position: absolute;
93
+ inset-inline: 1rem;
94
+ z-index: 1;
95
+ }
96
+
97
+ .extend > .responsive {
98
+ inset-inline: 0;
99
+ inline-size: 3.5rem;
100
+ }
101
+
102
+ .extend.border > .responsive {
103
+ inline-size: 3.375rem;
104
+ }
@@ -0,0 +1,289 @@
1
+ // <menu> — anchored popover. Spacing / position / submenu offset variants
2
+ // loop over a few small numeric scales.
3
+
4
+ menu {
5
+ opacity: 0;
6
+ visibility: hidden;
7
+ position: absolute;
8
+ box-shadow: var(--elevate2);
9
+ background-color: var(--surface-container);
10
+ z-index: 13;
11
+ inset: auto auto 0 0;
12
+ inline-size: 100%;
13
+ max-block-size: 50vh;
14
+ max-inline-size: none !important;
15
+ overflow-x: hidden;
16
+ overflow-y: auto;
17
+ font-size: 0.875rem;
18
+ font-weight: normal;
19
+ text-transform: none;
20
+ color: var(--on-surface);
21
+ line-height: normal;
22
+ text-align: start;
23
+ border-radius: 1rem;
24
+ transform: scale(0.8) translateY(120%);
25
+ transition: all var(--speed2) var(--speed2);
26
+ justify-content: flex-start;
27
+ padding: 0.25rem;
28
+ display: flex;
29
+ flex-direction: column;
30
+ gap: 0.125rem;
31
+
32
+ &.no-wrap {
33
+ inline-size: max-content !important;
34
+ white-space: nowrap !important;
35
+ }
36
+
37
+ * {
38
+ white-space: inherit !important;
39
+ }
40
+ }
41
+
42
+ $-menu-gaps: (
43
+ "no": 0,
44
+ "small": 0.25rem,
45
+ "medium": 0.375rem,
46
+ "large": 0.5rem,
47
+ "extra": 0.625rem,
48
+ );
49
+
50
+ @each $name, $value in $-menu-gaps {
51
+ menu.#{$name}-space {
52
+ gap: $value;
53
+ }
54
+ }
55
+
56
+ [dir="rtl"] menu {
57
+ inset: auto 0 0 auto;
58
+ }
59
+
60
+ menu.active,
61
+ :not([data-ui]):focus-within > menu,
62
+ menu > li:hover > menu,
63
+ menu > li > menu:hover {
64
+ opacity: 1;
65
+ visibility: visible;
66
+ transform: scale(1) translateY(100%);
67
+ transition: all var(--speed2), background-color 0s;
68
+ }
69
+
70
+ menu.top.active,
71
+ :not([data-ui]):focus-within > menu.top,
72
+ menu > li:hover > menu.top,
73
+ menu > li > menu.top:hover {
74
+ transform: scale(1) translateY(-100%);
75
+ }
76
+
77
+ menu:is(.min, .max).active,
78
+ :not([data-ui]):focus-within > menu:is(.min, .max) {
79
+ transform: scale(1);
80
+ }
81
+
82
+ menu {
83
+ > li,
84
+ > li > a:only-child {
85
+ all: unset;
86
+ box-sizing: border-box;
87
+ position: relative;
88
+ display: flex;
89
+ align-items: center;
90
+ align-self: normal;
91
+ text-align: start;
92
+ justify-content: inherit;
93
+ white-space: nowrap;
94
+ gap: 1rem;
95
+ padding: 0.5rem 1rem;
96
+ min-block-size: 2.75rem;
97
+ flex: 1;
98
+ margin: 0 !important;
99
+ cursor: pointer;
100
+ border-radius: 0.25rem;
101
+ transition: border-radius var(--speed2);
102
+ }
103
+
104
+ > li {
105
+ &:first-child {
106
+ border-top-left-radius: inherit;
107
+ border-top-right-radius: inherit;
108
+ }
109
+
110
+ &:last-child {
111
+ border-bottom-left-radius: inherit;
112
+ border-bottom-right-radius: inherit;
113
+ }
114
+
115
+ &:hover {
116
+ background-color: color-mix(in srgb, currentColor 10%, transparent);
117
+ }
118
+
119
+ &.active {
120
+ background-color: var(--tertiary-container);
121
+ color: var(--on-tertiary-container);
122
+ }
123
+
124
+ &:is(.active, :active) {
125
+ border-radius: 0.75rem;
126
+ }
127
+
128
+ > :is(.max, .field),
129
+ > a:only-child > .max {
130
+ flex: 1;
131
+ padding: 0;
132
+ margin: 0;
133
+ }
134
+ }
135
+
136
+ > li:has(.field, a:only-child) {
137
+ flex: 1;
138
+ padding: 0;
139
+ margin: 0;
140
+ }
141
+ }
142
+
143
+ menu.min {
144
+ inset: 0 0 auto 0;
145
+ transform: scale(0.8);
146
+ }
147
+
148
+ [dir="rtl"] menu.min.right,
149
+ menu.min.left,
150
+ menu.top.left {
151
+ inset: 0 0 auto auto;
152
+ }
153
+
154
+ [dir="rtl"] menu.min.left,
155
+ menu.min.right,
156
+ menu.top,
157
+ menu.top.right {
158
+ inset: 0 auto auto 0;
159
+ }
160
+
161
+ menu.max {
162
+ position: fixed;
163
+ inset: 0;
164
+ block-size: 100%;
165
+ max-block-size: none;
166
+ min-block-size: auto;
167
+ z-index: 100;
168
+ transform: scale(0.8);
169
+ border-radius: 0;
170
+
171
+ > li {
172
+ flex: none !important;
173
+ }
174
+ }
175
+
176
+ menu.no-wrap:is(.min, .max) {
177
+ min-inline-size: 16rem;
178
+ }
179
+
180
+ [dir="rtl"] menu.right,
181
+ [dir="rtl"] menu.top.min.right,
182
+ menu.left,
183
+ menu.top.min.left {
184
+ inset: auto 0 0 auto;
185
+ }
186
+
187
+ [dir="rtl"] menu.left,
188
+ [dir="rtl"] menu.top.min.left,
189
+ menu.right,
190
+ menu.top.min {
191
+ inset: auto auto 0 0;
192
+ }
193
+
194
+ menu.top {
195
+ transform: scale(0.8) translateY(-120%);
196
+ }
197
+
198
+ menu:has(menu) {
199
+ --_child: 1;
200
+ --_type: 0;
201
+ overflow: unset;
202
+ white-space: nowrap;
203
+ inline-size: auto;
204
+ min-inline-size: 12rem;
205
+ max-block-size: none;
206
+ }
207
+
208
+ menu > li > :is(menu, menu.right),
209
+ [dir="rtl"] menu > li > menu.left {
210
+ inset: auto auto calc(3rem * (var(--_child, 0) - var(--_type, 0))) 100%;
211
+ }
212
+
213
+ [dir="rtl"] menu > li > :is(menu, menu.right),
214
+ menu > li > menu.left {
215
+ inset: auto 100% calc(3rem * (var(--_child, 0) - var(--_type, 0))) auto;
216
+ }
217
+
218
+ menu > li > :is(menu.top, menu.top.right),
219
+ [dir="rtl"] menu > li > menu.top.left {
220
+ inset: calc(3rem * (var(--_child, 0) - var(--_type, 0))) auto auto 100%;
221
+ }
222
+
223
+ [dir="rtl"] menu > li > :is(menu.top, menu.top.right),
224
+ menu > li > menu.top.left {
225
+ inset: calc(3rem * (var(--_child, 0) - var(--_type, 0))) 100% auto auto;
226
+ }
227
+
228
+ menu.group {
229
+ padding: 0.5rem 0;
230
+ inline-size: 100%;
231
+ min-inline-size: auto;
232
+ max-block-size: none;
233
+ overflow: unset;
234
+ background: none;
235
+ box-shadow: none;
236
+
237
+ > li {
238
+ box-shadow: none;
239
+ padding: 0;
240
+ min-block-size: auto;
241
+
242
+ &:hover {
243
+ background: none;
244
+ }
245
+
246
+ > menu,
247
+ > menu:hover {
248
+ opacity: 1;
249
+ visibility: visible;
250
+ position: relative;
251
+ inset: 0;
252
+ max-block-size: none;
253
+ transform: none;
254
+ transition: none;
255
+ border-radius: 1rem 1rem 0.5rem 0.5rem;
256
+ z-index: auto;
257
+ flex: 1;
258
+ }
259
+
260
+ &:last-child > menu {
261
+ border-radius: 0.5rem 0.5rem 1rem 1rem;
262
+ }
263
+ }
264
+ }
265
+
266
+ // Submenu offset counters — emitted via @for to replace 22 hand-written rules.
267
+ @for $i from 2 through 11 {
268
+ menu > li:nth-last-child(#{$i}) {
269
+ --_child: #{$i};
270
+ }
271
+ }
272
+
273
+ @for $i from 2 through 11 {
274
+ menu > li:nth-last-of-type(#{$i}) {
275
+ --_type: #{$i - 1};
276
+ }
277
+ }
278
+
279
+ @media (pointer: coarse) {
280
+ :not(menu, [data-ui]):hover > menu {
281
+ opacity: 1;
282
+ visibility: visible;
283
+ transform: scale(1) translateY(100%);
284
+ }
285
+
286
+ :not(menu, [data-ui]):hover > menu.top {
287
+ transform: scale(1) translateY(-100%);
288
+ }
289
+ }