maverick-wave 5.29.0 → 5.31.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.
- package/README.md +2 -2
- package/maverick-wave.min.css +2 -2
- package/package.json +8 -2
- package/src/scss/components/_avatars.scss +35 -3
- package/src/scss/components/_dropdown.scss +24 -1
- package/src/scss/components/_lang-switch.scss +4 -8
- package/src/scss/components/_modals.scss +33 -5
- package/.claude/settings.local.json +0 -43
- package/.claude/skills/mw-maverick-wave/SKILL.md +0 -532
- package/.claude/skills/mw-maverick-wave/examples/angular-form.md +0 -279
- package/.claude/skills/mw-maverick-wave/examples/angular-list-page.md +0 -309
- package/.claude/skills/mw-maverick-wave/examples/angular-services.md +0 -538
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +0 -530
- package/.claude/skills/mw-maverick-wave/references/components.md +0 -2169
- package/.claude/skills/mw-maverick-wave/references/forms.md +0 -358
- package/.claude/skills/mw-maverick-wave/references/javascript.md +0 -164
- package/.claude/skills/mw-maverick-wave/references/layout.md +0 -764
- package/.claude/skills/mw-maverick-wave/references/theming.md +0 -528
- package/.github/workflows/ci.yml +0 -41
- package/.idea/codeStyles/Project.xml +0 -59
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/maverick-wave.iml +0 -12
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -6
- package/.idea/vcs.xml +0 -6
- package/.prettierignore +0 -8
- package/.prettierrc.json +0 -7
- package/CHANGELOG.md +0 -950
- package/CLAUDE.md +0 -60
- package/gulpfile.js +0 -167
- package/index.html +0 -1730
- package/release.sh +0 -31
- package/scripts/verify.js +0 -252
- 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 +0 -1
- package/src/assets/favicon/site.webmanifest +0 -37
- 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 +0 -24
- package/src/assets/images/gallery-city.svg +0 -49
- package/src/assets/images/gallery-desert.svg +0 -25
- package/src/assets/images/gallery-forest.svg +0 -46
- package/src/assets/images/gallery-lake.svg +0 -26
- package/src/assets/images/gallery-mountain.svg +0 -19
- package/src/assets/images/gallery-ocean.svg +0 -26
- package/src/assets/images/gallery-oldtown.svg +0 -41
- package/src/assets/images/gallery-snow.svg +0 -39
- package/src/assets/images/photo-balloon.svg +0 -35
- package/src/assets/images/photo-forest-path.svg +0 -31
- package/src/assets/images/photo-lighthouse.svg +0 -42
- package/src/assets/images/photo-palm.svg +0 -27
- package/src/assets/images/photo-peak.svg +0 -27
- package/src/assets/images/photo-tower.svg +0 -34
- package/src/assets/images/photo-waterfall.svg +0 -32
- package/src/assets/images/slider-field.svg +0 -124
- package/src/assets/images/slider-forest.svg +0 -33
- package/src/assets/images/slider-lake.svg +0 -35
- package/src/assets/images/slider-mountains.svg +0 -29
- package/src/assets/images/slider-trees.svg +0 -41
- package/src/assets/images/story-aurora.svg +0 -36
- package/src/assets/images/story-beach.svg +0 -34
- package/src/assets/images/story-stars.svg +0 -35
- package/src/assets/images/tile-analytics.svg +0 -22
- package/src/assets/images/tile-cloud.svg +0 -19
- package/src/assets/images/tile-ecommerce.svg +0 -14
- package/src/assets/images/tile-enterprise.svg +0 -22
- package/src/assets/images/tile-marketing.svg +0 -16
- package/src/assets/media/demo-chime.wav +0 -0
- package/src/assets/media/story-sunrise.jpg +0 -0
- package/src/assets/media/story-sunrise.mp4 +0 -0
- package/src/partials/accordions-container.html +0 -179
- package/src/partials/alerts-container.html +0 -151
- package/src/partials/announcement-container.html +0 -67
- package/src/partials/avatars-container.html +0 -229
- package/src/partials/badges-container.html +0 -114
- package/src/partials/blog-posts-container.html +0 -158
- package/src/partials/breadcrumbs-container.html +0 -126
- package/src/partials/button-bar-container.html +0 -175
- package/src/partials/buttons-container.html +0 -272
- package/src/partials/calendar-container.html +0 -203
- package/src/partials/cards-container.html +0 -727
- package/src/partials/code-container.html +0 -194
- package/src/partials/colors-container.html +0 -263
- package/src/partials/coming-soon-container.html +0 -10
- package/src/partials/contact-container.html +0 -85
- package/src/partials/content-slider-container.html +0 -36
- package/src/partials/divider-container.html +0 -70
- package/src/partials/documentation-container.html +0 -204
- package/src/partials/dropdown-container.html +0 -119
- package/src/partials/empty-state-container.html +0 -79
- package/src/partials/feed-container.html +0 -506
- package/src/partials/footer-container.html +0 -113
- package/src/partials/form-container.html +0 -262
- package/src/partials/form-elements-container.html +0 -616
- package/src/partials/form-field-container.html +0 -166
- package/src/partials/gallery-container.html +0 -62
- package/src/partials/get-started-container.html +0 -423
- package/src/partials/grid-container.html +0 -191
- package/src/partials/header-container.html +0 -69
- package/src/partials/header-utilities-container.html +0 -331
- package/src/partials/highlights-container.html +0 -71
- package/src/partials/history-container.html +0 -67
- package/src/partials/home-container.html +0 -31
- package/src/partials/html-lists-container.html +0 -63
- package/src/partials/info-container.html +0 -104
- package/src/partials/input-group-container.html +0 -299
- package/src/partials/item-lists-container.html +0 -368
- package/src/partials/kanban-container.html +0 -459
- package/src/partials/kbd-container.html +0 -63
- package/src/partials/leader-row-container.html +0 -139
- package/src/partials/login-container.html +0 -65
- package/src/partials/lunch-menu-container.html +0 -341
- package/src/partials/media-container.html +0 -27
- package/src/partials/meta-info-container.html +0 -21
- package/src/partials/modals-container.html +0 -199
- package/src/partials/mosaic-container.html +0 -173
- package/src/partials/page-header-container.html +0 -78
- package/src/partials/pagination-container.html +0 -64
- package/src/partials/palette-container.html +0 -480
- package/src/partials/panels-container.html +0 -126
- package/src/partials/parallax-container.html +0 -147
- package/src/partials/portrait-gallery-container.html +0 -175
- package/src/partials/preview-container.html +0 -136
- package/src/partials/pricing-container.html +0 -523
- package/src/partials/progress-container.html +0 -230
- package/src/partials/prose-container.html +0 -43
- package/src/partials/ratings-container.html +0 -104
- package/src/partials/section-head-container.html +0 -77
- package/src/partials/segmented-container.html +0 -66
- package/src/partials/skeleton-container.html +0 -87
- package/src/partials/spinners-container.html +0 -96
- package/src/partials/stepper-container.html +0 -111
- package/src/partials/stories-container.html +0 -182
- package/src/partials/tables-container.html +0 -309
- package/src/partials/tabs-container.html +0 -290
- package/src/partials/tags-container.html +0 -242
- package/src/partials/techstack-bucket-container.html +0 -187
- package/src/partials/testimonials-container.html +0 -88
- package/src/partials/tiles-container.html +0 -247
- package/src/partials/timelines-container.html +0 -196
- package/src/partials/typography-container.html +0 -74
- package/src/partials/utilities-container.html +0 -553
|
@@ -1,528 +0,0 @@
|
|
|
1
|
-
# Theming, tokens & partial imports
|
|
2
|
-
|
|
3
|
-
## The model
|
|
4
|
-
|
|
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
|
-
Writing those tokens on `<html>` at runtime is how a palette is swapped without
|
|
13
|
-
a reload. It repaints the same breadth the theme flip does and needs the same
|
|
14
|
-
guard against a page-wide interpolation - see **Light & dark** below.
|
|
15
|
-
|
|
16
|
-
Browser floor for that: `color-mix()` **and** `oklch(from ...)` - Chrome 119+,
|
|
17
|
-
Safari 16.4+, Firefox 128+. The same range is declared as `browserslist` in
|
|
18
|
-
`package.json`, so Autoprefixer and cssnano target exactly it.
|
|
19
|
-
|
|
20
|
-
```css
|
|
21
|
-
/* loaded after maverick-wave.min.css */
|
|
22
|
-
:root {
|
|
23
|
-
--mw-primary-color: #0f766e; /* also retunes hover, backgrounds, border accent */
|
|
24
|
-
--mw-secondary-color: #f39c12;
|
|
25
|
-
|
|
26
|
-
--mw-success-color: #157f4b;
|
|
27
|
-
--mw-warning-color: #bda817;
|
|
28
|
-
--mw-danger-color: #c42b1c;
|
|
29
|
-
--mw-info-color: #14618f;
|
|
30
|
-
|
|
31
|
-
--mw-gray-color: #5a6478;
|
|
32
|
-
|
|
33
|
-
--mw-dark-page-background: #171f30;
|
|
34
|
-
--mw-dark-text-color: #e8ecf1;
|
|
35
|
-
--mw-light-page-background: #f2f5f8;
|
|
36
|
-
--mw-light-text-color: #0c1119;
|
|
37
|
-
|
|
38
|
-
--mw-form-elements-background: #f4f7fb;
|
|
39
|
-
|
|
40
|
-
/* text on every solid coloured surface, and the one token that cannot be
|
|
41
|
-
derived: light brand colours need a dark label, dark ones a light label */
|
|
42
|
-
--mw-accent-text-color: #ffffff;
|
|
43
|
-
/* per colour override of that label, for a palette that does not sit on one
|
|
44
|
-
side of the lightness scale */
|
|
45
|
-
--mw-primary-accent-text-color: #0b0f0a;
|
|
46
|
-
|
|
47
|
-
--mw-font-family-base: 'Inter', sans-serif;
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Which token for what
|
|
52
|
-
|
|
53
|
-
| Token | Role |
|
|
54
|
-
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
-
| `--mw-primary-color` | Brand colour as a **fill**: primary buttons, table headers, bars, badges - the label on top is `--mw-primary-accent-text-color` |
|
|
56
|
-
| `--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 |
|
|
57
|
-
| `--mw-primary-color-hover` | Solid hover surface (derived: base + `$hover-shift` black, in both themes) |
|
|
58
|
-
| `--mw-primary-background` | 20% tint - focus halo, alert/badge/tag surface, scrollbar tracks |
|
|
59
|
-
| `--mw-primary-background-hover` | 45% tint - row and list hover |
|
|
60
|
-
| `--mw-primary-info-background` | Alias of `--mw-primary-background`, so a component can interpolate one name across all six colours |
|
|
61
|
-
| `--mw-border-accent` | Translucent accent **line**: panel rules, dividers, tab underlines. Theme-aware (70% of `--mw-*-text-color`) |
|
|
62
|
-
| `--mw-secondary-*` | Same set for the second brand colour |
|
|
63
|
-
| `--mw-success/warning/danger/info-color` | Status colours, each with `-text-color`, `-color-hover`, `-info-background`, `-info-background-hover` |
|
|
64
|
-
| `--mw-accent-text-color` | Text on any solid coloured surface (buttons, table/panel headers, badges, stepper dots) |
|
|
65
|
-
| `--mw-primary-accent-text-color` | Per colour override of that label. Same for `secondary`, `success`, `warning`, `danger`, `info`. Defaults to `--mw-accent-text-color`, so set one only when a colour needs the opposite label - a neon primary on a dark palette |
|
|
66
|
-
| `--mw-gray-color` | Neutral foreground: muted icons, tooltips |
|
|
67
|
-
| `--mw-gray-background` | Subtle neutral surface (20% alpha): zebra rows, disabled fields, tracks, skeletons |
|
|
68
|
-
| `--mw-corner-accent` | The accent arc on the two round corners of every card, panel, modal and tile, and on the top-right corner of an avatar. Theme-aware: the full `--mw-*-text-color` tone in the dark theme, held to 80% in the light one, where the same blue carries far more contrast on a near-white card. Restyle it to recolour the signature, or `mw-corner-plain` on a single box to drop it |
|
|
69
|
-
| `--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 |
|
|
70
|
-
| `--mw-overlay-background` | Heavy scrim (60%) behind modals and blocking spinners |
|
|
71
|
-
| `--mw-page-background`, `--mw-card-background`, `--mw-footer-background`, `--mw-border`, `--mw-shadow`, `--mw-text-color`, `--mw-text-muted-color`, `--mw-hero-image-filter` | The **active theme** - aliases pointing at the `--mw-dark-*` or `--mw-light-*` set |
|
|
72
|
-
| `--mw-header-*` | Header chrome: `background`, `text-color`, `navbar-list-color`, `navbar-list-active-color`, `burgerbutton-color`, `burgerbutton-open-color`, `border` - dark in both themes. The two burger tokens default to the primary and secondary label ink, because the burger sits on those two surfaces |
|
|
73
|
-
| `--mw-form-elements-background`, `--mw-form-elements-color` | Form controls stay light in both themes and therefore have their own pair |
|
|
74
|
-
| `--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 |
|
|
75
|
-
| `--mw-hero-background`, `--mw-hero-text-color` | Hero image (`url(...)`) and the ink on it. Fixed across themes - the photo does not change with the theme, so its text must not either. Defaults to the light end of the palette |
|
|
76
|
-
| `--mw-transition` | Hover and focus states - an explicit paint-only property list at `--mw-duration-base`, never `all` |
|
|
77
|
-
| `--mw-card-img-height` | Per-card image height (default `210px`; `mw-card-lg`/`-xl` set it to 340px/480px, 260px/340px below `sm`) |
|
|
78
|
-
| `--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 |
|
|
79
|
-
| `--mw-card-addon-text-color` | Label on that badge/ribbon; the `mw-card-addon-*` classes point it at the matching `--mw-*-accent-text-color` |
|
|
80
|
-
| `--mw-progress-ink` | Label inside `mw-progress-inline-label`; the `mw-progress-*` colour classes point it at the matching `--mw-*-accent-text-color` |
|
|
81
|
-
| `--mw-table-scroll-height` | Per-table height cap for `mw-table-responsive-scroll` |
|
|
82
|
-
| `--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`) |
|
|
83
|
-
| `--mw-container-gutter`, `--mw-container-width` | Page gutter of `mw-container` (fluid `clamp(1rem, 4.2vw + 0.5rem, 4rem)`, never below the safe-area inset) and the width derived from it (`min(1200px, 100% - 2 * gutter)`) |
|
|
84
|
-
| `--mw-section-padding-block` | Top/bottom rhythm of `mw-section` (3.3rem, stepping down to 2.5rem below `md` and 1.75rem below `sm`) |
|
|
85
|
-
| `--mw-section-padding-fluid` | The fluid alternative to the value above - 1.75rem on a phone up to 5.5rem at `xl`. Not applied by itself: set `--mw-section-padding-block: var(--mw-section-padding-fluid)` |
|
|
86
|
-
| `--mw-section-padding-compact`, `--mw-section-padding-airy` | The two presets, as tokens so the phone steps reach them - point `--mw-section-padding-block` at one |
|
|
87
|
-
| `--mw-section-head-step` | One step of the head rhythm, derived from `--mw-section-padding-block`. Every measure in a head and around a subtitle is a multiple of it, so a spacing preset moves them all |
|
|
88
|
-
| `--mw-section-nav-height` | Height the sticky `mw-section-nav` reserves (3.75rem). A page carrying a strip adds it to `scroll-padding-top` itself, through the offset token below |
|
|
89
|
-
| `--mw-announcement-offset`, `--mw-section-nav-offset` | What each layer of sticky chrome below the header adds to `scroll-padding-top`. `0px` until the component switches it on, so a page with both a ribbon and a strip reserves for both. For a sticky bar of your own, override `scroll-padding-top` on `html` - the calc names these two |
|
|
90
|
-
| `--mw-root-font-size` | Percentage the whole rem scale is built on (`100%`). Type, spacing and control heights move with it; px breakpoints do not |
|
|
91
|
-
| `--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 |
|
|
92
|
-
| `--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` |
|
|
93
|
-
| `--mw-elevation-1` … `-5` | Every shadow in the framework. Two layers per level - contact plus ambient. Never write a `box-shadow` by hand: a hand-rolled one is the wrong colour in one of the two themes |
|
|
94
|
-
| `--mw-shadow-near`, `--mw-shadow-far` | The two tones the ramp above is mixed from, per theme |
|
|
95
|
-
| `--mw-transition-fast` | The same property list at `--mw-duration-fast` - for a state change that should feel instant under the pointer |
|
|
96
|
-
| `--mw-duration-instant\|fast\|base\|slow\|slower` | 110 / 180 / 300 / 520 / 900ms. Anything built on these is covered by `prefers-reduced-motion` for free |
|
|
97
|
-
| `--mw-duration-zoom` | 650ms, for a large surface actually travelling - an image scaling inside a card, a slider track |
|
|
98
|
-
| `--mw-ease-out`, `--mw-ease-in-out`, `--mw-ease-spring` | Things arriving (the default) / A to B and back / a pop |
|
|
99
|
-
| `--mw-control-height-sm\|·\|lg`, `--mw-control-font-sm\|·\|lg`, `--mw-control-line-height` | One size scale for input, select, textarea and button, so a field and the button beside it line up by construction |
|
|
100
|
-
| `--mw-focus-ring-width\|offset\|color` | The keyboard focus ring |
|
|
101
|
-
| `--mw-focus-halo-size\|opacity` | The soft ring a form field gets instead of a hard outline |
|
|
102
|
-
| `--mw-internal-theme-mode` | Read-only: what `$mw-theme-mode` was compiled to |
|
|
103
|
-
|
|
104
|
-
`--mw-container-gutter`, `--mw-container-width` and `--mw-section-padding-block`
|
|
105
|
-
are the knobs a good default cannot settle, because the right answer differs per
|
|
106
|
-
project: what reads as generous on a landing page costs visible content in an
|
|
107
|
-
application with a sticky header. Override the gutter, not the width - the width
|
|
108
|
-
is derived from it and keeps the 1200px cap.
|
|
109
|
-
|
|
110
|
-
Two rules that prevent most colour bugs:
|
|
111
|
-
|
|
112
|
-
1. **Fill or ink.** A colour that _fills_ something is `--mw-*-color`; a colour
|
|
113
|
-
_drawn on_ a theme surface - text, icon, focus ring, accent border, thin
|
|
114
|
-
divider - is `--mw-*-text-color`. A colour picked to carry a label is by
|
|
115
|
-
definition unreadable on the page it sits on, so ink is always the
|
|
116
|
-
`-text-color` variant. For a generic rule or outline use `--mw-border-accent`
|
|
117
|
-
or `--mw-border`.
|
|
118
|
-
2. **`--mw-text-muted-color` is only for text on theme surfaces** (cards, page
|
|
119
|
-
background) - it follows the theme. It is a true gray with `$muted-tint`
|
|
120
|
-
(23%) of the primary mixed in, not a stepped-back text colour, so it stays
|
|
121
|
-
gray no matter how tinted the palette is. On a colour surface that stays the same
|
|
122
|
-
in both themes it is always wrong: use `--mw-*-accent-text-color`, or
|
|
123
|
-
`opacity` for a disabled look.
|
|
124
|
-
|
|
125
|
-
3. **Elevation, motion and focus are tokens too.** `var(--mw-elevation-1..5)`
|
|
126
|
-
for any shadow, `var(--mw-transition)` / `var(--mw-transition-fast)` for a
|
|
127
|
-
hover or focus state, `var(--mw-duration-*)` with `var(--mw-ease-*)` for
|
|
128
|
-
anything else, and `--mw-focus-ring-*` / `--mw-focus-halo-*` for the ring.
|
|
129
|
-
A hand-rolled shadow is the wrong colour in one of the two themes: the dark
|
|
130
|
-
theme's shadow is a light rim over a dark contact layer, not a black blur.
|
|
131
|
-
A hand-rolled duration also opts out of `prefers-reduced-motion`, which works
|
|
132
|
-
by turning the duration tokens down.
|
|
133
|
-
|
|
134
|
-
4. **The header has two knobs of its own.** `$header-surface` sets how dark the
|
|
135
|
-
bar sits under the primary colour (lower is darker); `$header-active-tint`
|
|
136
|
-
sets how far the active navbar link is lifted off it (lower is a stronger,
|
|
137
|
-
more saturated blue, higher is paler with more contrast against the bar).
|
|
138
|
-
Both are `!default` in `abstracts/_variables.scss`.
|
|
139
|
-
|
|
140
|
-
## Light & dark
|
|
141
|
-
|
|
142
|
-
- Every theme token is declared once on `:root` as `light-dark(light, dark)`.
|
|
143
|
-
Which half applies is decided by `color-scheme` on the element that **uses**
|
|
144
|
-
the token, and `:root` carries `color-scheme: light dark` - so a page follows
|
|
145
|
-
the OS until someone chooses otherwise.
|
|
146
|
-
- `mw-theme-light` and `mw-theme-dark` on `<body>` are that choice. They set
|
|
147
|
-
little more than `color-scheme`, and every token follows. `mw-theme-dark` is
|
|
148
|
-
not redundant: without it, a reader who picks dark on a machine set to light
|
|
149
|
-
would be pulled straight back to the OS preference.
|
|
150
|
-
- Chrome 119-122 and Safari 16.4-17.4 are in the browserslist but predate
|
|
151
|
-
`light-dark()`. `base/_base.scss` keeps the old route for them behind
|
|
152
|
-
`@supports` - dark on `:root`, light by class, no OS tracking.
|
|
153
|
-
- `--mw-hero-image-filter` is the one theme value that is not a colour and so
|
|
154
|
-
cannot ride along; it follows `prefers-color-scheme` instead.
|
|
155
|
-
- Card, footer and border are derived from the page background by scaling its
|
|
156
|
-
OKLch lightness and chroma by one factor. A card steps **away from the text
|
|
157
|
-
colour** - darker than the page in the dark theme, lighter in the light one.
|
|
158
|
-
A near-black `--mw-dark-page-background` leaves no headroom underneath and
|
|
159
|
-
cards collapse into it; keep it around OKLch lightness 0.24.
|
|
160
|
-
- The card and footer factors are `!default` SCSS knobs, so the distance
|
|
161
|
-
between a card and the page is one number per theme: `$card-surface-dark`
|
|
162
|
-
(0.85), `$card-surface-light` (1.05), `$footer-surface-dark` (0.75),
|
|
163
|
-
`$footer-surface-light` (0.95). Below 1 steps toward black, above 1 toward
|
|
164
|
-
white - read 0.85 as "the card sits at 85% of the page's lightness". Toward 1
|
|
165
|
-
is a flatter, borderless look; further apart makes cards read as raised
|
|
166
|
-
panels. Keep the footer further out than the card in the dark theme and on
|
|
167
|
-
the other side in the light one, or the footer stops reading as chrome. The
|
|
168
|
-
border factor is not configurable - it runs against the card by design.
|
|
169
|
-
- Footer chrome and form controls deliberately stay dark/light respectively in
|
|
170
|
-
both themes, and so does the header - see the next point for where its colour
|
|
171
|
-
comes from.
|
|
172
|
-
- The header bar is **not** part of that surface stack. It is
|
|
173
|
-
`--mw-primary-color` darkened straight toward black - `$header-surface` (14%)
|
|
174
|
-
is how much of the colour survives, the same shade ramp a colour tool prints.
|
|
175
|
-
It sits well past the bottom of that ramp so the hue reads as a tint on
|
|
176
|
-
near-black, not as a colour of its own. That matters for a light-only project:
|
|
177
|
-
while the bar was derived from the dark page background, its colour was frozen
|
|
178
|
-
at the framework default nobody had configured. Every `--mw-header-*` token
|
|
179
|
-
now follows the primary, and each is still overridable on its own.
|
|
180
|
-
- The ink on the bar is mixed off the same primary: `--mw-header-text-color` is
|
|
181
|
-
`tint(92%)` and `--mw-header-navbar-list-active-color` - the current page and
|
|
182
|
-
the hover tone both - is `tint(35%)`, so the active item reads as the brand
|
|
183
|
-
colour rather than a washed-out pastel. Do not reach for
|
|
184
|
-
`--mw-primary-text-color` here: that bound is calibrated against the page
|
|
185
|
-
background and lets a mid-dark primary through untouched, which on this much
|
|
186
|
-
darker bar lands around 2:1. At the default bar the active tone clears 5:1 on
|
|
187
|
-
every palette; a near-black primary is the one case that falls short (~3.5:1,
|
|
188
|
-
the bar is near-black too) - override the token there.
|
|
189
|
-
- Raising `$header-surface` for a lighter bar eats into that margin, since only
|
|
190
|
-
the bar moves and the ink stays put. Past roughly 30% check the active tone,
|
|
191
|
-
or move it down with the bar.
|
|
192
|
-
- Persisting the choice, the toggle UI and the initial class are the
|
|
193
|
-
application's job in a SPA (`examples/angular-services.md`). The shipped JS
|
|
194
|
-
does it for static pages using `localStorage` under the key `mw-theme`. With
|
|
195
|
-
nothing stored it takes the OS preference and keeps tracking it live, so
|
|
196
|
-
changing the system theme moves the page until the reader picks a side.
|
|
197
|
-
- **Suppress transitions while the class flips.** Colour changes on nearly every
|
|
198
|
-
element at once, and the shared `--mw-transition` turns that into thousands of
|
|
199
|
-
concurrent animations - on a documentation-sized page it is seconds of blocked
|
|
200
|
-
style and layout. `mw-theme-switching` on `<html>` kills them for the flip; the
|
|
201
|
-
forced reflow between the two class changes is what commits the new colours
|
|
202
|
-
before transitions come back.
|
|
203
|
-
|
|
204
|
-
```ts
|
|
205
|
-
const root = document.documentElement;
|
|
206
|
-
|
|
207
|
-
root.classList.add('mw-theme-switching');
|
|
208
|
-
document.body.classList.toggle('mw-theme-light', isLight);
|
|
209
|
-
document.body.classList.toggle('mw-theme-dark', !isLight);
|
|
210
|
-
void root.offsetHeight; // commit the new colours with transitions off
|
|
211
|
-
root.classList.remove('mw-theme-switching');
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Site-wide variants
|
|
215
|
-
|
|
216
|
-
Fifteen classes on `<html>` and six custom properties retune the whole look
|
|
217
|
-
without a rebuild. They stack, and none of them need a class per element. The
|
|
218
|
-
showcase at https://maverick-wave.m1well.com has a picker for the set, and its
|
|
219
|
-
URL carries the choice - a link is how a look gets agreed on before it is built.
|
|
220
|
-
|
|
221
|
-
| Class | Effect |
|
|
222
|
-
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
223
|
-
| `mw-corners-even` | Drops the surface signature - every card, panel and modal becomes an evenly rounded `radius('md')` box |
|
|
224
|
-
| `mw-accent-single` | `--mw-secondary-color` follows the primary; `mw-btn-secondary` turns outline so the two stay apart |
|
|
225
|
-
| `mw-shadows-flat` | Elevation 1-3 to `none`. The dropdown (4) and the modal (5) keep their shadow |
|
|
226
|
-
| `mw-surfaces-flush` | Card, panel and footer background drop to the page colour and the border is redrawn from the ink, because the old one is a neighbouring shade of a surface that is now the page |
|
|
227
|
-
| `mw-hover-static` | No hover travels - lifts, image zooms and slides go. Colour and border still respond |
|
|
228
|
-
| `mw-scroll-static` | No scroll entrance - `mw-reveal` and `mw-reveal-stagger` blocks sit where they land |
|
|
229
|
-
| `mw-sections-plain` | The diagonal hatch behind `mw-section-alternate` collapses into the page colour |
|
|
230
|
-
| `mw-headings-caps` | `h1`-`h3` in capitals with 0.045em tracking |
|
|
231
|
-
| `mw-links-underline` | `mw-link`, `mw-link-muted` and `mw-btn-link` carry their underline at rest. The hover signal moves to the stroke, which thickens to 3px - `mw-link` has no colour change of its own |
|
|
232
|
-
| `mw-btn-pill` | `mw-btn` fully rounded. Form fields keep their own radius |
|
|
233
|
-
| `mw-btn-square` | `mw-btn` to `border-radius: 0`. The other end of the same axis, and unlike `--mw-radius-scale: 0` it leaves the rest of the page rounded |
|
|
234
|
-
| `mw-btn-glass` | Filled buttons become tinted glass: translucent wash, vertical ramp, specular top edge. No `backdrop-filter` - it would trap a fixed-position tooltip inside the button |
|
|
235
|
-
| `mw-btn-tactile` | The four solid variants stand on a 3px edge mixed toward black and travel its full height on `:active`. Outline, ghost and link have no fill to darken and are untouched |
|
|
236
|
-
| `mw-density-compact` | Card and panel padding and the three control heights drop one step down the spacing scale. Type is untouched - `--mw-root-font-size` is the switch that scales everything together |
|
|
237
|
-
| `mw-density-roomy` | The same one step up |
|
|
238
|
-
|
|
239
|
-
| Property | Effect |
|
|
240
|
-
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
241
|
-
| `--mw-radius-scale` | Multiplies the whole radius scale - `0` squares everything off |
|
|
242
|
-
| `--mw-root-font-size` | Percentage on `html`. The scale is rem, so type, padding and control heights move together; breakpoints are px and stay put |
|
|
243
|
-
| `--mw-font-family-heading` | Headline typeface; body copy is untouched |
|
|
244
|
-
| `--mw-container-width` | Where the content stops growing |
|
|
245
|
-
| `--mw-section-padding-block` | Air above and below each section |
|
|
246
|
-
| `--mw-section-padding-fluid` | The same, but growing with the screen - point the line above at it |
|
|
247
|
-
| `--mw-section-padding-compact`, `--mw-section-padding-airy` | A tighter and an airier fixed rhythm - point the line above at one |
|
|
248
|
-
| `--mw-section-head-step` | Scales every gap in a section head and around a subtitle at once |
|
|
249
|
-
| `--mw-motion-scale` | Multiplies all six duration tokens - `0.6` brisk, `1.6` relaxed. `prefers-reduced-motion` still overrides it |
|
|
250
|
-
|
|
251
|
-
**Writing your own.** A variant that retunes a _theme-bound_ token - anything in
|
|
252
|
-
the dark/light maps - cannot be written on `:root` alone: `mw-theme-light`
|
|
253
|
-
re-declares those on `<body>`, which shadows the root value for the entire
|
|
254
|
-
subtree and the switch does nothing in light mode. Target both:
|
|
255
|
-
|
|
256
|
-
```scss
|
|
257
|
-
:root.my-variant,
|
|
258
|
-
:root.my-variant .mw-theme-light {
|
|
259
|
-
--mw-card-background: var(--mw-page-background);
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
`--mw-elevation-1..5` are the exception and need only `:root`: the ramp is one
|
|
264
|
-
set for both themes and reaches the theme through `--mw-shadow-near/-far`, so
|
|
265
|
-
there is no second declaration further down the tree to shadow it.
|
|
266
|
-
|
|
267
|
-
The same trap the other way round: never copy a theme alias _into_ a token on
|
|
268
|
-
`:root` (`--mw-x: var(--mw-page-background)`), because up there it still holds
|
|
269
|
-
the dark value. Write that rule on the element instead.
|
|
270
|
-
|
|
271
|
-
## SCSS configuration
|
|
272
|
-
|
|
273
|
-
Only `@use ... with (...)` works - a plain assignment before the `@use` has no
|
|
274
|
-
effect, because the root colours are declared with `!default`.
|
|
275
|
-
|
|
276
|
-
```scss
|
|
277
|
-
@use 'maverick-wave/src/scss/main' with (
|
|
278
|
-
$mw-theme-mode: 'switchable',
|
|
279
|
-
// 'switchable' | 'dark' | 'light'
|
|
280
|
-
$primary-color: #0f766e,
|
|
281
|
-
$secondary-color: #b45309,
|
|
282
|
-
$success-color: #15803d,
|
|
283
|
-
$warning-color: #a16207,
|
|
284
|
-
$danger-color: #b91c1c,
|
|
285
|
-
$info-color: #0e7490,
|
|
286
|
-
$gray-color: #64748b,
|
|
287
|
-
$dark-background: #172127,
|
|
288
|
-
$dark-text-color: #e8eef0,
|
|
289
|
-
$light-background: #f2f6f7,
|
|
290
|
-
$light-text-color: #172127,
|
|
291
|
-
$form-elements-background: #f5f9fa,
|
|
292
|
-
$accent-text-color: #f2fafa,
|
|
293
|
-
// the derivation knobs, all optional
|
|
294
|
-
$hover-shift: 15%,
|
|
295
|
-
$ink-lightness-dark: 0.68,
|
|
296
|
-
$ink-lightness-light: 0.55,
|
|
297
|
-
$muted-tint: 12%,
|
|
298
|
-
// the surface stack - distance of card and footer from the page
|
|
299
|
-
$card-surface-dark: 0.85,
|
|
300
|
-
$card-surface-light: 1.05,
|
|
301
|
-
$footer-surface-dark: 0.75,
|
|
302
|
-
$footer-surface-light: 0.95,
|
|
303
|
-
// the header bar - how much of the primary survives darkening toward black
|
|
304
|
-
$header-surface: 16%,
|
|
305
|
-
// how far the active navbar link sits off the primary colour - lower is a
|
|
306
|
-
// stronger, more saturated blue, higher is paler with more contrast
|
|
307
|
-
$header-active-tint: 25%,
|
|
308
|
-
$mw-hero-image: url('/assets/hero.jpg'),
|
|
309
|
-
// a pattern layer over it, for a hero that parallaxes - see mw-parallax-pattern
|
|
310
|
-
$mw-hero-pattern: repeating-linear-gradient(
|
|
311
|
-
to bottom,
|
|
312
|
-
rgb(255 255 255 / 5%) 0 1px,
|
|
313
|
-
transparent 1px 38px
|
|
314
|
-
),
|
|
315
|
-
// ink on that image - fixed, because the image is
|
|
316
|
-
$mw-hero-text-color: var(--mw-dark-text-color),
|
|
317
|
-
// per-theme treatment of that image - a filter, not an overlay, so the two
|
|
318
|
-
// themes differ visibly even when the photo is already dark
|
|
319
|
-
$hero-filter-dark: brightness(0.5),
|
|
320
|
-
$hero-filter-light: brightness(1.15) saturate(1.2),
|
|
321
|
-
$font-family-base: (
|
|
322
|
-
'Inter',
|
|
323
|
-
sans-serif,
|
|
324
|
-
),
|
|
325
|
-
$font-family-heading: (
|
|
326
|
-
'Inter',
|
|
327
|
-
sans-serif,
|
|
328
|
-
),
|
|
329
|
-
$font-family-mono: (
|
|
330
|
-
'JetBrains Mono',
|
|
331
|
-
monospace,
|
|
332
|
-
)
|
|
333
|
-
);
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
The three font stacks are the one place where the parentheses matter: a
|
|
337
|
-
comma-separated stack is a Sass list, and without them the commas would read as
|
|
338
|
-
further arguments to `with (...)`. A single family (`$font-family-base: 'Inter'`)
|
|
339
|
-
needs none.
|
|
340
|
-
|
|
341
|
-
`$mw-theme-mode: 'dark'` or `'light'` compiles a single theme - the other set of
|
|
342
|
-
variables is omitted and `mw-theme-light` has no effect. The theme toggle
|
|
343
|
-
component reads `--mw-internal-theme-mode` and disables itself.
|
|
344
|
-
|
|
345
|
-
Overriding a value that is not on the list above is done in CSS afterwards -
|
|
346
|
-
they are all `var()` references anyway:
|
|
347
|
-
|
|
348
|
-
```scss
|
|
349
|
-
@use 'maverick-wave/src/scss/main' with (
|
|
350
|
-
$primary-color: #0f766e
|
|
351
|
-
);
|
|
352
|
-
|
|
353
|
-
:root {
|
|
354
|
-
/* break out of the derived scale for one token */
|
|
355
|
-
--mw-primary-background-hover: color-mix(
|
|
356
|
-
in srgb,
|
|
357
|
-
var(--mw-primary-color) 35%,
|
|
358
|
-
transparent
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
## Mixins and functions
|
|
364
|
-
|
|
365
|
-
`@use 'maverick-wave/src/scss/abstracts' as *` brings the whole set in - the
|
|
366
|
-
tokens, the functions and the mixins. They exist on the SCSS path only; the
|
|
367
|
-
compiled CSS carries none of them, so a CDN project cannot reach them.
|
|
368
|
-
|
|
369
|
-
Functions read the maps: `spacing('4')`, `font-size('lg')`,
|
|
370
|
-
`font-weight('bold')`, `radius('md')`, `breakpoint('md')`, `color('primary-color')`,
|
|
371
|
-
`z-index('menu')`, `motion('base')`.
|
|
372
|
-
|
|
373
|
-
```scss
|
|
374
|
-
@use 'maverick-wave/src/scss/abstracts' as *;
|
|
375
|
-
|
|
376
|
-
.hero-title {
|
|
377
|
-
font-size: fluid(1.95rem, 4.2rem, $to: 'xl');
|
|
378
|
-
margin-bottom: spacing('6');
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
.my-icon-button {
|
|
382
|
-
@include touch-floor;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
.my-dot {
|
|
386
|
-
@include hit-area(7px);
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
- `fluid($min, $max, $from: 'xs', $to: 'md')` - a clamp between two sizes. Each
|
|
391
|
-
end is a key of `$font-sizes` or a plain rem/px length, so a hero that does
|
|
392
|
-
not sit on the scale still gets one. The rem term is what the vw-only form
|
|
393
|
-
throws away: a size in vw alone ignores the reader's font size and stops
|
|
394
|
-
responding to zoom. The default range ends at `md` because that is where the
|
|
395
|
-
stepped heading sizes it replaces reached their largest value - a headline
|
|
396
|
-
that should keep growing passes `$to: 'xl'`.
|
|
397
|
-
- `fluid-container($min, $max, $from, $to)` - the same ramp measured against the
|
|
398
|
-
container instead of the viewport, so the slope lands in `cqi`. For anything
|
|
399
|
-
inside a `@container` block: sizing there off `vw` hands a 440px card in a
|
|
400
|
-
1400px window the measurements a 900px card was drawn for. The endpoints are
|
|
401
|
-
container widths, not breakpoint names, because a container has none.
|
|
402
|
-
- `media-up($bp)` / `media-down($bp)` - the `$breakpoints` map as range syntax,
|
|
403
|
-
`width >= bp` and `width < bp`, so the two never overlap at the breakpoint.
|
|
404
|
-
`media-up` is the direction the framework is written in: the base block is the
|
|
405
|
-
phone and each breakpoint adds to it. `media-down` is for a rule that sets what
|
|
406
|
-
the base never sets - turned around it would hard-wire an inherited value - and
|
|
407
|
-
for a narrow layout that costs more properties than the wide one.
|
|
408
|
-
- `touch-context($bp: 'md')` - coarse pointer _or_ narrow viewport. Every
|
|
409
|
-
target-size rule in the framework hangs under it; put your own control under
|
|
410
|
-
the same condition instead of guessing it.
|
|
411
|
-
- `touch-floor($size: 2.75rem)` - that condition plus a `min-height`, and it
|
|
412
|
-
takes a `@content` block for whatever else the control needs there. Not for a
|
|
413
|
-
link inside a sentence: WCAG 2.5.8 exempts those, and a `min-height` there
|
|
414
|
-
pushes the lines of the paragraph apart.
|
|
415
|
-
- `hit-area($grow: 6px)` - grows the hit area through `::after` without touching
|
|
416
|
-
the silhouette, for a control whose size is the design. Neighbours need a gap
|
|
417
|
-
of at least twice `$grow`, or two hit areas overlap and a tap lands on the one
|
|
418
|
-
next door. It takes `::after`, so it is out for anything carrying a
|
|
419
|
-
`data-tooltip`.
|
|
420
|
-
- `hover` / `hover-move` - a hover effect that only runs where hovering is real.
|
|
421
|
-
See the pitfall on latching `:hover`.
|
|
422
|
-
- `focus-ring`, `focus-ring-inset`, `field-focus`, `focus-halo` - the ring, in
|
|
423
|
-
its four shapes.
|
|
424
|
-
- `truncate`, `scrollbar`, `surface`, `corner-accent` - the shared silhouette
|
|
425
|
-
and the one-line helpers the components use.
|
|
426
|
-
|
|
427
|
-
## Overriding a component
|
|
428
|
-
|
|
429
|
-
Tokens cover colour and rhythm; for anything else write a normal rule. The
|
|
430
|
-
framework emits everything inside
|
|
431
|
-
`@layer mw.reset, mw.base, mw.forms, mw.components, mw.layout, mw.utilities`,
|
|
432
|
-
and an unlayered rule beats every layer regardless of weight:
|
|
433
|
-
|
|
434
|
-
```css
|
|
435
|
-
/* wins over .mw-card, no !important and no doubled selector */
|
|
436
|
-
.mw-card {
|
|
437
|
-
border-radius: 12px;
|
|
438
|
-
}
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
The same rule cuts the other way: third-party CSS loaded unlayered also beats
|
|
442
|
-
the framework, which is what makes an icon font quietly win over `mw-tags-icon`.
|
|
443
|
-
Give it a layer of its own:
|
|
444
|
-
|
|
445
|
-
```css
|
|
446
|
-
@layer vendor, mw;
|
|
447
|
-
@import url('font-awesome.css') layer(vendor);
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
## Importing only what you need
|
|
451
|
-
|
|
452
|
-
The full stylesheet is ~290 kB raw / ~41 kB gzipped. Marketing components
|
|
453
|
-
(`blog-post`, `gallery`, `content-slider`, `techstack-bucket`, `tiles`,
|
|
454
|
-
`coming-soon`, `ratings`, `home`, `hero`) are dead weight in an application, and
|
|
455
|
-
Angular bundle budgets notice.
|
|
456
|
-
|
|
457
|
-
Every layer forwards one module per file, and no `@extend` crosses a file
|
|
458
|
-
boundary, so partial imports are safe. **The one thing you must not drop is
|
|
459
|
-
`base`** - it carries the `:root` tokens; without it every component renders
|
|
460
|
-
colourless. The cascade layer order comes along on its own: every module loads
|
|
461
|
-
`abstracts`, which declares it, so a hand-picked subset orders itself the same
|
|
462
|
-
way the full build does.
|
|
463
|
-
|
|
464
|
-
**The short way is `main-lean`**: the whole framework minus every component -
|
|
465
|
-
tokens, reset, typography, the complete layout and all utilities, ~98 kB raw /
|
|
466
|
-
~16 kB gzipped. Configure it like `main` and add the components next to it:
|
|
467
|
-
|
|
468
|
-
```scss
|
|
469
|
-
@use 'maverick-wave/src/scss/main-lean' with (
|
|
470
|
-
$primary-color: #0f766e
|
|
471
|
-
);
|
|
472
|
-
@use 'maverick-wave/src/scss/components/buttons';
|
|
473
|
-
@use 'maverick-wave/src/scss/components/cards';
|
|
474
|
-
@use 'maverick-wave/src/scss/components/alerts';
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
Those three land at ~19 kB gzipped against ~41 kB for the full build. Pick the
|
|
478
|
-
files by hand, as below, when you also want to leave parts of the layout out.
|
|
479
|
-
|
|
480
|
-
```scss
|
|
481
|
-
// styles.scss - configure first, then pick
|
|
482
|
-
@use 'maverick-wave/src/scss/abstracts/variables' with (
|
|
483
|
-
$primary-color: #0f766e
|
|
484
|
-
);
|
|
485
|
-
|
|
486
|
-
@use 'maverick-wave/src/scss/base'; // :root tokens + reset + typography
|
|
487
|
-
|
|
488
|
-
@use 'maverick-wave/src/scss/layout/grid';
|
|
489
|
-
@use 'maverick-wave/src/scss/layout/main';
|
|
490
|
-
@use 'maverick-wave/src/scss/layout/page-header';
|
|
491
|
-
@use 'maverick-wave/src/scss/layout/section';
|
|
492
|
-
|
|
493
|
-
@use 'maverick-wave/src/scss/components/alerts';
|
|
494
|
-
@use 'maverick-wave/src/scss/components/buttons';
|
|
495
|
-
@use 'maverick-wave/src/scss/components/cards';
|
|
496
|
-
@use 'maverick-wave/src/scss/components/empty-state';
|
|
497
|
-
@use 'maverick-wave/src/scss/components/modals';
|
|
498
|
-
@use 'maverick-wave/src/scss/components/panels';
|
|
499
|
-
@use 'maverick-wave/src/scss/components/skeleton';
|
|
500
|
-
@use 'maverick-wave/src/scss/components/spinners';
|
|
501
|
-
@use 'maverick-wave/src/scss/components/tables';
|
|
502
|
-
@use 'maverick-wave/src/scss/components/tags';
|
|
503
|
-
@use 'maverick-wave/src/scss/components/toasts';
|
|
504
|
-
|
|
505
|
-
@use 'maverick-wave/src/scss/form-elements'; // or single files
|
|
506
|
-
@use 'maverick-wave/src/scss/utilities';
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
That set compiles to ~137 kB raw / ~21 kB gzipped - about half the full build.
|
|
510
|
-
|
|
511
|
-
Details worth knowing:
|
|
512
|
-
|
|
513
|
-
- **Configuration has to come first.** `abstracts/variables` must be configured
|
|
514
|
-
before any other module loads it, so the `with (...)` line goes at the top of
|
|
515
|
-
the file. Configuring `main` instead pulls in everything again.
|
|
516
|
-
- `base` forwards `reset`, `base` and `typography`. If you already have your own
|
|
517
|
-
reset, `@use '.../base/base'` gives you the `:root` block alone (~15 kB raw /
|
|
518
|
-
~3 kB gzipped).
|
|
519
|
-
- Module names are the file names without the leading underscore:
|
|
520
|
-
`components/_buttons.scss` becomes `components/buttons`.
|
|
521
|
-
- Layer index files (`components`, `form-elements`, `layout`, `utilities`,
|
|
522
|
-
`base`) pull in their whole layer - convenient for the small ones
|
|
523
|
-
(`utilities`, `form-elements`), wasteful for `components`.
|
|
524
|
-
- Some components expect a sibling: `lists` styles checkbox rows and looks best
|
|
525
|
-
with `form-elements/checkbox`; `tags` uses `mw-btn-mini` from `buttons` for
|
|
526
|
-
its remove button. `mosaic` needs `lightbox` for its viewer, and
|
|
527
|
-
`portrait-gallery` needs `utilities/fit` for a photo it shows whole instead of
|
|
528
|
-
cropping. `overlay-btn` comes along with every component that uses it.
|
package/.github/workflows/ci.yml
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
pull_request:
|
|
7
|
-
workflow_dispatch:
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v4
|
|
15
|
-
|
|
16
|
-
- uses: actions/setup-node@v4
|
|
17
|
-
with:
|
|
18
|
-
node-version: 22
|
|
19
|
-
cache: npm
|
|
20
|
-
|
|
21
|
-
- name: Install dependencies
|
|
22
|
-
run: npm ci
|
|
23
|
-
|
|
24
|
-
- name: Check formatting
|
|
25
|
-
run: npm run format
|
|
26
|
-
|
|
27
|
-
# Fails on any Sass error, so a broken @use or an unknown function
|
|
28
|
-
# never reaches a release
|
|
29
|
-
- name: Build
|
|
30
|
-
run: npm run build
|
|
31
|
-
|
|
32
|
-
# Token and class consistency between the built CSS and the markup
|
|
33
|
-
- name: Verify
|
|
34
|
-
run: npm run verify
|
|
35
|
-
|
|
36
|
-
- name: Upload build output
|
|
37
|
-
uses: actions/upload-artifact@v4
|
|
38
|
-
with:
|
|
39
|
-
name: dist
|
|
40
|
-
path: dist/
|
|
41
|
-
retention-days: 7
|