maverick-wave 3.3.0 → 3.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/maverick-wave/SKILL.md +208 -0
- package/.claude/skills/maverick-wave/examples/angular-form.md +275 -0
- package/.claude/skills/maverick-wave/examples/angular-list-page.md +304 -0
- package/.claude/skills/maverick-wave/examples/angular-services.md +348 -0
- package/.claude/skills/maverick-wave/examples/static-landing-page.md +362 -0
- package/.claude/skills/maverick-wave/references/components.md +812 -0
- package/.claude/skills/maverick-wave/references/forms.md +289 -0
- package/.claude/skills/maverick-wave/references/javascript.md +70 -0
- package/.claude/skills/maverick-wave/references/layout.md +300 -0
- package/.claude/skills/maverick-wave/references/theming.md +192 -0
- package/.github/workflows/ci.yml +41 -0
- package/CHANGELOG.md +13 -0
- package/README.md +115 -21
- package/index.html +15 -9
- package/maverick-wave.min.css +1 -1
- package/maverick-wave.min.js +1 -1
- package/package.json +3 -1
- package/scripts/verify.js +137 -0
- package/src/js/main.js +39 -11
- package/src/partials/accordions-container.html +22 -27
- package/src/partials/alerts-container.html +26 -0
- package/src/partials/avatars-container.html +22 -0
- package/src/partials/buttons-container.html +11 -15
- package/src/partials/cards-container.html +8 -8
- package/src/partials/colors-container.html +33 -20
- package/src/partials/documentation-container.html +3 -0
- package/src/partials/form-field-container.html +16 -12
- package/src/partials/get-started-container.html +93 -35
- package/src/partials/header-utilities-container.html +64 -6
- package/src/partials/input-group-container.html +5 -3
- package/src/partials/page-header-container.html +78 -0
- package/src/partials/tables-container.html +130 -0
- package/src/partials/tabs-container.html +20 -16
- package/src/partials/tags-container.html +55 -1
- package/src/scss/abstracts/_index.scss +4 -1
- package/src/scss/abstracts/_variables.scss +128 -106
- package/src/scss/base/_base.scss +32 -136
- package/src/scss/base/_reset.scss +1 -1
- package/src/scss/base/_typography.scss +0 -92
- package/src/scss/components/_accordions.scss +3 -3
- package/src/scss/components/_avatars.scss +28 -1
- package/src/scss/components/_blog-post.scss +1 -1
- package/src/scss/components/_button-bar.scss +6 -6
- package/src/scss/components/_buttons.scss +33 -10
- package/src/scss/components/_cards.scss +7 -7
- package/src/scss/components/_coming-soon.scss +4 -4
- package/src/scss/components/_gallery.scss +2 -2
- package/src/scss/components/_index.scss +1 -0
- package/src/scss/components/_info.scss +20 -3
- package/src/scss/components/_lists.scss +11 -10
- package/src/scss/components/_modals.scss +14 -7
- package/src/scss/components/_pagination.scss +3 -3
- package/src/scss/components/_panels.scss +4 -4
- package/src/scss/components/_progress.scss +1 -1
- package/src/scss/components/_ratings.scss +1 -1
- package/src/scss/components/_spinners.scss +2 -2
- package/src/scss/components/_stepper.scss +3 -2
- package/src/scss/components/_tables.scss +42 -1
- package/src/scss/components/_tabs.scss +5 -5
- package/src/scss/components/_tags.scss +43 -27
- package/src/scss/components/_tiles.scss +3 -3
- package/src/scss/components/_timelines.scss +2 -2
- package/src/scss/components/_toasts.scss +92 -0
- package/src/scss/form-elements/_form.scss +11 -3
- package/src/scss/form-elements/_input.scss +24 -0
- package/src/scss/form-elements/_toggle.scss +1 -1
- package/src/scss/layout/_footer.scss +4 -4
- package/src/scss/layout/_header.scss +219 -59
- package/src/scss/layout/_index.scss +1 -0
- package/src/scss/layout/_main.scss +1 -1
- package/src/scss/layout/_page-header.scss +48 -0
- package/src/scss/layout/_section.scss +15 -14
- package/src/scss/main.scss +4 -0
- package/src/scss/utilities/_flex.scss +4 -0
- package/src/scss/utilities/_index.scss +1 -0
- package/src/scss/utilities/_text.scss +105 -0
- package/.claude/commands/mw.md +0 -595
|
@@ -0,0 +1,812 @@
|
|
|
1
|
+
# Components
|
|
2
|
+
|
|
3
|
+
Colour variants are always one of `primary`, `secondary`, `success`, `warning`,
|
|
4
|
+
`danger`, `info` - but not every component offers all six. The lists below are
|
|
5
|
+
exhaustive: what is not named does not exist.
|
|
6
|
+
|
|
7
|
+
## Buttons
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<button type="button" class="mw-btn mw-btn-primary">Save</button>
|
|
11
|
+
<button type="button" class="mw-btn mw-btn-primary">
|
|
12
|
+
<i class="fas fa-save"></i> Save
|
|
13
|
+
</button>
|
|
14
|
+
<a href="#" class="mw-btn mw-btn-outline">Link that looks like a button</a>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Variants: `mw-btn-primary`, `mw-btn-secondary`, `mw-btn-danger`,
|
|
18
|
+
`mw-btn-success`, `mw-btn-outline`, `mw-btn-link`, `mw-btn-link-muted`
|
|
19
|
+
- Sizes: `mw-btn-sm`, `mw-btn-lg`
|
|
20
|
+
- `mw-btn` is `inline-flex` with a gap - icons need no wrapper and no extra class
|
|
21
|
+
- `disabled` gets `opacity: .6` and `not-allowed`; there is no disabled class
|
|
22
|
+
- `active` (no prefix) gives the pressed/selected look on the coloured variants
|
|
23
|
+
- `mw-btn-link` still has the button padding - `mw-p-0` makes it read as inline
|
|
24
|
+
text
|
|
25
|
+
|
|
26
|
+
**Destructive actions use `mw-btn-danger`.** `mw-btn-secondary` is a brand
|
|
27
|
+
colour, not a semantic one.
|
|
28
|
+
|
|
29
|
+
### Mini buttons
|
|
30
|
+
|
|
31
|
+
Round 18px icon buttons - remove a row, close an alert, drop a tag.
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<button type="button" class="mw-btn-mini mw-btn-mini-danger">
|
|
35
|
+
<i class="fas fa-times"></i>
|
|
36
|
+
</button>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Variants: `mw-btn-mini-primary`, `-secondary`, `-danger`, `-success`. Plain
|
|
40
|
+
`mw-btn-mini` is the neutral one. Works on `<a>` as well.
|
|
41
|
+
|
|
42
|
+
### Button bar
|
|
43
|
+
|
|
44
|
+
Row of equally treated buttons, centered by default.
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<div class="mw-button-bar mw-button-bar-primary">
|
|
48
|
+
<button class="mw-btn">Previous</button>
|
|
49
|
+
<button class="mw-btn">Overview</button>
|
|
50
|
+
<button class="mw-btn">Next</button>
|
|
51
|
+
</div>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- Colouring: `mw-button-bar-primary`, `-secondary`, `-outline` style the bare
|
|
55
|
+
`mw-btn` children, so the buttons carry no variant class themselves.
|
|
56
|
+
`mw-button-bar-nav` mixes them for prev/center/next navigation.
|
|
57
|
+
- Alignment: `mw-button-bar-left`, `-right` (default is centered),
|
|
58
|
+
`mw-button-bar-between` pushes first and last apart.
|
|
59
|
+
- Sizes: `mw-button-bar-sm`, `mw-button-bar-lg`.
|
|
60
|
+
|
|
61
|
+
## Cards
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<div class="mw-card mw-card-content">
|
|
65
|
+
<div class="mw-card-img">
|
|
66
|
+
<img src="cover.jpg" alt="" />
|
|
67
|
+
</div>
|
|
68
|
+
<div class="mw-card-body">
|
|
69
|
+
<h3 class="mw-card-title">Title</h3>
|
|
70
|
+
<hr class="mw-card-title-divider" />
|
|
71
|
+
<p class="mw-card-subtitle">Subtitle in muted italics</p>
|
|
72
|
+
<p class="mw-card-text">Body copy.</p>
|
|
73
|
+
<div class="mw-card-footer">
|
|
74
|
+
<button class="mw-btn mw-btn-primary">Open</button>
|
|
75
|
+
<span class="mw-text-muted">12 items</span>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- `mw-card` is the shell; the hover lift is built in and has no modifier class.
|
|
82
|
+
- `mw-card-simple` is the flat variant with even padding for arbitrary content.
|
|
83
|
+
Use it when you only need a padded surface.
|
|
84
|
+
- `mw-card-content` turns the card into a flex column so `mw-card-footer` sticks
|
|
85
|
+
to the bottom - needed whenever cards sit next to each other in a grid.
|
|
86
|
+
- Image height: 210px, `mw-card-lg` 340px, `mw-card-xl` 480px.
|
|
87
|
+
`mw-card-img-contain` shows the whole image instead of cropping it.
|
|
88
|
+
- In `mw-card-footer` the last child is pushed to the right; below `lg` the
|
|
89
|
+
footer stacks and children go full width.
|
|
90
|
+
- `mw-card-badge` (top right corner) and `mw-card-ribbon` (diagonal banner) are
|
|
91
|
+
absolutely positioned overlays; colour them with `mw-card-addon-primary`,
|
|
92
|
+
`-secondary`, `-success`, `-warning`, `-danger`, `-info`.
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<div class="mw-card mw-card-content">
|
|
96
|
+
<div class="mw-card-badge mw-card-addon-success">New</div>
|
|
97
|
+
...
|
|
98
|
+
</div>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Stack card** - icon + title header with a gradient rule, for feature or
|
|
102
|
+
tech-stack grids:
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<div class="mw-card mw-card-stack">
|
|
106
|
+
<div class="mw-card-stack-header">
|
|
107
|
+
<div class="mw-card-stack-icon"><i class="fas fa-server"></i></div>
|
|
108
|
+
<h5 class="mw-card-stack-title">Backend</h5>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="mw-card-stack-body">
|
|
111
|
+
<div class="mw-tags"><span class="mw-tags-item">Kotlin</span></div>
|
|
112
|
+
<p class="mw-card-stack-text">Description.</p>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Panels
|
|
118
|
+
|
|
119
|
+
A bordered box with a header rule - the "titled section" of an application.
|
|
120
|
+
|
|
121
|
+
```html
|
|
122
|
+
<div class="mw-panel mw-panel-primary">
|
|
123
|
+
<h4 class="mw-panel-header">Filters</h4>
|
|
124
|
+
<div class="mw-panel-body">...</div>
|
|
125
|
+
<div class="mw-panel-footer">
|
|
126
|
+
<button class="mw-btn mw-btn-outline">Reset</button>
|
|
127
|
+
<button class="mw-btn mw-btn-primary">Apply</button>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- Header colour: `mw-panel-primary`, `mw-panel-secondary`; without them the
|
|
133
|
+
header is neutral.
|
|
134
|
+
- Height: `mw-panel-scrollable` (500px), `mw-panel-max-height-sm` (300px),
|
|
135
|
+
`-md` (500px), `-lg` (700px) - the body scrolls, header and footer stay.
|
|
136
|
+
- `mw-panel` has `min-height: 100%`, so panels in a grid row end up equally tall.
|
|
137
|
+
|
|
138
|
+
## Tiles
|
|
139
|
+
|
|
140
|
+
Compact, clickable info blocks in a fixed 3-column grid.
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<div class="mw-tiles mw-tiles-2col">
|
|
144
|
+
<div class="mw-tile">
|
|
145
|
+
<div class="mw-tile-img"><img src="icon.png" alt="" /></div>
|
|
146
|
+
<h3 class="mw-tile-header">Billing</h3>
|
|
147
|
+
<div class="mw-tile-body">
|
|
148
|
+
<p>Invoices and payments</p>
|
|
149
|
+
</div>
|
|
150
|
+
<div class="mw-tile-footer">Updated 2026-01-02</div>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Container: `mw-tiles` (3 columns), `mw-tiles-2col`, `mw-tiles-4col`.
|
|
156
|
+
Tile sizes: `mw-tile-sm`, `mw-tile-lg`.
|
|
157
|
+
|
|
158
|
+
## Accordion
|
|
159
|
+
|
|
160
|
+
```html
|
|
161
|
+
<div class="mw-accordion">
|
|
162
|
+
<div class="mw-accordion-item">
|
|
163
|
+
<div class="mw-accordion-header active">
|
|
164
|
+
<h3>Question</h3>
|
|
165
|
+
<i class="fas fa-chevron-down mw-accordion-icon"></i>
|
|
166
|
+
</div>
|
|
167
|
+
<div class="mw-accordion-content active">
|
|
168
|
+
<div class="mw-accordion-content-inner">Answer</div>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Open state = `active` (no prefix) on header **and** content. The icon rotates
|
|
175
|
+
via the header state. Content taller than 500px scrolls. Toggling is JS - see
|
|
176
|
+
`references/javascript.md`.
|
|
177
|
+
|
|
178
|
+
## Tabs
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<div class="mw-tabs">
|
|
182
|
+
<div class="mw-tabs-nav">
|
|
183
|
+
<div class="mw-tabs-nav-item active" data-tab="tab1">Details</div>
|
|
184
|
+
<div class="mw-tabs-nav-item" data-tab="tab2">History</div>
|
|
185
|
+
</div>
|
|
186
|
+
<div class="mw-tabs-content">
|
|
187
|
+
<div class="mw-tabs-panel active" id="tab1">...</div>
|
|
188
|
+
<div class="mw-tabs-panel" id="tab2">...</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- Variants: `mw-tabs-vertical` (nav on the left, horizontal again below `sm`),
|
|
194
|
+
`mw-tabs-pills`.
|
|
195
|
+
- `data-tab` matches the panel `id` - that pairing is only needed for the
|
|
196
|
+
shipped JS. In a SPA, bind `active` yourself and drop the attribute.
|
|
197
|
+
- The nav scrolls horizontally on small screens instead of wrapping.
|
|
198
|
+
|
|
199
|
+
## Modal
|
|
200
|
+
|
|
201
|
+
```html
|
|
202
|
+
<div id="delete-modal" class="mw-modal-overlay">
|
|
203
|
+
<div class="mw-modal mw-modal-sm">
|
|
204
|
+
<div class="mw-modal-header">
|
|
205
|
+
<h4 class="mw-modal-title">Delete invoice</h4>
|
|
206
|
+
<button class="mw-modal-close" type="button">𝗫</button>
|
|
207
|
+
</div>
|
|
208
|
+
<div class="mw-modal-body">
|
|
209
|
+
<p>This cannot be undone.</p>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="mw-modal-footer">
|
|
212
|
+
<button class="mw-btn mw-btn-outline">Cancel</button>
|
|
213
|
+
<button class="mw-btn mw-btn-danger">Delete</button>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
<div class="mw-modal-backdrop"></div>
|
|
217
|
+
</div>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
- The overlay is `display: none` until `mw-modal-open` is added to it. That
|
|
221
|
+
class is the whole open/close mechanism.
|
|
222
|
+
- Body scroll lock is automatic: the stylesheet uses
|
|
223
|
+
`body:has(.mw-modal-open)`. Nothing to implement.
|
|
224
|
+
- Sizes: `mw-modal-sm` 370px, default 550px, `mw-modal-lg` 680px,
|
|
225
|
+
`mw-modal-xl` 900px. Height is capped at 80-92dvh, the body scrolls.
|
|
226
|
+
- `mw-modal-backdrop` is the click-to-close surface; put the close handler on it.
|
|
227
|
+
- `mw-modal-body` takes a `mw-form` directly - the form brings the field gaps,
|
|
228
|
+
the body brings the padding.
|
|
229
|
+
|
|
230
|
+
Angular: `<div class="mw-modal-overlay" [class.mw-modal-open]="isOpen()">`.
|
|
231
|
+
|
|
232
|
+
## Alerts & toasts
|
|
233
|
+
|
|
234
|
+
```html
|
|
235
|
+
<div class="mw-alert mw-alert-success">
|
|
236
|
+
<div class="mw-alert-icon"><i class="fas fa-check-circle"></i></div>
|
|
237
|
+
<div class="mw-alert-content">
|
|
238
|
+
<span class="mw-alert-title">Saved</span>
|
|
239
|
+
<p>The invoice was created.</p>
|
|
240
|
+
</div>
|
|
241
|
+
<button type="button" class="mw-btn-mini mw-btn-mini-danger mw-alert-close">
|
|
242
|
+
<i class="fas fa-times"></i>
|
|
243
|
+
</button>
|
|
244
|
+
</div>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Variants: `mw-alert-primary`, `-secondary`, `-success`, `-warning`, `-danger`,
|
|
248
|
+
`-info`. `mw-alert-title` and the close button are optional. `mw-alert-closed`
|
|
249
|
+
hides a dismissed alert (`display: none`) - in a SPA prefer removing it from the
|
|
250
|
+
list instead.
|
|
251
|
+
|
|
252
|
+
**Toasts** are alerts inside a fixed stack:
|
|
253
|
+
|
|
254
|
+
```html
|
|
255
|
+
<div class="mw-toast-stack mw-toast-stack-top-right">
|
|
256
|
+
<div class="mw-alert mw-alert-success">...</div>
|
|
257
|
+
</div>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Positions: `mw-toast-stack-top-right` (also the default without a position
|
|
261
|
+
class), `-top-center`, `-bottom-right`. Width is capped at
|
|
262
|
+
`min(380px, 100vw - 2rem)`, clicks pass through everywhere except on a toast,
|
|
263
|
+
the entry animation respects `prefers-reduced-motion`. Auto-dismiss is the
|
|
264
|
+
application's job.
|
|
265
|
+
|
|
266
|
+
## Empty state
|
|
267
|
+
|
|
268
|
+
```html
|
|
269
|
+
<div class="mw-empty-state mw-empty-state-warning mw-empty-state-sm">
|
|
270
|
+
<div class="mw-empty-state-icon"><i class="fas fa-inbox"></i></div>
|
|
271
|
+
<p class="mw-empty-state-title">No results</p>
|
|
272
|
+
<p class="mw-empty-state-desc">Try a different filter.</p>
|
|
273
|
+
<button class="mw-btn mw-btn-outline">Clear filters</button>
|
|
274
|
+
</div>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Variants: `mw-empty-state-primary`, `-success`, `-warning`, `-danger`. Size:
|
|
278
|
+
`mw-empty-state-sm`.
|
|
279
|
+
|
|
280
|
+
## Spinners
|
|
281
|
+
|
|
282
|
+
```html
|
|
283
|
+
<div class="mw-spinner-container">
|
|
284
|
+
<div class="mw-spinner-border mw-spinner-primary"></div>
|
|
285
|
+
</div>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
- Shapes (one is mandatory): `mw-spinner-border`, `mw-spinner-dual-ring`,
|
|
289
|
+
`mw-spinner-dots` (needs three empty `<div>` children).
|
|
290
|
+
- Sizes `mw-spinner-sm`, `mw-spinner-lg`; colours `mw-spinner-primary`,
|
|
291
|
+
`mw-spinner-secondary`.
|
|
292
|
+
- `mw-spinner-container` centers in the available space.
|
|
293
|
+
`mw-spinner-container-overlay` lays a dimmed, blurred scrim over the parent -
|
|
294
|
+
the parent needs `position: relative`.
|
|
295
|
+
|
|
296
|
+
## Skeleton
|
|
297
|
+
|
|
298
|
+
```html
|
|
299
|
+
<div class="mw-skeleton-card">
|
|
300
|
+
<div class="mw-skeleton-row">
|
|
301
|
+
<span class="mw-skeleton mw-skeleton-circle"></span>
|
|
302
|
+
<div class="mw-skeleton-body">
|
|
303
|
+
<span class="mw-skeleton mw-skeleton-text" style="width: 55%"></span>
|
|
304
|
+
<span class="mw-skeleton mw-skeleton-text"></span>
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
<span class="mw-skeleton mw-skeleton-rect"></span>
|
|
308
|
+
<span class="mw-skeleton mw-skeleton-title"></span>
|
|
309
|
+
<span class="mw-skeleton mw-skeleton-text"></span>
|
|
310
|
+
</div>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Shapes: `mw-skeleton-title`, `-text`, `-circle`, `-rect` (+ `-rect-sm`,
|
|
314
|
+
`-rect-lg`). Widths are set inline when a line should look ragged.
|
|
315
|
+
|
|
316
|
+
## Tables
|
|
317
|
+
|
|
318
|
+
```html
|
|
319
|
+
<div class="mw-table-responsive">
|
|
320
|
+
<table class="mw-table mw-table-cards">
|
|
321
|
+
<thead>
|
|
322
|
+
<tr>
|
|
323
|
+
<th>Name</th>
|
|
324
|
+
<th>Status</th>
|
|
325
|
+
<th class="mw-text-numeric">Amount</th>
|
|
326
|
+
</tr>
|
|
327
|
+
</thead>
|
|
328
|
+
<tbody>
|
|
329
|
+
<tr>
|
|
330
|
+
<td data-label="Name">Jane Doe</td>
|
|
331
|
+
<td data-label="Status">
|
|
332
|
+
<span class="mw-tag mw-tag-success">Paid</span>
|
|
333
|
+
</td>
|
|
334
|
+
<td data-label="Amount" class="mw-text-numeric">1.204,50</td>
|
|
335
|
+
</tr>
|
|
336
|
+
</tbody>
|
|
337
|
+
</table>
|
|
338
|
+
</div>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
| Class | Effect |
|
|
342
|
+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
343
|
+
| `mw-table` | Base: zebra rows, row hover, primary-coloured header |
|
|
344
|
+
| `mw-table-subtle` | Quiet grey header with an accent rule - for data-heavy lists |
|
|
345
|
+
| `mw-table-compact` | Less padding, smaller type |
|
|
346
|
+
| `mw-table-hover` | Stronger row hover |
|
|
347
|
+
| `mw-table-cards` | Below `md` every row becomes a card; keep `<thead>` (hidden via CSS) and give each cell a `data-label` |
|
|
348
|
+
| `mw-table-responsive` | Wrapper, horizontal scroll |
|
|
349
|
+
| `mw-table-responsive-scroll` | Wrapper with a height cap (`--mw-table-scroll-height`, 400px / 260px below `sm`) and vertical scroll |
|
|
350
|
+
| `mw-table-sticky-head` | Header stays put while the body scrolls - only works inside a height-limited wrapper, i.e. `mw-table-responsive-scroll` |
|
|
351
|
+
|
|
352
|
+
```html
|
|
353
|
+
<div class="mw-table-responsive-scroll" style="--mw-table-scroll-height: 250px">
|
|
354
|
+
<table class="mw-table mw-table-subtle mw-table-sticky-head">
|
|
355
|
+
...
|
|
356
|
+
</table>
|
|
357
|
+
</div>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Tags
|
|
361
|
+
|
|
362
|
+
Two forms, picked by count - see also the pitfall list in `SKILL.md`.
|
|
363
|
+
|
|
364
|
+
**Single chip** (table cells, status columns) - carries its colour itself:
|
|
365
|
+
|
|
366
|
+
```html
|
|
367
|
+
<span class="mw-tag mw-tag-success">Paid</span>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Variants: `mw-tag-primary`, `-secondary`, `-success`, `-info`, `-warning`,
|
|
371
|
+
`-danger`, `-muted`. Size: `mw-tag-lg`. `mw-tag-muted` is the neutral tone for
|
|
372
|
+
states that should not shout (draft, archived).
|
|
373
|
+
|
|
374
|
+
**List** - the container carries the colour for all its items:
|
|
375
|
+
|
|
376
|
+
```html
|
|
377
|
+
<div class="mw-tags mw-tags-primary">
|
|
378
|
+
<span class="mw-tags-item"
|
|
379
|
+
><i class="fas fa-check mw-tags-icon"></i>Angular</span
|
|
380
|
+
>
|
|
381
|
+
<span class="mw-tags-item mw-tags-removable">
|
|
382
|
+
Kotlin
|
|
383
|
+
<button type="button" class="mw-btn-mini mw-btn-mini-danger mw-tags-remove">
|
|
384
|
+
<i class="fas fa-times"></i>
|
|
385
|
+
</button>
|
|
386
|
+
</span>
|
|
387
|
+
</div>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Container variants: `mw-tags-primary`, `-secondary`, `-success`, `-info`,
|
|
391
|
+
`-warning`, `-danger`, `-muted`, size `mw-tags-lg`. `mw-tags-remove` only
|
|
392
|
+
positions the button - its look comes from `mw-btn-mini` plus a colour variant.
|
|
393
|
+
|
|
394
|
+
## Info badges & counters
|
|
395
|
+
|
|
396
|
+
```html
|
|
397
|
+
<span class="mw-info mw-info-primary">Active</span>
|
|
398
|
+
|
|
399
|
+
<a href="/invoices" class="mw-info mw-info-counter mw-info-success">
|
|
400
|
+
<div class="mw-info-value">150</div>
|
|
401
|
+
<div class="mw-info-label">Invoices</div>
|
|
402
|
+
</a>
|
|
403
|
+
|
|
404
|
+
<span class="mw-info-mini mw-info-mini-danger"
|
|
405
|
+
><i class="fas fa-times"></i
|
|
406
|
+
></span>
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
- `mw-info`: sizes `mw-info-sm`, `-lg`, `-xl`; colours `mw-info-primary`,
|
|
410
|
+
`-secondary`, `-success`, `-warning`, `-danger`, `-info` (tinted background +
|
|
411
|
+
a 6px left border).
|
|
412
|
+
- `mw-info-counter` turns it into a big number over a small label
|
|
413
|
+
(`mw-info-value`, `mw-info-label`).
|
|
414
|
+
- The cursor is `default` because a figure is usually not clickable. On `<a>`
|
|
415
|
+
and `<button>` it turns into a pointer automatically; on anything else use
|
|
416
|
+
`mw-info-clickable`.
|
|
417
|
+
- `mw-info-mini` is the 20px status dot: sizes `-sm`, `-lg`, `-xl`, colours
|
|
418
|
+
`-primary`, `-secondary`, `-success`, `-warning`, `-danger`, `-info`.
|
|
419
|
+
|
|
420
|
+
## Progress
|
|
421
|
+
|
|
422
|
+
```html
|
|
423
|
+
<div class="mw-progress-container">
|
|
424
|
+
<div class="mw-progress-barinfo">
|
|
425
|
+
<span class="mw-progress-label">Completion</span>
|
|
426
|
+
<span class="mw-progress-value mw-progress-percent">75</span>
|
|
427
|
+
</div>
|
|
428
|
+
<div class="mw-progress-bar">
|
|
429
|
+
<div class="mw-progress-fill mw-progress-primary" style="width: 75%"></div>
|
|
430
|
+
</div>
|
|
431
|
+
</div>
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
- The value element only prints what you put in it; `mw-progress-percent`
|
|
435
|
+
appends `%`, `mw-progress-numeric` appends `/10`. Neither computes anything.
|
|
436
|
+
- The fill width is set by you (`style="width: 75%"`). The shipped JS instead
|
|
437
|
+
reads `data-value="75"` and animates it into view - in a SPA bind the style.
|
|
438
|
+
- Colours: `mw-progress-primary`, `-secondary`, `-success`, `-warning`,
|
|
439
|
+
`-danger`, `-info` (default fill is the secondary colour).
|
|
440
|
+
- Sizes on the container: `mw-progress-sm`, `mw-progress-lg`.
|
|
441
|
+
- `mw-progress-hide-info` on the info row hides the labels while keeping the
|
|
442
|
+
layout; `mw-progress-inline-label` on the container puts the text inside the
|
|
443
|
+
bar.
|
|
444
|
+
|
|
445
|
+
## Rating
|
|
446
|
+
|
|
447
|
+
```html
|
|
448
|
+
<div class="mw-rating-container">
|
|
449
|
+
<p class="mw-rating-info">Product rating</p>
|
|
450
|
+
<div class="mw-rating mw-rating-lg" data-rating="4">
|
|
451
|
+
<i class="mw-rating-icon fas fa-thumbs-up" aria-hidden="true"></i>
|
|
452
|
+
<!-- five icons total -->
|
|
453
|
+
</div>
|
|
454
|
+
</div>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
`data-rating` is `0`-`5` and highlights the first N icons - pure CSS, any icon
|
|
458
|
+
works. Sizes: `mw-rating-sm`, `mw-rating-lg`.
|
|
459
|
+
|
|
460
|
+
## Meta header
|
|
461
|
+
|
|
462
|
+
Small icon + text counters, e.g. under a page title.
|
|
463
|
+
|
|
464
|
+
```html
|
|
465
|
+
<div class="mw-meta-header">
|
|
466
|
+
<div class="mw-meta-item">
|
|
467
|
+
<i class="fas fa-list"></i><span>Total: 14</span>
|
|
468
|
+
</div>
|
|
469
|
+
<div class="mw-meta-item">
|
|
470
|
+
<i class="fas fa-pen"></i><span>Drafts: 3</span>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
## Stepper
|
|
476
|
+
|
|
477
|
+
```html
|
|
478
|
+
<div class="mw-stepper">
|
|
479
|
+
<div class="mw-stepper-step">
|
|
480
|
+
<div class="mw-stepper-indicator mw-done"><i class="fas fa-check"></i></div>
|
|
481
|
+
<span class="mw-stepper-label mw-done">Account</span>
|
|
482
|
+
</div>
|
|
483
|
+
<div class="mw-stepper-connector mw-done"></div>
|
|
484
|
+
<div class="mw-stepper-step">
|
|
485
|
+
<div class="mw-stepper-indicator mw-active">2</div>
|
|
486
|
+
<span class="mw-stepper-label mw-active">Details</span>
|
|
487
|
+
</div>
|
|
488
|
+
<div class="mw-stepper-connector"></div>
|
|
489
|
+
<div class="mw-stepper-step">
|
|
490
|
+
<div class="mw-stepper-indicator">3</div>
|
|
491
|
+
<span class="mw-stepper-label">Review</span>
|
|
492
|
+
</div>
|
|
493
|
+
</div>
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
State classes here are prefixed: `mw-done`, `mw-active`. The horizontal variant
|
|
497
|
+
needs the explicit `mw-stepper-connector` elements between the steps; the
|
|
498
|
+
vertical one (`mw-stepper-vertical`) draws the line itself and takes
|
|
499
|
+
`mw-stepper-content` with `mw-stepper-content-title` / `-desc` instead of a
|
|
500
|
+
label:
|
|
501
|
+
|
|
502
|
+
```html
|
|
503
|
+
<div class="mw-stepper-vertical">
|
|
504
|
+
<div class="mw-stepper-step mw-done">
|
|
505
|
+
<div class="mw-stepper-indicator mw-done"><i class="fas fa-check"></i></div>
|
|
506
|
+
<div class="mw-stepper-content">
|
|
507
|
+
<p class="mw-stepper-content-title">Dependencies installed</p>
|
|
508
|
+
<p class="mw-stepper-content-desc">All packages resolved.</p>
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
511
|
+
</div>
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## Timelines
|
|
515
|
+
|
|
516
|
+
Both are chronicles (CV, changelog), not schedulable time axes.
|
|
517
|
+
|
|
518
|
+
```html
|
|
519
|
+
<div class="mw-timeline-big">
|
|
520
|
+
<div class="mw-timeline-big-step active">
|
|
521
|
+
<div class="mw-timeline-big-date-container">
|
|
522
|
+
<div class="mw-timeline-big-date-main">01/2023 - today</div>
|
|
523
|
+
<div class="mw-timeline-big-date-sub">(3 years)</div>
|
|
524
|
+
</div>
|
|
525
|
+
<div class="mw-timeline-big-content">
|
|
526
|
+
<div class="mw-card mw-card-content">...</div>
|
|
527
|
+
<div class="mw-timeline-big-event">
|
|
528
|
+
<span class="mw-timeline-big-event-date">05/2023</span>
|
|
529
|
+
<span class="mw-timeline-big-event-title">Certification</span>
|
|
530
|
+
</div>
|
|
531
|
+
</div>
|
|
532
|
+
</div>
|
|
533
|
+
</div>
|
|
534
|
+
|
|
535
|
+
<div class="mw-timeline-simple">
|
|
536
|
+
<div class="mw-timeline-simple-step active">
|
|
537
|
+
<div class="mw-timeline-simple-date">2024-03-22</div>
|
|
538
|
+
<div class="mw-timeline-simple-content">
|
|
539
|
+
<div class="mw-card mw-card-simple">...</div>
|
|
540
|
+
</div>
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
The current step gets `active` (no prefix). Any card fits into the content
|
|
546
|
+
wrapper.
|
|
547
|
+
|
|
548
|
+
## Avatars
|
|
549
|
+
|
|
550
|
+
```html
|
|
551
|
+
<div class="mw-avatar mw-avatar-lg mw-avatar-primary">
|
|
552
|
+
<img src="me.jpg" alt="" />
|
|
553
|
+
</div>
|
|
554
|
+
|
|
555
|
+
<div class="mw-avatar mw-avatar-initials mw-avatar-xs">MW</div>
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
- Sizes: `mw-avatar-xs` 32, `-sm` 64, default 96, `-lg` 144, `-xl` 250 px.
|
|
559
|
+
- Shape: `mw-avatar-square`.
|
|
560
|
+
- Colours `mw-avatar-primary`, `-secondary`, `-success`, `-warning`, `-danger`,
|
|
561
|
+
`-info` tint the **border**. On `mw-avatar-initials` the same class also tints
|
|
562
|
+
the **surface**, so both can be combined.
|
|
563
|
+
- `mw-avatar-initials` centers text and scales the font with the size class -
|
|
564
|
+
the standard display for a signed-in user without a picture.
|
|
565
|
+
- `mw-avatar-group` overlaps its avatars; `mw-avatar-group-sm` / `-lg` change
|
|
566
|
+
the overlap.
|
|
567
|
+
|
|
568
|
+
## Item lists
|
|
569
|
+
|
|
570
|
+
Layout containers for arbitrary children - the children need no classes.
|
|
571
|
+
|
|
572
|
+
| Class | Look |
|
|
573
|
+
| ------------------------- | ---------------------------------------------------------------------------- |
|
|
574
|
+
| `mw-item-list` | Plain flex column with gaps |
|
|
575
|
+
| `mw-item-list-horizontal` | Row, wrapping; column below `sm` |
|
|
576
|
+
| `mw-item-list-cards` | Wider gaps, for cards |
|
|
577
|
+
| `mw-item-list-compact` | Bordered box, divided rows, hover indent (nests) |
|
|
578
|
+
| `mw-item-list-menu` | Elevated menu card, pointer cursor, press feedback |
|
|
579
|
+
| `mw-item-list-slide` | Cards with a sliding accent border on hover (`mw-item-list-slide-secondary`) |
|
|
580
|
+
| `mw-item-list-scroll` | Scroll box, 300px (`-sm` 200, `-lg` 400, `-xl` 500) |
|
|
581
|
+
|
|
582
|
+
```html
|
|
583
|
+
<div class="mw-item-list-compact">
|
|
584
|
+
<div>Quick settings</div>
|
|
585
|
+
<div>
|
|
586
|
+
Privacy
|
|
587
|
+
<div class="mw-item-list-compact">
|
|
588
|
+
<div>Cookies</div>
|
|
589
|
+
</div>
|
|
590
|
+
</div>
|
|
591
|
+
</div>
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**Checkbox lists** are the one variant with required inner markup - a `<ul>` of
|
|
595
|
+
`<li>` each holding a `mw-checkbox`:
|
|
596
|
+
|
|
597
|
+
```html
|
|
598
|
+
<ul class="mw-item-list-checkbox">
|
|
599
|
+
<li class="mw-selected">
|
|
600
|
+
<label class="mw-checkbox">
|
|
601
|
+
<input type="checkbox" checked />
|
|
602
|
+
<span class="mw-checkbox-box"></span>
|
|
603
|
+
<div class="mw-checkbox-content">
|
|
604
|
+
<h4 class="mw-checkbox-header">Task management</h4>
|
|
605
|
+
<p class="mw-checkbox-label">Track your daily tasks</p>
|
|
606
|
+
</div>
|
|
607
|
+
</label>
|
|
608
|
+
</li>
|
|
609
|
+
</ul>
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
Variants: `mw-item-list-checkbox-compact`, `-large`, `-secondary`,
|
|
613
|
+
`-scroll`. `mw-selected` on the `<li>` is the selected-row highlight - bind it
|
|
614
|
+
to the checkbox state yourself in a SPA. The `mw-checkbox-content` block is
|
|
615
|
+
optional; a bare `mw-checkbox-label` renders a single-line row.
|
|
616
|
+
|
|
617
|
+
## HTML lists
|
|
618
|
+
|
|
619
|
+
`mw-list` is the base (spacing for `li`), combined with one of:
|
|
620
|
+
`mw-list-unstyled`, `mw-list-inline`, `mw-list-link` (underlined anchors),
|
|
621
|
+
`mw-list-dot` (coloured markers), `mw-list-check` (✓ prefix).
|
|
622
|
+
|
|
623
|
+
```html
|
|
624
|
+
<ul class="mw-list mw-list-check">
|
|
625
|
+
<li>Done</li>
|
|
626
|
+
</ul>
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
## Breadcrumbs
|
|
630
|
+
|
|
631
|
+
```html
|
|
632
|
+
<nav class="mw-breadcrumbs mw-breadcrumbs-collapse" aria-label="Breadcrumb">
|
|
633
|
+
<ol class="mw-breadcrumbs-list">
|
|
634
|
+
<li class="mw-breadcrumbs-item">
|
|
635
|
+
<a href="/"><i class="fas fa-home"></i></a>
|
|
636
|
+
</li>
|
|
637
|
+
<li class="mw-breadcrumbs-item">
|
|
638
|
+
<a href="/invoices"><span>Invoices</span></a>
|
|
639
|
+
</li>
|
|
640
|
+
<li class="mw-breadcrumbs-item mw-breadcrumbs-current">
|
|
641
|
+
<a href="#" class="mw-breadcrumbs-active"><span>2026-001</span></a>
|
|
642
|
+
</li>
|
|
643
|
+
</ol>
|
|
644
|
+
</nav>
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
The last item takes `mw-breadcrumbs-current` on the `li` and
|
|
648
|
+
`mw-breadcrumbs-active` on the anchor. `mw-breadcrumbs-sm` is the small variant,
|
|
649
|
+
`mw-breadcrumbs-collapse` hides middle items on narrow screens.
|
|
650
|
+
|
|
651
|
+
## Pagination
|
|
652
|
+
|
|
653
|
+
A titled content frame with prev/next controls - not a page-number list.
|
|
654
|
+
|
|
655
|
+
```html
|
|
656
|
+
<div class="mw-pagination">
|
|
657
|
+
<div class="mw-pagination-header">
|
|
658
|
+
<button class="mw-pagination-nav"><i class="fas fa-arrow-left"></i></button>
|
|
659
|
+
<h3 class="mw-pagination-title">Week 10</h3>
|
|
660
|
+
<button class="mw-pagination-nav">
|
|
661
|
+
<i class="fas fa-arrow-right"></i>
|
|
662
|
+
</button>
|
|
663
|
+
</div>
|
|
664
|
+
<div class="mw-pagination-content">...</div>
|
|
665
|
+
</div>
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
`mw-pagination-loading` on the container dims the content while it swaps;
|
|
669
|
+
`mw-pagination-slide-left` / `-slide-right` are the directional transitions.
|
|
670
|
+
|
|
671
|
+
## Divider
|
|
672
|
+
|
|
673
|
+
```html
|
|
674
|
+
<hr class="mw-divider mw-divider-dashed" />
|
|
675
|
+
<div class="mw-divider-text"><span>or</span></div>
|
|
676
|
+
<div class="mw-divider-vertical"></div>
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
Variants: `mw-divider-thick`, `mw-divider-dashed`, `mw-divider-primary`,
|
|
680
|
+
`mw-divider-secondary`. `mw-divider-text` is a labelled rule (the colour
|
|
681
|
+
variants apply to it too), `mw-divider-vertical` needs a flex row with a height.
|
|
682
|
+
|
|
683
|
+
## Gallery & image slider
|
|
684
|
+
|
|
685
|
+
```html
|
|
686
|
+
<div class="mw-gallery-container">
|
|
687
|
+
<div class="mw-gallery">
|
|
688
|
+
<button type="button" class="mw-gallery-navi mw-gallery-navi-prev">
|
|
689
|
+
❮
|
|
690
|
+
</button>
|
|
691
|
+
<div class="mw-gallery-track">
|
|
692
|
+
<div class="mw-gallery-slide" data-desc="Mountains">
|
|
693
|
+
<img src="1.jpg" alt="" />
|
|
694
|
+
</div>
|
|
695
|
+
</div>
|
|
696
|
+
<button type="button" class="mw-gallery-navi mw-gallery-navi-next">
|
|
697
|
+
❯
|
|
698
|
+
</button>
|
|
699
|
+
</div>
|
|
700
|
+
<div class="mw-gallery-desc">Mountains</div>
|
|
701
|
+
<div class="mw-gallery-dots"></div>
|
|
702
|
+
</div>
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
The dots (`mw-gallery-dot`, active one gets `mw-active`) are generated by the
|
|
706
|
+
shipped JS, as is the track transform. In a SPA, render the dots and set
|
|
707
|
+
`transform: translateX(...)` yourself.
|
|
708
|
+
|
|
709
|
+
`mw-image-slider` swaps a base image against overlays through indexed buttons:
|
|
710
|
+
|
|
711
|
+
```html
|
|
712
|
+
<div class="mw-image-slider">
|
|
713
|
+
<div class="mw-image-slider-base" data-index="0">
|
|
714
|
+
<img class="mw-image-slider-base-image" src="base.jpg" alt="" />
|
|
715
|
+
</div>
|
|
716
|
+
<div class="mw-image-slider-overlay">
|
|
717
|
+
<div class="mw-image-slider-overlay-image active" data-index="1">
|
|
718
|
+
<img src="a.jpg" alt="" />
|
|
719
|
+
</div>
|
|
720
|
+
</div>
|
|
721
|
+
<div class="mw-image-slider-controls-grid-3">
|
|
722
|
+
<button class="mw-btn mw-btn-primary active" data-index="0">Base</button>
|
|
723
|
+
</div>
|
|
724
|
+
</div>
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
Control grids: `mw-image-slider-controls-grid-2`, `-grid-3`. Visible overlay and
|
|
728
|
+
current button carry `active`.
|
|
729
|
+
|
|
730
|
+
## Blog post
|
|
731
|
+
|
|
732
|
+
```html
|
|
733
|
+
<article class="mw-blog-post">
|
|
734
|
+
<h2 class="mw-blog-post-title">Title</h2>
|
|
735
|
+
<div class="mw-blog-post-header">
|
|
736
|
+
<div class="mw-blog-post-header-icon"><i class="fas fa-code"></i></div>
|
|
737
|
+
<div class="mw-blog-post-meta">
|
|
738
|
+
<div class="mw-blog-post-meta-item">
|
|
739
|
+
<i class="far fa-calendar"></i><span>2026-04-10</span>
|
|
740
|
+
</div>
|
|
741
|
+
</div>
|
|
742
|
+
</div>
|
|
743
|
+
<img class="mw-blog-post-featured-image" src="cover.jpg" alt="" />
|
|
744
|
+
<div class="mw-blog-post-content-markdown">
|
|
745
|
+
<!-- raw h3/p/ul/blockquote/pre from a markdown renderer -->
|
|
746
|
+
</div>
|
|
747
|
+
<div class="mw-blog-post-footer">
|
|
748
|
+
<button class="mw-btn mw-blog-post-footer-button">
|
|
749
|
+
<i class="fas fa-arrow-left"></i><span>Previous</span>
|
|
750
|
+
</button>
|
|
751
|
+
</div>
|
|
752
|
+
</article>
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
`mw-blog-post-content-markdown` styles unclassed HTML - the target for rendered
|
|
756
|
+
markdown. `mw-blog-post-content` is the same wrapper for hand-written markup.
|
|
757
|
+
|
|
758
|
+
## Code & terminal
|
|
759
|
+
|
|
760
|
+
```html
|
|
761
|
+
<div class="mw-code-block">
|
|
762
|
+
<div class="mw-code-block-header">
|
|
763
|
+
<span class="mw-code-block-filename">main.kt</span>
|
|
764
|
+
<span class="mw-code-block-language">Kotlin</span>
|
|
765
|
+
</div>
|
|
766
|
+
<div class="mw-code-container">
|
|
767
|
+
<pre><code>fun main() {}</code></pre>
|
|
768
|
+
</div>
|
|
769
|
+
</div>
|
|
770
|
+
|
|
771
|
+
<div class="mw-terminal">
|
|
772
|
+
<span class="mw-terminal-line">npm install maverick-wave</span>
|
|
773
|
+
<span class="mw-terminal-line mw-terminal-output">added 1 package</span>
|
|
774
|
+
</div>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
Token classes for manual highlighting: `mw-code-keyword`, `mw-code-function`,
|
|
778
|
+
`mw-code-string`, `mw-code-number`, `mw-code-comment`, `mw-code-operator`. There
|
|
779
|
+
is no highlighting engine - wrap spans yourself or plug in Prism/highlight.js.
|
|
780
|
+
`mw-code-nowrap` disables wrapping. `<code>` on its own is styled as inline code.
|
|
781
|
+
|
|
782
|
+
## Tech stack bucket
|
|
783
|
+
|
|
784
|
+
```html
|
|
785
|
+
<div class="mw-techstack-bucket mw-techstack-bucket-dashed">
|
|
786
|
+
<a href="https://angular.dev" class="mw-techstack-item">
|
|
787
|
+
<img class="mw-techstack-logo" src="angular.svg" alt="Angular" />
|
|
788
|
+
<div class="mw-techstack-info">
|
|
789
|
+
<span class="mw-techstack-name">Angular</span>
|
|
790
|
+
<span class="mw-techstack-desc">Frontend</span>
|
|
791
|
+
</div>
|
|
792
|
+
</a>
|
|
793
|
+
<a
|
|
794
|
+
href="#"
|
|
795
|
+
class="mw-techstack-item mw-techstack-item-sm"
|
|
796
|
+
data-tooltip="Docker"
|
|
797
|
+
>
|
|
798
|
+
<img class="mw-techstack-logo" src="docker.svg" alt="Docker" />
|
|
799
|
+
</a>
|
|
800
|
+
</div>
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
`mw-techstack-item-sm` is the logo-only chip; the info block is optional.
|
|
804
|
+
|
|
805
|
+
## Coming soon
|
|
806
|
+
|
|
807
|
+
```html
|
|
808
|
+
<div class="mw-coming-soon">
|
|
809
|
+
<i class="mw-coming-soon-icon fas fa-tools"></i>
|
|
810
|
+
<div class="mw-coming-soon-text">Coming soon</div>
|
|
811
|
+
</div>
|
|
812
|
+
```
|