@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,142 @@
1
+ // Shared Sass variables, maps, and mixins consumed across the framework.
2
+ // Token values that vary by theme stay as CSS custom properties (see settings/_themes.scss).
3
+ // Static structural tokens live here as Sass vars for compile-time loops.
4
+
5
+ @use "sass:map";
6
+ @use "sass:list";
7
+
8
+ // ────────────────────────────── spacing scale ──────────────────────────────
9
+ $spaces: (
10
+ "tiny": 0.25rem,
11
+ "small": 0.5rem,
12
+ "": 1rem,
13
+ "large": 1.5rem,
14
+ );
15
+
16
+ $space-blocks: (
17
+ "tiny": 0.5rem,
18
+ "": 1rem,
19
+ "small": 1rem,
20
+ "medium": 2rem,
21
+ "large": 3rem,
22
+ "extra": 4rem,
23
+ );
24
+
25
+ // ────────────────────────────── breakpoints ─────────────────────────────────
26
+ $breakpoints: (
27
+ "s": 600px,
28
+ "m": 993px,
29
+ "l": 1240px,
30
+ );
31
+
32
+ // ─────────────────────────── material palette (legacy) ──────────────────────
33
+ // Reused by helpers/_colors.scss. Each entry: name → (base, 1..10 shades).
34
+ $material-palette: (
35
+ "red": (#F44336, #FFEBEE, #FFCDD2, #EF9A9A, #E57373, #EF5350, #F44336, #E53935, #D32F2F, #C62828, #B71C1C),
36
+ "pink": (#E91E63, #FCE4EC, #F8BBD0, #F48FB1, #F06292, #EC407A, #E91E63, #D81B60, #C2185B, #AD1457, #880E4F),
37
+ "purple": (#9C27B0, #F3E5F5, #E1BEE7, #CE93D8, #BA68C8, #AB47BC, #9C27B0, #8E24AA, #7B1FA2, #6A1B9A, #4A148C),
38
+ "deep-purple": (#673AB7, #EDE7F6, #D1C4E9, #B39DDB, #9575CD, #7E57C2, #673AB7, #5E35B1, #512DA8, #4527A0, #311B92),
39
+ "blue": (#2196F3, #E3F2FD, #BBDEFB, #90CAF9, #64B5F6, #42A5F5, #2196F3, #1E88E5, #1976D2, #1565C0, #0D47A1),
40
+ "light-blue": (#03A9F4, #E1F5FE, #B3E5FC, #81D4FA, #4FC3F7, #29B6F6, #03A9F4, #039BE5, #0288D1, #0277BD, #01579B),
41
+ "cyan": (#00BCD4, #E0F7FA, #B2EBF2, #80DEEA, #4DD0E1, #26C6DA, #00BCD4, #00ACC1, #0097A7, #00838F, #006064),
42
+ "green": (#4CAF50, #E8F5E9, #C8E6C9, #A5D6A7, #81C784, #66BB6A, #4CAF50, #43A047, #388E3C, #2E7D32, #1B5E20),
43
+ "light-green": (#8BC34A, #F1F8E9, #DCEDC8, #C5E1A5, #AED581, #9CCC65, #8BC34A, #7CB342, #689F38, #558B2F, #33691E),
44
+ "lime": (#CDDC39, #F9FBE7, #F0F4C3, #E6EE9C, #DCE775, #D4E157, #CDDC39, #C0CA33, #AFB42B, #9E9D24, #827717),
45
+ "yellow": (#FFEB3B, #FFFDE7, #FFF9C4, #FFF59D, #FFF176, #FFEE58, #FFEB3B, #FDD835, #FBC02D, #F9A825, #F57F17),
46
+ "amber": (#FFC107, #FFF8E1, #FFECB3, #FFE082, #FFD54F, #FFCA28, #FFC107, #FFB300, #FFA000, #FF8F00, #FF6F00),
47
+ "orange": (#FF9800, #FFF3E0, #FFE0B2, #FFCC80, #FFB74D, #FFA726, #FF9800, #FB8C00, #F57C00, #EF6C00, #E65100),
48
+ "deep-orange": (#FF5722, #FBE9E7, #FFCCBC, #FFAB91, #FF8A65, #FF7043, #FF5722, #F4511E, #E64A19, #D84315, #BF360C),
49
+ "brown": (#795548, #EFEBE9, #D7CCC8, #BCAAA4, #A1887F, #8D6E63, #795548, #6D4C41, #5D4037, #4E342E, #3E2723),
50
+ "blue-grey": (#607D8B, #ECEFF1, #CFD8DC, #B0BEC5, #90A4AE, #78909C, #607D8B, #546E7A, #455A64, #37474F, #263238),
51
+ "stackific": (#1447e6, #e8edfd, #c7d3fa, #98aff6, #698af2, #3a66ee, #1448eb, #113dc5, #0d2e96, #092067, #051138),
52
+ "hello-pumpkin": (#ff8f00, #fff4e5, #ffe4c2, #ffce8f, #ffb75c, #ffa129, #ff8f00, #d67800, #a35c00, #703f00, #3d2200),
53
+ "sea-lettuce": (#63a002, #f5ffe6, #e7fec3, #d3fe90, #c0fd5e, #acfc2b, #9cfc03, #83d403, #64a102, #456f01, #253c01),
54
+ "olive": (#7c7c67, #f7f7ed, #ededd4, #ddddb0, #cece8d, #bfbf69, #b2b34d, #969640, #727231, #4f4f22, #2b2b12),
55
+ "nord": (#5e81ac, #edf2f7, #d4dfed, #b0c5dd, #8daace, #6990bf, #4d7ab3, #406796, #314e72, #22364f, #121d2b),
56
+ "vega-violet": (#ad46ff, #f4e5ff, #e4c2ff, #cd8fff, #b75cff, #a029ff, #8e00ff, #7700d6, #5b00a3, #3e0070, #22003d),
57
+ "wild-strawberry": (#f6339a, #fee7f3, #fcc4e2, #fa94ca, #f863b2, #f63299, #f40b86, #cd0971, #9c0756, #6b053b, #3b0320),
58
+ "heliotrope-magenta": (#e12afb, #fbe6ff, #f7c3fe, #ef91fd, #e85ffc, #e12dfb, #dc05fa, #b904d2, #8d03a0, #61026e, #35013c),
59
+ "voodoo-violet": (#804792, #f5edf7, #e7d4ed, #d3b0dd, #be8dce, #aa69bf, #9a4db3, #814096, #633172, #44224f, #25122b),
60
+ "red-orchid": (#c0001c, #ffe5e9, #ffc2cb, #ff8f9f, #ff5c74, #ff2948, #ff0025, #d6001f, #a30018, #700010, #3d0009),
61
+ "green-brown": (#6e5d00, #fffbe5, #fff6c2, #ffee8f, #ffe65c, #ffde29, #ffd800, #d6b500, #a38a00, #705f00, #3d3400),
62
+ "shakshuka": (#ab350f, #fdede8, #fad3c7, #f6af98, #f28a69, #ee663a, #ea4915, #c53d11, #962f0d, #672009, #381105),
63
+ "purple-honeycreeper": (#8e51ff, #eee5ff, #d7c2ff, #b68fff, #955cff, #7429ff, #5900ff, #4b00d6, #3900a3, #270070, #15003d),
64
+ "maldives": (#00b8db, #e5fbff, #c2f5ff, #8fedff, #5ce5ff, #29ddff, #00d6ff, #00b4d6, #0089a3, #005e70, #00333d),
65
+ "verditer": (#00bba7, #e5fffc, #c2fff8, #8ffff3, #5cffee, #29ffe8, #00ffe4, #00d6bf, #00a392, #007064, #003d37),
66
+ "fennel": (#00bc7d, #e5fff6, #c2ffea, #8fffd9, #5cffc8, #29ffb7, #00ffaa, #00d68e, #00a36d, #00704b, #003d29),
67
+ "gold": (#efb100, #fff8e5, #ffefc2, #ffe28f, #ffd55c, #ffc729, #ffbd00, #d69f00, #a37900, #705300, #3d2d00),
68
+ "vitamin-c": (#fd9a00, #fff5e5, #ffe7c2, #ffd38f, #ffbf5c, #ffab29, #ff9b00, #d68200, #a36300, #704400, #3d2500),
69
+ "burtuqali": (#ff6900, #fff0e5, #ffdbc2, #ffbd8f, #ff9f5c, #ff8129, #ff6900, #d65800, #a34300, #702e00, #3d1900),
70
+ );
71
+
72
+ // ───────────────────────── M3 semantic color roles ──────────────────────────
73
+ // Roles whose `.foo` utility paints both bg + on-foreground text.
74
+ $theme-roles-paired: (
75
+ "primary",
76
+ "secondary",
77
+ "tertiary",
78
+ "error",
79
+ "background",
80
+ );
81
+
82
+ // Subset of paired roles that also get -text and -border utilities.
83
+ // Upstream skips `.background-text` / `.background-border` — keep parity.
84
+ $theme-roles-with-edges: (
85
+ "primary",
86
+ "secondary",
87
+ "tertiary",
88
+ "error",
89
+ );
90
+
91
+ // Container variants (paint container bg + on-container text).
92
+ $theme-roles-container: (
93
+ "primary",
94
+ "secondary",
95
+ "tertiary",
96
+ "error",
97
+ );
98
+
99
+ // Roles whose nav/menu active-state recoloring is emitted. Upstream stops
100
+ // at tertiary (error is excluded), so we mirror that to avoid extra rules.
101
+ $theme-roles-nav-active: (
102
+ "primary",
103
+ "secondary",
104
+ "tertiary",
105
+ );
106
+
107
+ // Surface tonal stops (background only; on-surface inherited).
108
+ $surface-stops: (
109
+ "surface-dim",
110
+ "surface-bright",
111
+ "surface-container-lowest",
112
+ "surface-container-low",
113
+ "surface-container",
114
+ "surface-container-high",
115
+ "surface-container-highest",
116
+ );
117
+
118
+ // ───────────────────────────── mixins ────────────────────────────────────────
119
+ @mixin paired-color($role) {
120
+ background-color: var(--#{$role}) !important;
121
+ color: var(--on-#{$role}) !important;
122
+ }
123
+
124
+ @mixin text-color($role) {
125
+ color: var(--#{$role}) !important;
126
+ }
127
+
128
+ @mixin border-color($role) {
129
+ border-color: var(--#{$role}) !important;
130
+ }
131
+
132
+ @mixin breakpoint-up($name) {
133
+ @media (min-width: #{map.get($breakpoints, $name)}) {
134
+ @content;
135
+ }
136
+ }
137
+
138
+ @mixin breakpoint-down($name) {
139
+ @media (max-width: #{map.get($breakpoints, $name) - 1px}) {
140
+ @content;
141
+ }
142
+ }
@@ -0,0 +1,80 @@
1
+ // Reusable SCSS mixins extracted from the framework's helper rules. Vanilla's
2
+ // own elements still get these effects via the global helper selectors
3
+ // (waves, ripples, focus rings); this file exists for component libraries
4
+ // (@stackific/md3-svelte, @stackific/md3-webcomp) that scope styles per
5
+ // component and can't rely on document-wide selectors.
6
+
7
+ // Material radial-gradient wave on hover / focus, retracting on press.
8
+ // Apply inside a positioned host. Vanilla's equivalent is the giant
9
+ // :is(.wave, .chip, .button, button, ...)::after rule in helpers/_waves.scss.
10
+ @mixin wave-overlay() {
11
+ &::after {
12
+ content: "";
13
+ position: absolute;
14
+ inset: 0;
15
+ z-index: 1;
16
+ border-radius: inherit;
17
+ inline-size: 100%;
18
+ block-size: 100%;
19
+ background-position: center;
20
+ background-image: radial-gradient(circle, currentColor 1%, transparent 1%);
21
+ opacity: 0;
22
+ transition: none;
23
+ pointer-events: none;
24
+ }
25
+
26
+ &:is(:focus-visible, :hover)::after {
27
+ background-size: 22500%;
28
+ opacity: 0.1;
29
+ transition: background-size var(--speed2) linear;
30
+ }
31
+
32
+ &:active::after {
33
+ background-size: 0%;
34
+ opacity: 0;
35
+ transition: none;
36
+ }
37
+ }
38
+
39
+ // Hover/focus tint overlay used by [class*="ripple"] elements.
40
+ @mixin ripple-hover-overlay() {
41
+ &:is(:hover, :focus-visible)::after {
42
+ content: "";
43
+ position: absolute;
44
+ inset: 0;
45
+ background: currentColor;
46
+ opacity: 0.1;
47
+ border-radius: inherit;
48
+ pointer-events: none;
49
+ }
50
+ }
51
+
52
+ // JS-driven expanding-circle ripple container injected on mousedown.
53
+ // Component shadow stylesheets only need this if they host the .ripple-js node.
54
+ @mixin ripple-js-container() {
55
+ > .ripple-js {
56
+ position: absolute;
57
+ inset: 0;
58
+ pointer-events: none;
59
+ overflow: hidden;
60
+
61
+ > div {
62
+ position: absolute;
63
+ border-radius: 50%;
64
+ background: currentColor;
65
+ opacity: 0.3;
66
+ transform: scale(0);
67
+ animation: to-ripple var(--_duration, 600ms) linear;
68
+ }
69
+ }
70
+ }
71
+
72
+ // Standard focus ring used on interactive surfaces. Vanilla applies this via
73
+ // :is(a, button, .button, .chip, summary):focus-visible — replicate inside
74
+ // a component's own root selector.
75
+ @mixin focus-ring() {
76
+ &:focus-visible {
77
+ outline: 0.125rem solid var(--primary);
78
+ outline-offset: 0.25rem;
79
+ }
80
+ }
@@ -0,0 +1,65 @@
1
+ // .badge — corner indicator. Position via .top/.bottom/.left/.right modifiers.
2
+
3
+ .badge {
4
+ --_x: 0;
5
+ --_y: -100%;
6
+ display: inline-flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ position: absolute;
10
+ font-size: 0.6875rem;
11
+ z-index: 2;
12
+ padding: 0 0.25rem;
13
+ min-block-size: 1rem;
14
+ min-inline-size: 1rem;
15
+ background-color: var(--error);
16
+ color: var(--on-error);
17
+ line-height: normal;
18
+ border-radius: 1rem;
19
+ inset: 50% auto auto 50%;
20
+ transform: translate(var(--_x, 50%), var(--_y, -50%));
21
+ font-family: var(--font);
22
+
23
+ &.top { --_y: -100%; }
24
+ &.bottom { --_y: 0; }
25
+ &.left { --_x: -100%; }
26
+ &.right { --_x: 0; }
27
+
28
+ &.border {
29
+ border-color: var(--error);
30
+ color: var(--error);
31
+ background-color: var(--surface);
32
+ }
33
+
34
+ &:is(.circle, .square) {
35
+ text-align: center;
36
+ inline-size: auto;
37
+ block-size: auto;
38
+ padding: 0 0.25rem;
39
+ border-radius: 1rem;
40
+ }
41
+
42
+ &.square {
43
+ border-radius: 0;
44
+ }
45
+
46
+ &.min {
47
+ clip-path: circle(18.75% at 50% 50%);
48
+
49
+ > * {
50
+ display: none;
51
+ }
52
+ }
53
+
54
+ &.none {
55
+ inset: auto !important;
56
+ transform: none;
57
+ position: relative;
58
+ margin: 0 0.125rem;
59
+ }
60
+ }
61
+
62
+ nav:is(.left, .right, .top, .bottom) > a > .badge,
63
+ nav:is(.left, .right, .top, .bottom) > :is(ol > li, ul > li, div:not([class]), div[class="active"]) > a > .badge {
64
+ inset: 1rem auto auto 50%;
65
+ }
@@ -0,0 +1,83 @@
1
+ // <header> and <footer> top/bottom bars + .fixed sticky behavior.
2
+
3
+ header,
4
+ footer {
5
+ display: grid;
6
+ align-content: center;
7
+ border-radius: 0;
8
+ padding: 0 1rem;
9
+ }
10
+
11
+ :is(dialog, article) > :is(header, footer) {
12
+ padding-inline: 0;
13
+ inset: 0;
14
+ }
15
+
16
+ header { min-block-size: 4rem; }
17
+ footer { min-block-size: 5rem; }
18
+
19
+ :is(header, footer, menu > *).fixed {
20
+ position: sticky;
21
+ inset: 0;
22
+ z-index: 11;
23
+ background-color: inherit;
24
+ }
25
+
26
+ header.fixed {
27
+ inset: calc(-1 * var(--_padding, 0)) 0 0 0;
28
+ margin-block-start: calc(-1 * var(--_padding, 0));
29
+ }
30
+
31
+ footer.fixed {
32
+ inset: 0 0 calc(-1 * var(--_padding, 0)) 0;
33
+ margin-block-end: calc(-1 * var(--_padding, 0));
34
+ }
35
+
36
+ :is(header, footer).fixed.min {
37
+ margin-inline: auto;
38
+ }
39
+
40
+ dialog > :is(header, footer) {
41
+ background: none;
42
+ }
43
+
44
+ dialog > :is(header, footer).fixed {
45
+ background-color: inherit;
46
+ }
47
+
48
+ :is(main, header, footer, section).responsive {
49
+ max-inline-size: min(100vw, 75rem);
50
+ margin: 0 auto;
51
+
52
+ &.max {
53
+ max-inline-size: none;
54
+ }
55
+ }
56
+
57
+ :has(> main) > :is(header, footer).fixed {
58
+ transform: none;
59
+ box-sizing: content-box;
60
+ position: sticky;
61
+ inset: 0;
62
+ z-index: 12;
63
+ }
64
+
65
+ :has(> main) > header { padding-block-start: var(--top, 0); }
66
+ :has(> main) > footer { padding-block-end: var(--bottom, 0); }
67
+
68
+ nav.top ~ header,
69
+ nav.bottom ~ footer {
70
+ padding-block: 0;
71
+ }
72
+
73
+ nav.top ~ header.fixed {
74
+ inset-block: calc(var(--top, 0) + 4.5rem) 0;
75
+ }
76
+
77
+ nav.bottom ~ footer.fixed {
78
+ inset-block: 0 calc(var(--bottom, 0) + 4.5rem);
79
+ }
80
+
81
+ :is(nav, .row) > header {
82
+ background-color: inherit;
83
+ }
@@ -0,0 +1,119 @@
1
+ // .button / <button> baseline + size/shape/state variants.
2
+
3
+ @use "sass:map";
4
+
5
+ .button,
6
+ button {
7
+ --_padding: 1rem;
8
+ --_size: 2.5rem;
9
+ --_round: calc(var(--_size) / 2) !important;
10
+ box-sizing: content-box;
11
+ display: inline-flex;
12
+ align-items: center;
13
+ justify-content: center;
14
+ block-size: var(--_size);
15
+ font-size: 0.875rem;
16
+ font-weight: 500;
17
+ color: var(--on-primary);
18
+ padding: 0 var(--_padding);
19
+ background-color: var(--primary);
20
+ border-radius: 1.25rem;
21
+ transition:
22
+ transform var(--speed3),
23
+ border-radius var(--speed2),
24
+ padding var(--speed3);
25
+ user-select: none;
26
+ gap: 0.5rem;
27
+ line-height: normal;
28
+ }
29
+
30
+ $-button-sizes: (
31
+ "small": (size: 2rem, padding: 0.75rem),
32
+ "large": (size: 3rem, padding: 1.25rem),
33
+ );
34
+
35
+ @each $name, $values in $-button-sizes {
36
+ :is(button, .button).#{$name} {
37
+ --_size: #{map.get($values, size)};
38
+ --_padding: #{map.get($values, padding)};
39
+ }
40
+ }
41
+
42
+ :is(.button, button):is(.extra, .extend) {
43
+ --_size: 3.5rem;
44
+ font-size: 1rem;
45
+ --_padding: 1.5rem;
46
+ }
47
+
48
+ :is(button, .button):is(.square, .circle) {
49
+ --_padding: 0;
50
+ }
51
+
52
+ :is(button, .button).border {
53
+ border-color: var(--outline-variant);
54
+ color: var(--primary);
55
+ }
56
+
57
+ .extend {
58
+ > span:not([class]) {
59
+ display: none;
60
+ }
61
+
62
+ &:is(:hover, .active) {
63
+ inline-size: auto;
64
+ --_padding: 1.5rem;
65
+ padding: 0 var(--_padding);
66
+
67
+ > i + span {
68
+ display: inherit;
69
+ margin-inline-start: var(--_padding);
70
+ }
71
+
72
+ > :is(img, svg) + span {
73
+ display: inherit;
74
+ margin-inline-start: calc(1rem + var(--_padding, 0));
75
+ }
76
+ }
77
+ }
78
+
79
+ :is(.button, button)[disabled] {
80
+ opacity: 0.5;
81
+ cursor: not-allowed;
82
+ }
83
+
84
+ .button[disabled] {
85
+ pointer-events: none;
86
+ }
87
+
88
+ :is(.button, button)[disabled]::before,
89
+ :is(.button, button)[disabled]::after {
90
+ display: none;
91
+ }
92
+
93
+ :is(.button, button):not(.chip, .extend) {
94
+ &.fill {
95
+ background-color: var(--secondary-container) !important;
96
+ color: var(--on-secondary-container) !important;
97
+ }
98
+
99
+ &.active {
100
+ background-color: var(--primary-container);
101
+ color: var(--on-primary-container);
102
+ }
103
+
104
+ &.fill.active {
105
+ background-color: var(--secondary) !important;
106
+ color: var(--on-secondary) !important;
107
+ }
108
+
109
+ &.border.active {
110
+ background-color: var(--inverse-surface) !important;
111
+ color: var(--inverse-on-surface) !important;
112
+ border-color: var(--inverse-surface) !important;
113
+ }
114
+ }
115
+
116
+ :is(.button, button):not(.chip):active,
117
+ :is(.button, button):not(.chip).active {
118
+ border-radius: 0.5rem !important;
119
+ }
@@ -0,0 +1,32 @@
1
+ // <article> = card surface. Sizes loop over a small map.
2
+
3
+ article {
4
+ --_padding: 1rem;
5
+ box-shadow: var(--elevate1);
6
+ background-color: var(--surface-container-low);
7
+ color: var(--on-surface);
8
+ padding: var(--_padding);
9
+ border-radius: 0.75rem;
10
+ display: block;
11
+ transition:
12
+ transform var(--speed3),
13
+ border-radius var(--speed3),
14
+ padding var(--speed3);
15
+
16
+ &.border {
17
+ box-shadow: none;
18
+ border: 0.0625rem solid var(--outline-variant);
19
+ }
20
+ }
21
+
22
+ $-card-sizes: (
23
+ "small": 12rem,
24
+ "medium": 20rem,
25
+ "large": 32rem,
26
+ );
27
+
28
+ @each $name, $value in $-card-sizes {
29
+ article.#{$name} {
30
+ block-size: $value;
31
+ }
32
+ }
@@ -0,0 +1,46 @@
1
+ // .chip — pill-shaped action element with three size tiers.
2
+
3
+ @use "sass:map";
4
+
5
+ .chip {
6
+ --_padding: 0.75rem;
7
+ --_size: 2rem;
8
+ --_round: calc(var(--_size) / 2) !important;
9
+ box-sizing: border-box;
10
+ display: inline-flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ block-size: var(--_size);
14
+ min-inline-size: var(--_size);
15
+ font-size: 0.875rem;
16
+ font-weight: 500;
17
+ background-color: transparent;
18
+ border: 0.0625rem solid var(--outline-variant);
19
+ color: var(--on-surface-variant);
20
+ padding: 0 var(--_padding);
21
+ border-radius: 0.5rem;
22
+ transition:
23
+ transform var(--speed3),
24
+ border-radius var(--speed3),
25
+ padding var(--speed3);
26
+ user-select: none;
27
+ gap: 0.5rem;
28
+ line-height: normal;
29
+ letter-spacing: normal;
30
+
31
+ &.fill {
32
+ border: none;
33
+ }
34
+ }
35
+
36
+ $-chip-sizes: (
37
+ "medium": (size: 2.5rem, padding: 1rem),
38
+ "large": (size: 3rem, padding: 1.25rem),
39
+ );
40
+
41
+ @each $name, $values in $-chip-sizes {
42
+ .chip.#{$name} {
43
+ --_size: #{map.get($values, size)};
44
+ --_padding: #{map.get($values, padding)};
45
+ }
46
+ }