maverick-wave 4.4.0 → 4.4.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 (56) hide show
  1. package/.claude/skills/maverick-wave/SKILL.md +3 -2
  2. package/.claude/skills/maverick-wave/examples/static-landing-page.md +1 -1
  3. package/.claude/skills/maverick-wave/references/theming.md +91 -67
  4. package/CHANGELOG.md +6 -0
  5. package/README.md +100 -22
  6. package/index.html +7 -29
  7. package/maverick-wave.min.css +2 -2
  8. package/package.json +1 -1
  9. package/scripts/verify.js +8 -2
  10. package/src/assets/favicon/apple-touch-icon.png +0 -0
  11. package/src/assets/favicon/favicon-96x96.png +0 -0
  12. package/src/assets/favicon/favicon.svg +1 -0
  13. package/src/assets/favicon/site.webmanifest +37 -1
  14. package/src/assets/favicon/web-app-manifest-192x192.png +0 -0
  15. package/src/assets/favicon/web-app-manifest-512x512.png +0 -0
  16. package/src/assets/favicon.ico +0 -0
  17. package/src/assets/header-logo.svg +4 -4
  18. package/src/partials/accordions-container.html +6 -6
  19. package/src/partials/colors-container.html +76 -4
  20. package/src/partials/get-started-container.html +17 -14
  21. package/src/partials/tabs-container.html +7 -6
  22. package/src/scss/abstracts/_variables.scss +152 -45
  23. package/src/scss/base/_typography.scss +2 -2
  24. package/src/scss/components/_alerts.scss +2 -2
  25. package/src/scss/components/_avatars.scss +1 -1
  26. package/src/scss/components/_blog-post.scss +5 -5
  27. package/src/scss/components/_breadcrumbs.scss +3 -3
  28. package/src/scss/components/_button-bar.scss +4 -4
  29. package/src/scss/components/_buttons.scss +6 -6
  30. package/src/scss/components/_calendar.scss +10 -10
  31. package/src/scss/components/_cards.scss +2 -2
  32. package/src/scss/components/_divider.scss +3 -3
  33. package/src/scss/components/_empty-state.scss +4 -4
  34. package/src/scss/components/_gallery.scss +1 -1
  35. package/src/scss/components/_info.scss +3 -3
  36. package/src/scss/components/_kanban.scss +3 -3
  37. package/src/scss/components/_lists.scss +13 -12
  38. package/src/scss/components/_localhost-indicator.scss +2 -2
  39. package/src/scss/components/_meta-info.scss +1 -1
  40. package/src/scss/components/_ratings.scss +1 -1
  41. package/src/scss/components/_segmented.scss +3 -3
  42. package/src/scss/components/_spinners.scss +10 -10
  43. package/src/scss/components/_stepper.scss +4 -4
  44. package/src/scss/components/_tabs.scss +5 -5
  45. package/src/scss/components/_techstack-bucket.scss +2 -2
  46. package/src/scss/components/_timelines.scss +10 -10
  47. package/src/scss/form-elements/_form.scss +2 -2
  48. package/src/scss/form-elements/_login.scss +2 -2
  49. package/src/scss/layout/_footer.scss +3 -3
  50. package/src/scss/layout/_header.scss +4 -4
  51. package/src/scss/layout/_section.scss +5 -5
  52. package/src/scss/utilities/_text.scss +6 -6
  53. package/src/assets/favicon/android-chrome-192x192.png +0 -0
  54. package/src/assets/favicon/android-chrome-512x512.png +0 -0
  55. package/src/assets/favicon/favicon-16x16.png +0 -0
  56. package/src/assets/favicon/favicon-32x32.png +0 -0
@@ -230,8 +230,9 @@ text
230
230
  backgrounds and borders are derived with `color-mix()` at runtime. Setting
231
231
  `--mw-primary-color-hover` by hand is usually a sign the base token was not
232
232
  set.
233
- 10. **Browser floor: `color-mix()`** - Chrome 111+, Safari 16.2+, Firefox 113+.
234
- Older browsers get no colours at all, not merely worse ones.
233
+ 10. **Browser floor: `color-mix()` and `oklch(from ...)`** - Chrome 119+,
234
+ Safari 16.4+, Firefox 128+. Both carry the derived tones, so older browsers
235
+ get no colours at all, not merely worse ones.
235
236
  11. **Touch targets grow on their own.** On `pointer: coarse` or below 768px,
236
237
  `mw-btn-sm`, `mw-input-sm`, `mw-select-sm` and `mw-textarea-sm` get a 2.5rem
237
238
  minimum height, a tab 2.75rem, a calendar day 44px. `mw-btn-mini` keeps its
@@ -26,7 +26,7 @@ wired up by hand.
26
26
  /* Brand colours - one token per family, the rest is derived */
27
27
  :root {
28
28
  --mw-primary-color: #0f766e;
29
- --mw-secondary-color: #f39c12;
29
+ --mw-secondary-color: #b45309;
30
30
  --mw-hero-background: url('/assets/hero.jpg');
31
31
  }
32
32
  </style>
@@ -2,11 +2,15 @@
2
2
 
3
3
  ## The model
4
4
 
5
- Twelve colours are configured, everything else is derived from them **at
6
- runtime** with `color-mix()`. Overriding a root token therefore retunes its
7
- whole family - hover tone, translucent backgrounds, borders. That is the
8
- difference to pre-3.4.0, where derived values were baked in at compile time and
9
- a palette switch meant setting 41 variables.
5
+ Thirteen colours are configured, everything else is derived from them **at
6
+ runtime** with `color-mix()` and relative colour syntax. Overriding a root token
7
+ therefore retunes its whole family - hover tone, translucent backgrounds,
8
+ borders, the theme's surface stack, the ink variant the dark theme needs. That is
9
+ the difference to pre-3.4.0, where derived values were baked in at compile time
10
+ and a palette switch meant setting 41 variables.
11
+
12
+ Browser floor for that: `color-mix()` **and** `oklch(from ...)` - Chrome 119+,
13
+ Safari 16.4+, Firefox 128+.
10
14
 
11
15
  ```css
12
16
  /* loaded after maverick-wave.min.css */
@@ -14,21 +18,22 @@ a palette switch meant setting 41 variables.
14
18
  --mw-primary-color: #0f766e; /* also retunes hover, backgrounds, border accent */
15
19
  --mw-secondary-color: #f39c12;
16
20
 
17
- --mw-success-color: #218838;
18
- --mw-warning-color: #d4a310;
19
- --mw-danger-color: #c82333;
20
- --mw-info-color: #17a2b8;
21
+ --mw-success-color: #157f4b;
22
+ --mw-warning-color: #bda817;
23
+ --mw-danger-color: #c42b1c;
24
+ --mw-info-color: #14618f;
21
25
 
22
- --mw-gray-color: #565656;
26
+ --mw-gray-color: #5a6478;
23
27
 
24
- --mw-dark-page-background: #0b111a;
25
- --mw-dark-text-color: #d6dbdf;
26
- --mw-light-page-background: #d2d1e1;
27
- --mw-light-text-color: #1a1a1d;
28
+ --mw-dark-page-background: #171f30;
29
+ --mw-dark-text-color: #e8ecf1;
30
+ --mw-light-page-background: #f2f5f8;
31
+ --mw-light-text-color: #0c1119;
28
32
 
29
- --mw-form-elements-background: #efefef;
33
+ --mw-form-elements-background: #f4f7fb;
30
34
 
31
- /* text on every solid coloured surface */
35
+ /* text on every solid coloured surface, and the one token that cannot be
36
+ derived: light brand colours need a dark label, dark ones a light label */
32
37
  --mw-accent-text-color: #ffffff;
33
38
 
34
39
  --mw-font-family-base: 'Inter', sans-serif;
@@ -37,48 +42,55 @@ a palette switch meant setting 41 variables.
37
42
 
38
43
  ## Which token for what
39
44
 
40
- | Token | Role |
41
- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
42
- | `--mw-primary-color` | Brand colour: primary buttons, table headers, focus rings, active states |
43
- | `--mw-primary-color-hover` | Solid hover surface (derived: base + 18% black) |
44
- | `--mw-primary-background` | 20% tint - focus halo, scrollbar tracks |
45
- | `--mw-primary-background-hover` | 50% tint - row and list hover |
46
- | `--mw-primary-info-background` | 70% tint - alert and info surfaces |
47
- | `--mw-border-accent` | Translucent accent **line**: panel rules, dividers, tab underlines |
48
- | `--mw-secondary-*` | Same set for the second brand colour |
49
- | `--mw-success/warning/danger/info-color` | Status colours, each with `-color-hover`, `-info-background`, `-info-background-hover` |
50
- | `--mw-accent-text-color` | Text on any solid coloured surface (buttons, table/panel headers, badges, stepper dots) |
51
- | `--mw-gray-color` | Neutral foreground: muted icons, tooltips |
52
- | `--mw-gray-background` | Subtle neutral surface (20% alpha): zebra rows, disabled fields, tracks, skeletons |
53
- | `--mw-surface-muted` | Alias of `--mw-gray-background` under the name you reach for: a slightly set-off area _inside_ a card - hint block, framed paragraph, form summary |
54
- | `--mw-overlay-background` | Heavy scrim (60%) behind modals and blocking spinners |
55
- | `--mw-page-background`, `--mw-card-background`, `--mw-footer-background`, `--mw-border`, `--mw-shadow`, `--mw-text-color`, `--mw-text-muted-color`, `--mw-hero-overlay-background` | The **active theme** - aliases pointing at the `--mw-dark-*` or `--mw-light-*` set |
56
- | `--mw-header-*` | Header chrome: `background`, `text-color`, `navbar-list-color`, `navbar-list-active-color`, `burgerbutton-color`, `border` - dark in both themes |
57
- | `--mw-form-elements-background`, `--mw-form-elements-color` | Form controls stay light in both themes and therefore have their own pair |
58
- | `--mw-font-family-base`, `-heading`, `-mono` | Font stacks - system stacks by default (`-mono` leads with Fira Code); no font is bundled. Configurable in SCSS, see below |
59
- | `--mw-hero-background` | Hero image (`url(...)`) |
60
- | `--mw-transition` | Global transition (`all 0.3s ease`) |
61
- | `--mw-card-img-height` | Per-card image height (default `210px`; `mw-card-lg`/`-xl` set it to 340px/480px) |
62
- | `--mw-card-addon-color` | Background of `mw-card-badge` / `mw-card-ribbon`; the `mw-card-addon-*` classes set it, override it for a custom colour |
63
- | `--mw-table-scroll-height` | Per-table height cap for `mw-table-responsive-scroll` |
64
- | `--mw-kanban-background`, `--mw-kanban-lane-border`, `--mw-kanban-column-min-height` | Per-board surface, lane border and lane floor (120px, 90px on `mw-kanban-compact`) |
65
- | `--mw-container-width`, `--mw-container-width-sm` | Content width of `mw-container` (`min(1200px, 89%)`, below 576px a 1rem gutter) |
66
- | `--mw-section-padding-block` | Top/bottom rhythm of `mw-section` (1.75rem) |
67
- | `--mw-calendar-dot` | Colour of a single calendar dot - set it per dot or per cell; the `mw-calendar-dot-*` classes are presets for it |
68
- | `--mw-scroll-hint-cover` | Colour the scroll hint on a tab bar fades into. Preset to the page, re-pointed to the card background inside `mw-card`, `mw-panel`, `mw-modal`, `mw-tile`, `mw-calendar` |
69
- | `--mw-internal-theme-mode` | Read-only: what `$mw-theme-mode` was compiled to |
70
-
71
- The four above are the knobs a good default cannot settle, because the right
72
- answer differs per project: what reads as generous on a landing page costs
73
- visible content in an application with a sticky header.
45
+ | Token | Role |
46
+ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
47
+ | `--mw-primary-color` | Brand colour as a **fill**: primary buttons, table headers, bars, badges - the label on top is `--mw-accent-text-color` |
48
+ | `--mw-primary-text-color` | Brand colour as **ink** on a theme surface: text, icons, focus rings, accent borders. Derived by clamping OKLch lightness (`max(l, .68)` on dark, `min(l, .55)` on light), so a colour already in range is used untouched |
49
+ | `--mw-primary-color-hover` | Solid hover surface (derived: base + `$hover-shift` black, in both themes) |
50
+ | `--mw-primary-background` | 20% tint - focus halo, alert/badge/tag surface, scrollbar tracks |
51
+ | `--mw-primary-background-hover` | 45% tint - row and list hover |
52
+ | `--mw-primary-info-background` | Alias of `--mw-primary-background`, so a component can interpolate one name across all six colours |
53
+ | `--mw-border-accent` | Translucent accent **line**: panel rules, dividers, tab underlines. Theme-aware (70% of `--mw-*-text-color`) |
54
+ | `--mw-secondary-*` | Same set for the second brand colour |
55
+ | `--mw-success/warning/danger/info-color` | Status colours, each with `-text-color`, `-color-hover`, `-info-background`, `-info-background-hover` |
56
+ | `--mw-accent-text-color` | Text on any solid coloured surface (buttons, table/panel headers, badges, stepper dots) |
57
+ | `--mw-gray-color` | Neutral foreground: muted icons, tooltips |
58
+ | `--mw-gray-background` | Subtle neutral surface (20% alpha): zebra rows, disabled fields, tracks, skeletons |
59
+ | `--mw-surface-muted` | Alias of `--mw-gray-background` under the name you reach for: a slightly set-off area _inside_ a card - hint block, framed paragraph, form summary |
60
+ | `--mw-overlay-background` | Heavy scrim (60%) behind modals and blocking spinners |
61
+ | `--mw-page-background`, `--mw-card-background`, `--mw-footer-background`, `--mw-border`, `--mw-shadow`, `--mw-text-color`, `--mw-text-muted-color`, `--mw-hero-overlay-background` | The **active theme** - aliases pointing at the `--mw-dark-*` or `--mw-light-*` set |
62
+ | `--mw-header-*` | Header chrome: `background`, `text-color`, `navbar-list-color`, `navbar-list-active-color`, `burgerbutton-color`, `border` - dark in both themes |
63
+ | `--mw-form-elements-background`, `--mw-form-elements-color` | Form controls stay light in both themes and therefore have their own pair |
64
+ | `--mw-font-family-base`, `-heading`, `-mono` | Font stacks - system stacks by default (`-mono` leads with Fira Code); no font is bundled. Configurable in SCSS, see below |
65
+ | `--mw-hero-background` | Hero image (`url(...)`) |
66
+ | `--mw-transition` | Global transition (`all 0.3s ease`) |
67
+ | `--mw-card-img-height` | Per-card image height (default `210px`; `mw-card-lg`/`-xl` set it to 340px/480px) |
68
+ | `--mw-card-addon-color` | Background of `mw-card-badge` / `mw-card-ribbon`; the `mw-card-addon-*` classes set it, override it for a custom colour |
69
+ | `--mw-table-scroll-height` | Per-table height cap for `mw-table-responsive-scroll` |
70
+ | `--mw-kanban-background`, `--mw-kanban-lane-border`, `--mw-kanban-column-min-height` | Per-board surface, lane border and lane floor (120px, 90px on `mw-kanban-compact`) |
71
+ | `--mw-container-width`, `--mw-container-width-sm` | Content width of `mw-container` (`min(1200px, 89%)`, below 576px a 1rem gutter) |
72
+ | `--mw-section-padding-block` | Top/bottom rhythm of `mw-section` (1.75rem) |
73
+ | `--mw-calendar-dot` | Colour of a single calendar dot - set it per dot or per cell; the `mw-calendar-dot-*` classes are presets for it |
74
+ | `--mw-scroll-hint-cover` | Colour the scroll hint on a tab bar fades into. Preset to the page, re-pointed to the card background inside `mw-card`, `mw-panel`, `mw-modal`, `mw-tile`, `mw-calendar` |
75
+ | `--mw-internal-theme-mode` | Read-only: what `$mw-theme-mode` was compiled to |
76
+
77
+ `--mw-container-width`, `--mw-container-width-sm` and
78
+ `--mw-section-padding-block` are the knobs a good default cannot settle, because
79
+ the right answer differs per project: what reads as generous on a landing page
80
+ costs visible content in an application with a sticky header.
74
81
 
75
82
  Two rules that prevent most colour bugs:
76
83
 
77
- 1. **Surfaces are opaque, lines are translucent.** For a coloured surface use
78
- `--mw-*-color` / `--mw-*-color-hover`; for a rule or outline use
79
- `--mw-border-accent` or `--mw-border`.
84
+ 1. **Fill or ink.** A colour that _fills_ something is `--mw-*-color`; a colour
85
+ _drawn on_ a theme surface - text, icon, focus ring, accent border, thin
86
+ divider - is `--mw-*-text-color`. A colour picked to carry a label is by
87
+ definition unreadable on the page it sits on, so ink is always the
88
+ `-text-color` variant. For a generic rule or outline use `--mw-border-accent`
89
+ or `--mw-border`.
80
90
  2. **`--mw-text-muted-color` is only for text on theme surfaces** (cards, page
81
- background) - it follows the theme. On a colour surface that stays the same
91
+ background) - it follows the theme. It is a true gray with `$muted-tint`
92
+ (12%) of the primary mixed in, not a stepped-back text colour, so it stays
93
+ gray no matter how tinted the palette is. On a colour surface that stays the same
82
94
  in both themes it is always wrong: use `--mw-accent-text-color`, or `opacity`
83
95
  for a disabled look.
84
96
 
@@ -86,6 +98,11 @@ Two rules that prevent most colour bugs:
86
98
 
87
99
  - Dark is the base. Light is applied by putting `mw-theme-light` on `<body>` -
88
100
  that class only re-points the theme aliases at the `--mw-light-*` set.
101
+ - Card, footer and border are derived from the page background by scaling its
102
+ OKLch lightness and chroma by one factor. A card steps **away from the text
103
+ colour** - darker than the page in the dark theme, lighter in the light one.
104
+ A near-black `--mw-dark-page-background` leaves no headroom underneath and
105
+ cards collapse into it; keep it around OKLch lightness 0.24.
89
106
  - Header, footer chrome and form controls deliberately stay dark/light
90
107
  respectively in both themes.
91
108
  - Persisting the choice, the toggle UI and the initial class are the
@@ -106,17 +123,23 @@ effect, because the root colours are declared with `!default`.
106
123
  $mw-theme-mode: 'switchable',
107
124
  // 'switchable' | 'dark' | 'light'
108
125
  $primary-color: #0f766e,
109
- $secondary-color: #f39c12,
110
- $success-color: #218838,
111
- $warning-color: #d4a310,
112
- $danger-color: #c82333,
113
- $info-color: #17a2b8,
114
- $gray-color: #565656,
115
- $dark-background: #0b111a,
116
- $dark-text-color: #d6dbdf,
117
- $light-background: #d2d1e1,
118
- $light-text-color: #1a1a1d,
119
- $form-elements-background: #efefef,
126
+ $secondary-color: #b45309,
127
+ $success-color: #15803d,
128
+ $warning-color: #a16207,
129
+ $danger-color: #b91c1c,
130
+ $info-color: #0e7490,
131
+ $gray-color: #64748b,
132
+ $dark-background: #172127,
133
+ $dark-text-color: #e8eef0,
134
+ $light-background: #f2f6f7,
135
+ $light-text-color: #172127,
136
+ $form-elements-background: #f5f9fa,
137
+ $accent-text-color: #f2fafa,
138
+ // the three derivation knobs, all optional
139
+ $hover-shift: 15%,
140
+ $ink-lightness-dark: 0.68,
141
+ $ink-lightness-light: 0.55,
142
+ $muted-tint: 12%,
120
143
  $mw-hero-image: url('/assets/hero.jpg'),
121
144
  $font-family-base: (
122
145
  'Inter',
@@ -162,7 +185,7 @@ they are all `var()` references anyway:
162
185
 
163
186
  ## Importing only what you need
164
187
 
165
- The full stylesheet is ~147 kB raw / ~22.5 kB gzipped. Marketing components
188
+ The full stylesheet is ~172 kB raw / ~26 kB gzipped. Marketing components
166
189
  (`blog-post`, `gallery`, `content-slider`, `techstack-bucket`, `tiles`,
167
190
  `coming-soon`, `ratings`, `home`, `hero`) are dead weight in an application, and
168
191
  Angular bundle budgets notice.
@@ -201,7 +224,8 @@ colourless.
201
224
  @use 'maverick-wave/src/scss/utilities';
202
225
  ```
203
226
 
204
- That set compiles to ~98 kB raw / ~15 kB gzipped - a third off the full build.
227
+ That set compiles to ~77 kB raw / ~13 kB gzipped - well under half the full
228
+ build.
205
229
 
206
230
  Details worth knowing:
207
231
 
package/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ Patch releases are only for test purposes - here I only document major and minor
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [4.5.0] - 2026-08-21
10
+
11
+ ### Changed
12
+
13
+ - new color concept and new default color palette
14
+
9
15
  ## [4.4.0] - 2026-08-20
10
16
 
11
17
  ### Added
package/README.md CHANGED
@@ -38,12 +38,12 @@ The result is a framework that balances utility with simplicity, offering develo
38
38
  <title>My MaverickWave Project</title>
39
39
  <link
40
40
  rel="stylesheet"
41
- href="https://cdn.jsdelivr.net/npm/maverick-wave@3.7.0/maverick-wave.min.css"
41
+ href="https://cdn.jsdelivr.net/npm/maverick-wave@4.4.1/maverick-wave.min.css"
42
42
  />
43
43
  </head>
44
44
  <body>
45
45
  <!-- Your content here -->
46
- <script src="https://cdn.jsdelivr.net/npm/maverick-wave@3.7.0/maverick-wave.min.js"></script>
46
+ <script src="https://cdn.jsdelivr.net/npm/maverick-wave@4.4.1/maverick-wave.min.js"></script>
47
47
  </body>
48
48
  </html>
49
49
  ```
@@ -71,25 +71,27 @@ backgrounds, borders, muted text - is derived from them at runtime with
71
71
  ```css
72
72
  :root {
73
73
  /* brand */
74
- --mw-primary-color: #e94560;
75
- --mw-secondary-color: #f39c12;
74
+ --mw-primary-color: #0f766e;
75
+ --mw-secondary-color: #b45309;
76
76
 
77
77
  /* status */
78
- --mw-success-color: #218838;
79
- --mw-warning-color: #d4a310;
80
- --mw-danger-color: #c82333;
81
- --mw-info-color: #17a2b8;
78
+ --mw-success-color: #15803d;
79
+ --mw-warning-color: #a16207;
80
+ --mw-danger-color: #b91c1c;
81
+ --mw-info-color: #0e7490;
82
82
 
83
83
  /* neutrals and themes */
84
- --mw-gray-color: #565656;
85
- --mw-dark-page-background: #1a1a2e;
86
- --mw-dark-text-color: #d6dbdf;
87
- --mw-light-page-background: #f8f9fa;
88
- --mw-light-text-color: #1a1a1d;
89
- --mw-form-elements-background: #ffffff;
90
-
91
- /* text on solid colored surfaces: buttons, table and panel headers */
92
- --mw-accent-text-color: #ffffff;
84
+ --mw-gray-color: #64748b;
85
+ --mw-dark-page-background: #172127;
86
+ --mw-dark-text-color: #e8eef0;
87
+ --mw-light-page-background: #f2f6f7;
88
+ --mw-light-text-color: #172127;
89
+ --mw-form-elements-background: #f5f9fa;
90
+
91
+ /* text on every solid colored surface: buttons, table and panel headers.
92
+ The one token that cannot be derived - a light brand color needs a dark
93
+ label, a dark one a light label. Set it opposite your --mw-primary-color. */
94
+ --mw-accent-text-color: #f2fafa;
93
95
 
94
96
  --mw-font-family-base: 'Your Font Name', sans-serif;
95
97
  }
@@ -97,11 +99,82 @@ backgrounds, borders, muted text - is derived from them at runtime with
97
99
 
98
100
  Setting `--mw-primary-color` alone also retunes `--mw-primary-color-hover`,
99
101
  `--mw-primary-background`, `--mw-primary-background-hover`,
100
- `--mw-primary-info-background` and `--mw-border-accent`. The same holds for
102
+ `--mw-primary-text-color` and `--mw-border-accent`. The same holds for
101
103
  `--mw-dark-page-background`, which drives the dark card, footer and border
102
104
  tones. Each derived token can still be overridden individually if you want to
103
105
  break out of the scale.
104
106
 
107
+ > The derivation needs `color-mix()` **and** relative colour syntax
108
+ > (`oklch(from ...)`): Chrome 119+, Safari 16.4+, Firefox 128+. Older browsers
109
+ > get no colours at all, not merely worse ones.
110
+
111
+ ### Fill or ink
112
+
113
+ Every brand and status colour comes in two tokens, and picking the right one is
114
+ the whole trick:
115
+
116
+ - `--mw-primary-color` is the exact colour, for anything it **fills** - buttons,
117
+ badges, bars, progress. The label on top is `--mw-accent-text-color`.
118
+ - `--mw-primary-text-color` is the same colour tuned to the active theme, for
119
+ anything drawn **on** a theme surface - text, icons, focus rings, accent
120
+ borders and dividers.
121
+
122
+ The second one exists because a colour picked to carry a label is by definition
123
+ too dark or too light to be read _on_ the page it sits on. The ink token is
124
+ derived by clamping OKLch lightness and keeping hue and chroma:
125
+
126
+ ```css
127
+ --mw-dark-primary-text-color: oklch(
128
+ from var(--mw-primary-color) max(l, 0.68) c h
129
+ );
130
+ --mw-light-primary-text-color: oklch(
131
+ from var(--mw-primary-color) min(l, 0.55) c h
132
+ );
133
+ ```
134
+
135
+ That is a bound, not a target, which is what makes it work for any palette. A
136
+ dark brand colour gets lifted, a very light one gets deepened, and a colour
137
+ already inside the range passes through untouched - a neon green stays neon on
138
+ the dark page and only turns into a real green on the light one. The bounds are
139
+ `$ink-lightness-dark` and `$ink-lightness-light` in SCSS.
140
+ `--mw-secondary-text-color` and `--mw-success/warning/danger/info-text-color`
141
+ are derived the same way.
142
+
143
+ `--mw-text-muted-color` is built the other way round: a true gray at a fixed
144
+ lightness with `$muted-tint` (12%) of the primary colour mixed in, so the gray
145
+ belongs to the palette without carrying its saturation. Stepping the theme's
146
+ text colour back instead would hand its tint straight through - a mint white
147
+ page would end up with mint green secondary text. Set `$muted-tint: 0%` for a
148
+ neutral gray.
149
+
150
+ Tinted surfaces follow one rule as well: `--mw-*-background` is 20% of the
151
+ colour, `--mw-*-background-hover` 45%. Both stay close enough to the surface
152
+ underneath that `--mw-text-color` keeps working on top, which is what makes an
153
+ alert, badge or tag readable in either theme.
154
+
155
+ ### The surface stack
156
+
157
+ Card, footer and border are derived from the page background by scaling its
158
+ OKLch lightness _and_ chroma by one factor, keeping the hue:
159
+
160
+ ```css
161
+ --mw-dark-card-background: oklch(
162
+ from var(--mw-dark-page-background) calc(l * 0.75) calc(c * 0.75) h
163
+ );
164
+ ```
165
+
166
+ Both themes step a card **away from their text colour** - down into the dark
167
+ theme, up into the light one - so content always sits on the cleaner of the two
168
+ surfaces. Chroma rides along with lightness because that is what a hand-picked
169
+ stack does: a darker surface of the same hue carries less colour, not the same
170
+ colour at a lower lightness.
171
+
172
+ The one thing to know when picking `--mw-dark-page-background`: it needs
173
+ headroom underneath. On a near-black page the surfaces below it have nowhere to
174
+ go and cards collapse into the background, leaving only the border to separate
175
+ them. The default sits at OKLch lightness 0.24 for that reason. The factors sit
176
+ inline in `$dark-theme-colors` / `$light-theme-colors`, one per surface.
177
+
105
178
  ### SCSS Source
106
179
 
107
180
  For full control, clone the repository and integrate `src/scss/main.scss` into your Sass build (Dart Sass required). MaverickWave uses modern `@use`/`@forward` syntax. Pass your overrides through `with`:
@@ -114,10 +187,15 @@ For full control, clone the repository and integrate `src/scss/main.scss` into y
114
187
  $mw-theme-mode: 'switchable',
115
188
 
116
189
  // Override root colors
117
- $primary-color: #e94560,
118
- $secondary-color: #f39c12,
119
- $dark-background: #1f1f2e,
120
- $light-background: #f8f9fa
190
+ $primary-color: #0f766e,
191
+ $secondary-color: #b45309,
192
+ $dark-background: #172127,
193
+ $light-background: #f2f6f7,
194
+
195
+ // Optional: the three derivation knobs
196
+ $ink-lightness-dark: 0.68,
197
+ $ink-lightness-light: 0.55,
198
+ $muted-tint: 12%
121
199
  );
122
200
  ```
123
201
 
package/index.html CHANGED
@@ -16,46 +16,24 @@
16
16
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
17
17
  />
18
18
  <link rel="stylesheet" href="maverick-wave.min.css" />
19
- <!-- Basic favicon -->
20
- <link rel="icon" type="image/x-icon" href="favicon.ico" />
21
-
22
- <!-- PNG favicons -->
23
- <link
24
- rel="icon"
25
- type="image/png"
26
- sizes="32x32"
27
- href="favicon/favicon-32x32.png"
28
- />
19
+ <!-- Favicons -->
20
+ <link rel="icon" type="image/svg+xml" href="favicon/favicon.svg" />
29
21
  <link
30
22
  rel="icon"
31
23
  type="image/png"
32
- sizes="16x16"
33
- href="favicon/favicon-16x16.png"
24
+ sizes="96x96"
25
+ href="favicon/favicon-96x96.png"
34
26
  />
35
-
36
- <!-- Apple Touch Icon (for iOS devices) -->
27
+ <link rel="shortcut icon" href="favicon.ico" />
37
28
  <link
38
29
  rel="apple-touch-icon"
39
30
  sizes="180x180"
40
31
  href="favicon/apple-touch-icon.png"
41
32
  />
42
-
43
- <!-- Safari Pinned Tab Icon -->
44
- <link
45
- rel="mask-icon"
46
- href="favicon/safari-pinned-tab.svg"
47
- color="#5bbad5"
48
- />
49
-
50
- <!-- Android/Chrome Icons -->
51
33
  <link rel="manifest" href="favicon/site.webmanifest" />
52
34
 
53
- <!-- Microsoft Tiles (for Windows) -->
54
- <meta name="msapplication-TileColor" content="#da532c" />
55
- <meta name="msapplication-config" content="favicon/browserconfig.xml" />
56
-
57
- <!-- Theme Color for browsers that support it -->
58
- <meta name="theme-color" content="#ffffff" />
35
+ <!-- Showcase starts in dark mode unless localStorage says otherwise -->
36
+ <meta name="theme-color" content="#171f30" />
59
37
  <style>
60
38
  /* Additional styles only for the showcase page */
61
39
  .position-relative {