maverick-wave 3.3.0 → 3.3.2

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 (77) hide show
  1. package/.claude/skills/maverick-wave/SKILL.md +208 -0
  2. package/.claude/skills/maverick-wave/examples/angular-form.md +275 -0
  3. package/.claude/skills/maverick-wave/examples/angular-list-page.md +304 -0
  4. package/.claude/skills/maverick-wave/examples/angular-services.md +348 -0
  5. package/.claude/skills/maverick-wave/examples/static-landing-page.md +362 -0
  6. package/.claude/skills/maverick-wave/references/components.md +812 -0
  7. package/.claude/skills/maverick-wave/references/forms.md +289 -0
  8. package/.claude/skills/maverick-wave/references/javascript.md +70 -0
  9. package/.claude/skills/maverick-wave/references/layout.md +300 -0
  10. package/.claude/skills/maverick-wave/references/theming.md +192 -0
  11. package/.github/workflows/ci.yml +41 -0
  12. package/CHANGELOG.md +13 -0
  13. package/README.md +115 -21
  14. package/index.html +15 -9
  15. package/maverick-wave.min.css +1 -1
  16. package/maverick-wave.min.js +1 -1
  17. package/package.json +3 -1
  18. package/scripts/verify.js +137 -0
  19. package/src/js/main.js +39 -11
  20. package/src/partials/accordions-container.html +22 -27
  21. package/src/partials/alerts-container.html +26 -0
  22. package/src/partials/avatars-container.html +22 -0
  23. package/src/partials/buttons-container.html +11 -15
  24. package/src/partials/cards-container.html +8 -8
  25. package/src/partials/colors-container.html +33 -20
  26. package/src/partials/documentation-container.html +3 -0
  27. package/src/partials/form-field-container.html +16 -12
  28. package/src/partials/get-started-container.html +93 -35
  29. package/src/partials/header-utilities-container.html +64 -6
  30. package/src/partials/input-group-container.html +5 -3
  31. package/src/partials/page-header-container.html +78 -0
  32. package/src/partials/tables-container.html +130 -0
  33. package/src/partials/tabs-container.html +20 -16
  34. package/src/partials/tags-container.html +55 -1
  35. package/src/scss/abstracts/_index.scss +4 -1
  36. package/src/scss/abstracts/_variables.scss +128 -106
  37. package/src/scss/base/_base.scss +32 -136
  38. package/src/scss/base/_reset.scss +1 -1
  39. package/src/scss/base/_typography.scss +0 -92
  40. package/src/scss/components/_accordions.scss +3 -3
  41. package/src/scss/components/_avatars.scss +28 -1
  42. package/src/scss/components/_blog-post.scss +1 -1
  43. package/src/scss/components/_button-bar.scss +6 -6
  44. package/src/scss/components/_buttons.scss +33 -10
  45. package/src/scss/components/_cards.scss +7 -7
  46. package/src/scss/components/_coming-soon.scss +4 -4
  47. package/src/scss/components/_gallery.scss +2 -2
  48. package/src/scss/components/_index.scss +1 -0
  49. package/src/scss/components/_info.scss +20 -3
  50. package/src/scss/components/_lists.scss +11 -10
  51. package/src/scss/components/_modals.scss +14 -7
  52. package/src/scss/components/_pagination.scss +3 -3
  53. package/src/scss/components/_panels.scss +4 -4
  54. package/src/scss/components/_progress.scss +1 -1
  55. package/src/scss/components/_ratings.scss +1 -1
  56. package/src/scss/components/_spinners.scss +2 -2
  57. package/src/scss/components/_stepper.scss +3 -2
  58. package/src/scss/components/_tables.scss +42 -1
  59. package/src/scss/components/_tabs.scss +5 -5
  60. package/src/scss/components/_tags.scss +43 -27
  61. package/src/scss/components/_tiles.scss +3 -3
  62. package/src/scss/components/_timelines.scss +2 -2
  63. package/src/scss/components/_toasts.scss +92 -0
  64. package/src/scss/form-elements/_form.scss +11 -3
  65. package/src/scss/form-elements/_input.scss +24 -0
  66. package/src/scss/form-elements/_toggle.scss +1 -1
  67. package/src/scss/layout/_footer.scss +4 -4
  68. package/src/scss/layout/_header.scss +219 -59
  69. package/src/scss/layout/_index.scss +1 -0
  70. package/src/scss/layout/_main.scss +1 -1
  71. package/src/scss/layout/_page-header.scss +48 -0
  72. package/src/scss/layout/_section.scss +15 -14
  73. package/src/scss/main.scss +4 -0
  74. package/src/scss/utilities/_flex.scss +4 -0
  75. package/src/scss/utilities/_index.scss +1 -0
  76. package/src/scss/utilities/_text.scss +105 -0
  77. package/.claude/commands/mw.md +0 -595
@@ -47,7 +47,7 @@
47
47
  // Login button styling
48
48
  .mw-login-btn {
49
49
  background: var(--mw-primary-color);
50
- color: var(--mw-primary-text-color);
50
+ color: var(--mw-accent-text-color);
51
51
  border: none;
52
52
  border-radius: radius('md');
53
53
  font-size: font-size('md');
@@ -66,7 +66,9 @@
66
66
  }
67
67
 
68
68
  &:disabled {
69
- color: var(--mw-text-muted-color);
69
+ // Same treatment as every other disabled button — a theme-bound text
70
+ // color would go dark on this always-primary surface in light mode
71
+ opacity: 0.6;
70
72
  cursor: not-allowed;
71
73
  }
72
74
  }
@@ -107,9 +109,6 @@
107
109
 
108
110
  &.open {
109
111
  background: var(--mw-secondary-color);
110
- position: fixed;
111
- top: 14px;
112
- right: 6%;
113
112
  z-index: z-index('header') + 10;
114
113
 
115
114
  &:hover {
@@ -136,7 +135,7 @@
136
135
  .mw-menu-btn-burger {
137
136
  width: 18px;
138
137
  height: 2px;
139
- background: var(--mw-primary-text-color);
138
+ background: var(--mw-header-burgerbutton-color);
140
139
  border-radius: 1px;
141
140
  position: relative;
142
141
  transition: all 0.3s ease;
@@ -148,7 +147,7 @@
148
147
  left: 0;
149
148
  width: 18px;
150
149
  height: 2px;
151
- background: var(--mw-primary-text-color);
150
+ background: var(--mw-header-burgerbutton-color);
152
151
  border-radius: 1px;
153
152
  transition: all 0.3s ease;
154
153
  }
@@ -163,56 +162,144 @@
163
162
  }
164
163
  }
165
164
 
166
- @mixin navbar-open-state {
165
+ // Header bar height: 42px logo + 2 × spacing('3') padding + 1px border.
166
+ // Overridable via --mw-header-height for projects with a taller bar.
167
+ $_header-height: 59px;
168
+
169
+ // Off-canvas drawer for the collapsed navbar (mobile only)
170
+ @mixin navbar-off-canvas {
171
+ position: fixed;
172
+ top: 0;
173
+ right: 0;
174
+ --mw-navbar-drawer-width: 250px;
175
+ width: var(--mw-navbar-drawer-width);
176
+ height: 100dvh;
177
+ background: var(--mw-header-background);
178
+ border-left: 1px solid var(--mw-header-border);
179
+ box-shadow: -10px 0 30px var(--mw-shadow);
180
+ z-index: z-index('header') + 3;
181
+
182
+ transform: translateX(100%);
183
+ visibility: hidden;
184
+ transition:
185
+ transform 0.3s cubic-bezier(0.32, 0.72, 0, 1),
186
+ visibility 0.3s;
187
+
188
+ .mw-navbar-list {
189
+ display: flex;
190
+ flex-direction: column;
191
+ align-items: stretch;
192
+ gap: spacing('1');
193
+ height: 100%;
194
+ overflow-y: auto;
195
+ // Keeps a rubber-band scroll inside the panel from moving the page
196
+ overscroll-behavior: contain;
197
+ padding: calc(
198
+ var(--mw-header-height, #{$_header-height}) + #{spacing('6')} +
199
+ env(safe-area-inset-top)
200
+ )
201
+ spacing('4') calc(#{spacing('6')} + env(safe-area-inset-bottom));
202
+ }
203
+
204
+ .mw-navbar-item {
205
+ width: 100%;
206
+ margin: spacing('0');
207
+ opacity: 0;
208
+ transform: translateX(12px);
209
+ }
210
+
211
+ .mw-navbar-link {
212
+ display: flex;
213
+ align-items: center;
214
+ min-height: 48px;
215
+ width: 100%;
216
+ padding: spacing('3') spacing('4');
217
+ border-radius: radius('md');
218
+ font-size: font-size('md');
219
+ text-align: left;
220
+ color: var(--mw-header-text-color);
221
+
222
+ // The sliding underline is a hover affordance and has no place on touch
223
+ &::after {
224
+ display: none;
225
+ }
226
+
227
+ // Restated here: the plain color above already outranks the base
228
+ &:hover {
229
+ color: var(--mw-header-navbar-list-active-color);
230
+ background: var(--mw-primary-background);
231
+ }
232
+
233
+ &:active {
234
+ background: var(--mw-primary-background-hover);
235
+ }
236
+
237
+ // Last, so the current page keeps its look while being hovered
238
+ &.active {
239
+ color: var(--mw-header-navbar-list-active-color);
240
+ background: var(--mw-primary-background);
241
+ box-shadow: inset 3px 0 0 var(--mw-primary-color);
242
+ font-weight: font-weight('medium');
243
+ }
244
+ }
245
+
167
246
  &.open {
168
- position: fixed;
169
- top: 0;
170
- right: 0;
171
- width: 80%;
172
- max-width: 280px;
173
- height: 100dvh;
174
- background: var(--mw-header-background);
175
247
  transform: translateX(0);
176
- transition: transform 0.3s ease;
177
- z-index: z-index('header') + 3;
178
- border-left: 1px solid var(--mw-header-border);
248
+ visibility: visible;
179
249
 
180
- .mw-navbar-list {
181
- display: flex;
182
- flex-direction: column;
183
- align-items: flex-start;
184
- gap: spacing('0');
185
- padding-top: 80px;
186
- padding-left: spacing('3');
187
- padding-right: spacing('3');
188
- height: 100%;
189
- overflow-y: auto;
250
+ // Items follow the panel in, slightly staggered
251
+ .mw-navbar-item {
252
+ animation: mw-navbar-item-in 0.3s ease forwards;
253
+
254
+ @for $i from 1 through 10 {
255
+ &:nth-child(#{$i}) {
256
+ animation-delay: 0.1s + $i * 0.035s;
257
+ }
258
+ }
190
259
  }
260
+ }
261
+
262
+ @media (prefers-reduced-motion: reduce) {
263
+ transition-duration: 0.01ms;
191
264
 
192
265
  .mw-navbar-item {
193
- width: 100%;
194
- margin: spacing('0');
266
+ opacity: 1;
267
+ transform: none;
268
+ animation: none;
195
269
  }
270
+ }
271
+ }
196
272
 
197
- .mw-navbar-link {
198
- display: block;
199
- padding: spacing('3') spacing('0');
200
- border-bottom: 1px solid var(--mw-header-border);
201
- width: 100%;
202
- text-align: left;
203
-
204
- &::after {
205
- display: none;
206
- }
273
+ // Page scrim behind the drawer
274
+ @mixin navbar-scrim($navbar-selector) {
275
+ body:has(#{$navbar-selector}.open) {
276
+ overflow: hidden;
207
277
 
208
- &.active {
209
- color: var(--mw-header-navbar-list-active-color);
210
- font-weight: font-weight('medium');
211
- }
278
+ &::after {
279
+ content: '';
280
+ position: fixed;
281
+ inset: 0;
282
+ background: var(--mw-overlay-background);
283
+ backdrop-filter: blur(2px);
284
+ z-index: z-index('header') - 1;
285
+ animation: mw-navbar-scrim-in 0.3s ease;
212
286
  }
213
287
  }
214
288
  }
215
289
 
290
+ @keyframes mw-navbar-item-in {
291
+ to {
292
+ opacity: 1;
293
+ transform: translateX(0);
294
+ }
295
+ }
296
+
297
+ @keyframes mw-navbar-scrim-in {
298
+ from {
299
+ opacity: 0;
300
+ }
301
+ }
302
+
216
303
  // Navbar with built-in auto-detection
217
304
  .mw-navbar {
218
305
  display: flex;
@@ -277,36 +364,37 @@
277
364
  // Auto-responsive behavior based on nav item count
278
365
  // Default behavior (1-3 items): collapse at md
279
366
  @include media-down('md') {
280
- .mw-navbar-list {
281
- display: none;
282
- }
283
-
284
- @include navbar-open-state;
367
+ @include navbar-off-canvas;
285
368
  }
286
369
 
287
370
  // Medium (4-5 items): collapse at lg
288
371
  &.mw-navbar-medium {
289
372
  @include media-down('lg') {
290
- .mw-navbar-list {
291
- display: none;
292
- }
293
-
294
- @include navbar-open-state;
373
+ @include navbar-off-canvas;
295
374
  }
296
375
  }
297
376
 
298
377
  // Large (6+ items): collapse at xl
299
378
  &.mw-navbar-large {
300
379
  @include media-down('xl') {
301
- .mw-navbar-list {
302
- display: none;
303
- }
304
-
305
- @include navbar-open-state;
380
+ @include navbar-off-canvas;
306
381
  }
307
382
  }
308
383
  }
309
384
 
385
+ // Every variant is collapsed at md, so the default selector covers them all
386
+ @include media-down('md') {
387
+ @include navbar-scrim('.mw-navbar');
388
+ }
389
+
390
+ @include media-down('lg') {
391
+ @include navbar-scrim('.mw-navbar-medium');
392
+ }
393
+
394
+ @include media-down('xl') {
395
+ @include navbar-scrim('.mw-navbar-large');
396
+ }
397
+
310
398
  // Show burger button based on navbar size
311
399
  .mw-navbar {
312
400
  // Default (1-3 items): show burger at md
@@ -351,3 +439,75 @@
351
439
  transform: translateY(0);
352
440
  }
353
441
  }
442
+
443
+ // Profile button - avatar plus the signed-in name
444
+ .mw-profile-btn {
445
+ display: inline-flex;
446
+ align-items: center;
447
+ gap: spacing('3');
448
+ height: 40px;
449
+ padding: spacing('0') spacing('4') spacing('0') spacing('1');
450
+ background: transparent;
451
+ border: 1px solid var(--mw-header-border);
452
+ border-radius: radius('2xl');
453
+ color: var(--mw-header-text-color);
454
+ cursor: pointer;
455
+ transition: var(--mw-transition);
456
+ flex-shrink: 0;
457
+ max-width: 220px;
458
+
459
+ // The avatar brings spacing of its own that would break the pill shape
460
+ .mw-avatar {
461
+ margin: spacing('0');
462
+ box-shadow: none;
463
+ border-width: 0;
464
+ }
465
+
466
+ &-name {
467
+ font-size: font-size('sm');
468
+ font-weight: font-weight('medium');
469
+ line-height: 1.2;
470
+ white-space: nowrap;
471
+ overflow: hidden;
472
+ text-overflow: ellipsis;
473
+ }
474
+
475
+ &:hover:not(:disabled) {
476
+ background: var(--mw-primary-background-hover);
477
+ border-color: var(--mw-primary-color);
478
+ }
479
+
480
+ &:focus-visible {
481
+ outline: 2px solid var(--mw-primary-color);
482
+ outline-offset: 2px;
483
+ }
484
+
485
+ &:disabled {
486
+ opacity: 0.6;
487
+ cursor: not-allowed;
488
+ }
489
+
490
+ // Icon fallback for projects without initials
491
+ > i,
492
+ > svg,
493
+ > [class*='fa-'] {
494
+ display: inline-flex;
495
+ align-items: center;
496
+ justify-content: center;
497
+ width: 32px;
498
+ height: 32px;
499
+ flex-shrink: 0;
500
+ font-size: font-size('xl');
501
+ }
502
+
503
+ @include media-down('md') {
504
+ padding: spacing('0');
505
+ width: 40px;
506
+ justify-content: center;
507
+ border-radius: radius('full');
508
+
509
+ .mw-profile-btn-name {
510
+ display: none;
511
+ }
512
+ }
513
+ }
@@ -3,4 +3,5 @@
3
3
  @forward 'header';
4
4
  @forward 'home';
5
5
  @forward 'main';
6
+ @forward 'page-header';
6
7
  @forward 'section';
@@ -70,7 +70,7 @@
70
70
  left: 50%;
71
71
  transform: translateX(-50%) translateY(-10px);
72
72
  background: var(--mw-gray-color);
73
- color: var(--mw-white-color);
73
+ color: var(--mw-accent-text-color);
74
74
  padding: spacing('1') spacing('2');
75
75
  font-size: font-size('xs');
76
76
  border-radius: radius('xs');
@@ -0,0 +1,48 @@
1
+ @use '../abstracts' as *;
2
+
3
+ .mw-page-header {
4
+ display: flex;
5
+ flex-wrap: wrap;
6
+ align-items: flex-start;
7
+ justify-content: space-between;
8
+ gap: spacing('4');
9
+ margin-bottom: spacing('6');
10
+ padding-bottom: spacing('4');
11
+ border-bottom: 1px solid var(--mw-border);
12
+
13
+ h1,
14
+ h2,
15
+ h3 {
16
+ margin: spacing('0');
17
+ font-size: font-size('2xl');
18
+ line-height: 1.2;
19
+
20
+ @include media-down('sm') {
21
+ font-size: font-size('xl');
22
+ }
23
+ }
24
+
25
+ p {
26
+ margin: spacing('1') spacing('0') spacing('0') spacing('0');
27
+ color: var(--mw-text-muted-color);
28
+ font-size: font-size('sm');
29
+ }
30
+
31
+ &-actions {
32
+ display: flex;
33
+ flex-wrap: wrap;
34
+ align-items: center;
35
+ gap: spacing('3');
36
+ margin-left: auto;
37
+
38
+ @include media-down('sm') {
39
+ width: 100%;
40
+ margin-left: spacing('0');
41
+ }
42
+ }
43
+
44
+ &-plain {
45
+ padding-bottom: spacing('0');
46
+ border-bottom: none;
47
+ }
48
+ }
@@ -73,7 +73,7 @@
73
73
 
74
74
  &:hover:not(:disabled) {
75
75
  background: var(--mw-primary-color);
76
- color: var(--mw-primary-text-color);
76
+ color: var(--mw-accent-text-color);
77
77
  }
78
78
 
79
79
  &:focus-visible {
@@ -104,20 +104,21 @@
104
104
  }
105
105
  }
106
106
 
107
- // additional spacing for the whole section
108
- // Pattern variants for sections
109
- section {
107
+ // Additional spacing for the whole section
108
+ .mw-section {
110
109
  padding: spacing('7') spacing('0');
111
110
  position: relative;
111
+ }
112
112
 
113
- &.mw-section-alternate {
114
- --s: 5px; // size
115
- --c1: var(--mw-page-background);
116
- --c2: var(--mw-section-alternate-pattern);
117
- --g: var(--c2) -5% 5%, var(--c1) 0 45%;
118
- background:
119
- linear-gradient(0deg, #0000 10%, var(--c1) 0 40%, #0000 0),
120
- repeating-linear-gradient(-45deg, var(--g)) var(--c1);
121
- background-size: var(--s) var(--s);
122
- }
113
+ // Pattern variant for sections
114
+ .mw-section-alternate {
115
+ position: relative;
116
+ --s: 5px; // size
117
+ --c1: var(--mw-page-background);
118
+ --c2: var(--mw-section-alternate-pattern);
119
+ --g: var(--c2) -5% 5%, var(--c1) 0 45%;
120
+ background:
121
+ linear-gradient(0deg, #0000 10%, var(--c1) 0 40%, #0000 0),
122
+ repeating-linear-gradient(-45deg, var(--g)) var(--c1);
123
+ background-size: var(--s) var(--s);
123
124
  }
@@ -1,3 +1,7 @@
1
+ // Forwarded first so `@use 'main' with (...)` can configure the root colors,
2
+ // $mw-theme-mode and $mw-hero-image before any layer consumes them.
3
+ @forward 'abstracts/variables';
4
+
1
5
  @use 'base';
2
6
  @use 'components';
3
7
  @use 'form-elements';
@@ -22,6 +22,10 @@
22
22
  flex: 1;
23
23
  }
24
24
 
25
+ &-grow-1 {
26
+ flex-grow: 1;
27
+ }
28
+
25
29
  &-shrink-0 {
26
30
  flex-shrink: 0;
27
31
  }
@@ -1,3 +1,4 @@
1
1
  @forward 'display';
2
2
  @forward 'flex';
3
3
  @forward 'spacing';
4
+ @forward 'text';
@@ -0,0 +1,105 @@
1
+ @use '../abstracts' as *;
2
+
3
+ // Text utilities
4
+ .mw-text {
5
+ &-center {
6
+ text-align: center;
7
+ }
8
+
9
+ &-left {
10
+ text-align: left;
11
+ }
12
+
13
+ &-right {
14
+ text-align: right;
15
+ }
16
+
17
+ // For money and other figures in tables: right-aligned, fixed-width digits
18
+ // so decimal places line up across rows, and never wrapped mid-number.
19
+ // Locale-agnostic - works for 1,204.50 and 1.204,50 alike, because the
20
+ // alignment comes from the right edge, not from the separator.
21
+ // `lining-nums` guards against fonts that default to old-style figures.
22
+ &-numeric {
23
+ text-align: right;
24
+ font-variant-numeric: tabular-nums lining-nums;
25
+ font-feature-settings: 'tnum', 'lnum';
26
+ white-space: nowrap;
27
+ }
28
+
29
+ &-primary {
30
+ color: var(--mw-primary-color);
31
+ }
32
+
33
+ &-secondary {
34
+ color: var(--mw-secondary-color);
35
+ }
36
+
37
+ &-success {
38
+ color: var(--mw-success-color);
39
+ }
40
+
41
+ &-warning {
42
+ color: var(--mw-warning-color);
43
+ }
44
+
45
+ &-danger {
46
+ color: var(--mw-danger-color);
47
+ }
48
+
49
+ &-info {
50
+ color: var(--mw-info-color);
51
+ }
52
+
53
+ &-muted {
54
+ color: var(--mw-text-muted-color);
55
+ }
56
+
57
+ &-bold {
58
+ font-weight: font-weight('bold');
59
+ }
60
+
61
+ &-medium {
62
+ font-weight: font-weight('medium');
63
+ }
64
+
65
+ &-normal {
66
+ font-weight: font-weight('normal');
67
+ }
68
+
69
+ &-light {
70
+ font-weight: font-weight('light');
71
+ }
72
+
73
+ &-italic {
74
+ font-style: italic;
75
+ }
76
+
77
+ &-color-dark {
78
+ color: var(--mw-dark-text-color);
79
+ }
80
+
81
+ &-color-light {
82
+ color: var(--mw-light-text-color);
83
+ }
84
+
85
+ @each $name, $size in $font-sizes {
86
+ &-#{$name} {
87
+ font-size: $size;
88
+ }
89
+ }
90
+ }
91
+
92
+ // Line height utilities
93
+ .mw-leading {
94
+ &-tight {
95
+ line-height: 1.2;
96
+ }
97
+
98
+ &-normal {
99
+ line-height: 1.5;
100
+ }
101
+
102
+ &-loose {
103
+ line-height: 1.8;
104
+ }
105
+ }