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.
- package/.claude/skills/maverick-wave/SKILL.md +3 -2
- package/.claude/skills/maverick-wave/examples/static-landing-page.md +1 -1
- package/.claude/skills/maverick-wave/references/theming.md +91 -67
- package/CHANGELOG.md +6 -0
- package/README.md +100 -22
- package/index.html +7 -29
- package/maverick-wave.min.css +2 -2
- package/package.json +1 -1
- package/scripts/verify.js +8 -2
- package/src/assets/favicon/apple-touch-icon.png +0 -0
- package/src/assets/favicon/favicon-96x96.png +0 -0
- package/src/assets/favicon/favicon.svg +1 -0
- package/src/assets/favicon/site.webmanifest +37 -1
- package/src/assets/favicon/web-app-manifest-192x192.png +0 -0
- package/src/assets/favicon/web-app-manifest-512x512.png +0 -0
- package/src/assets/favicon.ico +0 -0
- package/src/assets/header-logo.svg +4 -4
- package/src/partials/accordions-container.html +6 -6
- package/src/partials/colors-container.html +76 -4
- package/src/partials/get-started-container.html +17 -14
- package/src/partials/tabs-container.html +7 -6
- package/src/scss/abstracts/_variables.scss +152 -45
- package/src/scss/base/_typography.scss +2 -2
- package/src/scss/components/_alerts.scss +2 -2
- package/src/scss/components/_avatars.scss +1 -1
- package/src/scss/components/_blog-post.scss +5 -5
- package/src/scss/components/_breadcrumbs.scss +3 -3
- package/src/scss/components/_button-bar.scss +4 -4
- package/src/scss/components/_buttons.scss +6 -6
- package/src/scss/components/_calendar.scss +10 -10
- package/src/scss/components/_cards.scss +2 -2
- package/src/scss/components/_divider.scss +3 -3
- package/src/scss/components/_empty-state.scss +4 -4
- package/src/scss/components/_gallery.scss +1 -1
- package/src/scss/components/_info.scss +3 -3
- package/src/scss/components/_kanban.scss +3 -3
- package/src/scss/components/_lists.scss +13 -12
- package/src/scss/components/_localhost-indicator.scss +2 -2
- package/src/scss/components/_meta-info.scss +1 -1
- package/src/scss/components/_ratings.scss +1 -1
- package/src/scss/components/_segmented.scss +3 -3
- package/src/scss/components/_spinners.scss +10 -10
- package/src/scss/components/_stepper.scss +4 -4
- package/src/scss/components/_tabs.scss +5 -5
- package/src/scss/components/_techstack-bucket.scss +2 -2
- package/src/scss/components/_timelines.scss +10 -10
- package/src/scss/form-elements/_form.scss +2 -2
- package/src/scss/form-elements/_login.scss +2 -2
- package/src/scss/layout/_footer.scss +3 -3
- package/src/scss/layout/_header.scss +4 -4
- package/src/scss/layout/_section.scss +5 -5
- package/src/scss/utilities/_text.scss +6 -6
- package/src/assets/favicon/android-chrome-192x192.png +0 -0
- package/src/assets/favicon/android-chrome-512x512.png +0 -0
- package/src/assets/favicon/favicon-16x16.png +0 -0
- 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
|
|
234
|
-
|
|
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: #
|
|
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
|
-
|
|
6
|
-
runtime** with `color-mix()
|
|
7
|
-
whole family - hover tone, translucent backgrounds,
|
|
8
|
-
|
|
9
|
-
|
|
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: #
|
|
18
|
-
--mw-warning-color: #
|
|
19
|
-
--mw-danger-color: #
|
|
20
|
-
--mw-info-color: #
|
|
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: #
|
|
26
|
+
--mw-gray-color: #5a6478;
|
|
23
27
|
|
|
24
|
-
--mw-dark-page-background: #
|
|
25
|
-
--mw-dark-text-color: #
|
|
26
|
-
--mw-light-page-background: #
|
|
27
|
-
--mw-light-text-color: #
|
|
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: #
|
|
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
|
|
43
|
-
| `--mw-primary-color
|
|
44
|
-
| `--mw-primary-
|
|
45
|
-
| `--mw-primary-background
|
|
46
|
-
| `--mw-primary-
|
|
47
|
-
| `--mw-
|
|
48
|
-
| `--mw-
|
|
49
|
-
| `--mw-
|
|
50
|
-
| `--mw-
|
|
51
|
-
| `--mw-
|
|
52
|
-
| `--mw-gray-
|
|
53
|
-
| `--mw-
|
|
54
|
-
| `--mw-
|
|
55
|
-
| `--mw-
|
|
56
|
-
| `--mw-
|
|
57
|
-
| `--mw-
|
|
58
|
-
| `--mw-
|
|
59
|
-
| `--mw-
|
|
60
|
-
| `--mw-
|
|
61
|
-
| `--mw-
|
|
62
|
-
| `--mw-card-
|
|
63
|
-
| `--mw-
|
|
64
|
-
| `--mw-
|
|
65
|
-
| `--mw-
|
|
66
|
-
| `--mw-
|
|
67
|
-
| `--mw-
|
|
68
|
-
| `--mw-
|
|
69
|
-
| `--mw-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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. **
|
|
78
|
-
|
|
79
|
-
|
|
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.
|
|
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: #
|
|
110
|
-
$success-color: #
|
|
111
|
-
$warning-color: #
|
|
112
|
-
$danger-color: #
|
|
113
|
-
$info-color: #
|
|
114
|
-
$gray-color: #
|
|
115
|
-
$dark-background: #
|
|
116
|
-
$dark-text-color: #
|
|
117
|
-
$light-background: #
|
|
118
|
-
$light-text-color: #
|
|
119
|
-
$form-elements-background: #
|
|
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 ~
|
|
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 ~
|
|
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@
|
|
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@
|
|
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: #
|
|
75
|
-
--mw-secondary-color: #
|
|
74
|
+
--mw-primary-color: #0f766e;
|
|
75
|
+
--mw-secondary-color: #b45309;
|
|
76
76
|
|
|
77
77
|
/* status */
|
|
78
|
-
--mw-success-color: #
|
|
79
|
-
--mw-warning-color: #
|
|
80
|
-
--mw-danger-color: #
|
|
81
|
-
--mw-info-color: #
|
|
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: #
|
|
85
|
-
--mw-dark-page-background: #
|
|
86
|
-
--mw-dark-text-color: #
|
|
87
|
-
--mw-light-page-background: #
|
|
88
|
-
--mw-light-text-color: #
|
|
89
|
-
--mw-form-elements-background: #
|
|
90
|
-
|
|
91
|
-
/* text on solid colored
|
|
92
|
-
|
|
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-
|
|
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: #
|
|
118
|
-
$secondary-color: #
|
|
119
|
-
$dark-background: #
|
|
120
|
-
$light-background: #
|
|
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
|
-
<!--
|
|
20
|
-
<link rel="icon" type="image/
|
|
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="
|
|
33
|
-
href="favicon/favicon-
|
|
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
|
-
<!--
|
|
54
|
-
<meta name="
|
|
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 {
|