mote.css 0.6.0 → 0.7.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/CHANGELOG.md +92 -1
- package/README.md +14 -2
- package/mote.components.css +74 -6
- package/mote.css +56 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,96 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [0.
|
|
8
|
+
## [0.7.0] - 2026-10-21
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Badges are gated** (same as buttons): a plain `.mote-badge` is always
|
|
13
|
+
accent-tinted; a status class on the badge itself provides the tint —
|
|
14
|
+
never inherited from context. Closes the "tag chips silently re-tint
|
|
15
|
+
inside themed cards" surprise from four evaluation rounds.
|
|
16
|
+
Two-tier principle: **content surfaces follow context; content markers
|
|
17
|
+
and actions declare their own status.**
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- `.mote-table-scroll` sticky-header borders: Chromium paints collapsed
|
|
22
|
+
borders at the original flow position, not with the sticky cell —
|
|
23
|
+
switched to `border-collapse: separate; border-spacing: 0` inside the
|
|
24
|
+
wrapper.
|
|
25
|
+
- `.mote-table-scroll` clips rows in print: `max-height: none;
|
|
26
|
+
overflow: visible` added to the `@media print` block.
|
|
27
|
+
- Bare `<pre>` without `<code>` now gets the mono stack and 0.875rem size.
|
|
28
|
+
- `.mote-btn` now reads `var(--mote-control-pad, …)` instead of hardcoded
|
|
29
|
+
`0.5rem 1.1rem` — density overrides reach all buttons uniformly.
|
|
30
|
+
- Form controls (input/select/textarea) now read the same density tokens
|
|
31
|
+
as buttons: `var(--mote-control-pad, …) var(--mote-control-pad-inline, …)`.
|
|
32
|
+
- `.mote-stack` now stretches `progress` and `meter` alongside fields.
|
|
33
|
+
- `.mote-doc > aside` resets to `position: static` under 50rem (was
|
|
34
|
+
staying sticky while the nav went static — clipped scroll region on mobile).
|
|
35
|
+
- `.mote-table-scroll` max-height tokenized: `var(--mote-table-max, 60vh)`.
|
|
36
|
+
- Badge links get a hover state: `filter: brightness(0.92)`.
|
|
37
|
+
- Docs: theme-toggle snippet now 3-state (auto→light→dark) matching the
|
|
38
|
+
working demo; Patterns error-page uses `.mote-hero`; docs' own header
|
|
39
|
+
uses `.mote-row`/`.mote-push` instead of inline styles.
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- `.mote-hero`: vertically centers content in the remaining viewport
|
|
44
|
+
height — for error pages, login screens, empty states. Uses
|
|
45
|
+
`--mote-hero-offset` (default 12rem) to account for header/footer.
|
|
46
|
+
- `.mote-card-media`: flush-top cover images for cards — negative margins,
|
|
47
|
+
clipped overflow, radius matched to the card, all in one class. Replaces
|
|
48
|
+
the 5-line page recipe that broke card corners.
|
|
49
|
+
- `.mote-brand`: quiet wordmark link for site headers — `font-weight: 700`,
|
|
50
|
+
fg color, no underline.
|
|
51
|
+
- `.mote-num`: right-aligned tabular figures for data table columns.
|
|
52
|
+
|
|
53
|
+
### Changed (evaluation)
|
|
54
|
+
|
|
55
|
+
- Fourth ten-app evaluation completed against v0.6.1; all round-3 fixes
|
|
56
|
+
verified holding. Round-4 findings addressed in this minor release.
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- `.mote-print-only` now actually displays in print (the unconditional
|
|
61
|
+
`display: none` was after the print block at equal specificity —
|
|
62
|
+
scoped to `@media not print` and moved before it).
|
|
63
|
+
- `.mote-stack` no longer stretches `.mote-sr-only` inputs to 100%
|
|
64
|
+
width (hidden file inputs were creating invisible horizontal scroll).
|
|
65
|
+
- `.mote-doc > main` now uses `overflow-x: auto` (was `clip`, which
|
|
66
|
+
made wide tables invisible rather than scrollable).
|
|
67
|
+
- `.mote-theme-switch` shipped in mote.css: disables transitions during
|
|
68
|
+
`data-theme` flips so Chromium doesn't wedge elements at stale colors
|
|
69
|
+
(custom-property changes don't restart CSS transitions). The docs'
|
|
70
|
+
toggle snippet now includes it; the demo uses it.
|
|
71
|
+
- `.mote-doc > aside` gets the same sticky treatment as the nav rail
|
|
72
|
+
(top, max-height, overflow) — TOCs and aside content no longer scroll
|
|
73
|
+
out of view.
|
|
74
|
+
- Nav rail `max-height` accounts for `--mote-rail-top` (was
|
|
75
|
+
`calc(100svh - 2rem)` regardless of header height).
|
|
76
|
+
- Rail heading treatment (small uppercase labels) now applies to
|
|
77
|
+
`.mote-doc > aside` and `nav[aria-label="toc"]` headings too.
|
|
78
|
+
- `legend` gets `font-weight: 600` so the group caption reads stronger
|
|
79
|
+
than the field labels inside it.
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- `tabular-nums` on all `td` — figures align in data tables without
|
|
84
|
+
any page CSS (invisible on non-numeric content).
|
|
85
|
+
- `.mote-table-scroll`: scrollable table wrapper with sticky `thead`,
|
|
86
|
+
no margin jump on scroll start, and no page-level horizontal scroll.
|
|
87
|
+
- `.mote-grid-sparse`: auto-fit variant that collapses empty grid
|
|
88
|
+
tracks (footers, short card rows).
|
|
89
|
+
- `--mote-control-pad` / `--mote-control-pad-inline` and
|
|
90
|
+
`--mote-cell-pad` / `--mote-cell-pad-inline` density tokens.
|
|
91
|
+
- Docs: toggle snippet includes the theme-switch workaround; Chromium
|
|
92
|
+
note references the shipped class.
|
|
93
|
+
|
|
94
|
+
### Changed
|
|
95
|
+
|
|
96
|
+
- Third ten-app evaluation completed against v0.6.0; all round-2 fixes
|
|
97
|
+
verified holding. Round-3 findings addressed in this patch release.
|
|
9
98
|
|
|
10
99
|
### Fixed
|
|
11
100
|
|
|
@@ -335,6 +424,8 @@ Components:
|
|
|
335
424
|
- Element gallery demo page (`demo.html`).
|
|
336
425
|
|
|
337
426
|
[0.3.0]: https://gitlab.com/abmach/mote/compare/v0.2.1...v0.3.0
|
|
427
|
+
[0.7.0]: https://gitlab.com/abmach/mote/compare/v0.6.1...v0.7.0
|
|
428
|
+
[0.6.1]: https://gitlab.com/abmach/mote/compare/v0.6.0...v0.6.1
|
|
338
429
|
[0.6.0]: https://gitlab.com/abmach/mote/compare/v0.5.1...v0.6.0
|
|
339
430
|
[0.5.1]: https://gitlab.com/abmach/mote/compare/v0.5.0...v0.5.1
|
|
340
431
|
[0.5.0]: https://gitlab.com/abmach/mote/compare/v0.4.0...v0.5.0
|
package/README.md
CHANGED
|
@@ -100,6 +100,8 @@ The consequence: theming is a handful of variable overrides, and an inline tweak
|
|
|
100
100
|
| `--mote-display` | `clamp(2.75rem, 1.5rem + 4vw, 5rem)` | | Display text scale (opt-in) |
|
|
101
101
|
| `--mote-grid-min` | `16rem` | | Card grid minimum track width |
|
|
102
102
|
| `--mote-avatar` | `2.5rem` | | Avatar size |
|
|
103
|
+
| `--mote-control-pad` | `0.5rem` | | Button/control vertical padding |
|
|
104
|
+
| `--mote-cell-pad` | `0.6rem` | | Table cell vertical padding |
|
|
103
105
|
| `--mote-shadow` / `--mote-shadow-sm` | warm diffuse | | Elevation |
|
|
104
106
|
| `--mote-transition` | `150ms ease` | | Hover/focus timing |
|
|
105
107
|
|
|
@@ -149,19 +151,29 @@ mote is class-optional by design — elements are styled from tags alone; these
|
|
|
149
151
|
| Semantic buttons (gated) | `class="mote-success"` etc. on the button itself — themed sections never recolor actions |
|
|
150
152
|
| Ghost buttons | `.mote-ghost` — transparent fill; status tints from the button's own class (gated like solids) |
|
|
151
153
|
| Solid button on any element | `.mote-btn` — the full solid recipe for anchors, spans; status classes gated |
|
|
154
|
+
| Hero centering | `.mote-hero` — vertically centers content for error/login/empty-state pages |
|
|
155
|
+
| Card cover media | `.mote-card-media` — flush-top cover images with matched radius |
|
|
156
|
+
| Brand/wordmark | `.mote-brand` — quiet non-nav link for site headers |
|
|
152
157
|
| Media objects | `.mote-media` — avatar/icon beside body (flex, last child grows) |
|
|
153
158
|
| Display text | `.mote-display` — opt-in hero/error-code scale via `--mote-display` |
|
|
154
159
|
| Content rows | `.mote-row` + `.mote-push` — flex row, right-align helper |
|
|
160
|
+
| Stacked forms | `.mote-stack` — opt-in full-width fields, checkboxes stay 1em |
|
|
161
|
+
| Scrollable tables | `.mote-table-scroll` — sticky `thead`, no page scroll, no margin jump |
|
|
162
|
+
| Numeric columns | `.mote-num` — right-aligned tabular figures |
|
|
163
|
+
| Sparse grids | `.mote-grid-sparse` — auto-fit variant, collapses empty tracks |
|
|
155
164
|
| Pagination | `nav[aria-label="pagination"]` — semantic, no class |
|
|
156
165
|
| Table of contents | `nav[aria-label="toc"]` — semantic, no class |
|
|
157
166
|
| Footer baseline | `body > footer` — semantic top-border + padding |
|
|
158
167
|
| Screen-reader helper | `.mote-sr-only` (doubles as a skip link when focused) |
|
|
159
168
|
| Print helpers | `.mote-no-print` / `.mote-print-only` |
|
|
169
|
+
| Theme-switch guard | `.mote-theme-switch` — prevents Chromium stale-color bug on `data-theme` flips |
|
|
160
170
|
| Status inheritance control | `.mote-default` (force accent) · `.mote-reset` (clear inherited status) |
|
|
171
|
+
| Hero offset | `--mote-hero-offset` (default 12rem) — space for header/footer in `.mote-hero` |
|
|
172
|
+
| Table max height | `--mote-table-max` (default 60vh) — `.mote-table-scroll` panel cap |
|
|
161
173
|
| Breadcrumbs | `nav[aria-label="breadcrumb"]` — semantic, no class |
|
|
162
174
|
| Card grids | `.mote-grid` — auto-fill columns from the container, no breakpoints |
|
|
163
175
|
| Cards | `.mote-card` |
|
|
164
|
-
| Badges | `.mote-badge`
|
|
176
|
+
| Badges | `.mote-badge` — gated: status from the badge's own class, never inherited |
|
|
165
177
|
| Avatars | `.mote-avatar` |
|
|
166
178
|
| Skeleton / spinner | `.mote-skeleton`, `.mote-spinner` |
|
|
167
179
|
| Tooltips | `[popover].mote-tooltip` + `popovertarget` button |
|
|
@@ -183,7 +195,7 @@ animations become instant, on older engines.
|
|
|
183
195
|
|
|
184
196
|
## Demo
|
|
185
197
|
|
|
186
|
-
Open [`docs/index.html`](docs/index.html) for the full live documentation, or [`demo.html`](demo.html) for a quick gallery of every styled element.
|
|
198
|
+
Open [`docs/index.html`](docs/index.html) for the full live documentation, or [`docs/demo.html`](docs/demo.html) for a quick gallery of every styled element.
|
|
187
199
|
|
|
188
200
|
## License
|
|
189
201
|
|
package/mote.components.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* mote.components.css — opt-in components for mote.css.
|
|
3
|
-
* v0.
|
|
3
|
+
* v0.7.0 · MIT
|
|
4
4
|
* https://gitlab.com/abmach/mote · mirror: https://github.com/abmach/mote
|
|
5
5
|
*
|
|
6
6
|
* Requires mote.css loaded first (provides the --mote-* tokens).
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
* <span class="mote-badge mote-success">success</span>
|
|
41
41
|
* ------------------------------------------------------------------------- */
|
|
42
42
|
|
|
43
|
+
/* Badges are content markers, not surfaces — they declare their own
|
|
44
|
+
status, never inherit it from context (same gating as buttons).
|
|
45
|
+
A plain .mote-badge is always accent-tinted; a status class on the
|
|
46
|
+
badge itself provides the tint. */
|
|
43
47
|
.mote-badge {
|
|
44
48
|
display: inline-block;
|
|
45
49
|
padding: 0.1rem 0.6rem;
|
|
@@ -47,8 +51,13 @@
|
|
|
47
51
|
font-size: 0.8em;
|
|
48
52
|
font-weight: 500;
|
|
49
53
|
line-height: 1.4;
|
|
50
|
-
background: var(--mote-
|
|
51
|
-
color: var(--mote-
|
|
54
|
+
background: var(--mote-accent-soft);
|
|
55
|
+
color: var(--mote-accent-deep);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.mote-badge:where(.mote-success, .mote-warning, .mote-error, .mote-info, .mote-muted) {
|
|
59
|
+
background: var(--mote-status-soft);
|
|
60
|
+
color: var(--mote-status);
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
/* Badges as links (tag chips, version pills): kill the underline */
|
|
@@ -56,6 +65,10 @@ a:where(.mote-badge) {
|
|
|
56
65
|
text-decoration: none;
|
|
57
66
|
}
|
|
58
67
|
|
|
68
|
+
a:where(.mote-badge):hover {
|
|
69
|
+
filter: brightness(0.92);
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
/* ---------------------------------------------------------------------------
|
|
60
73
|
* 3. Avatars
|
|
61
74
|
* ------------------------------------------------------------------------- */
|
|
@@ -245,6 +258,44 @@ nav[aria-label="toc"] a:hover {
|
|
|
245
258
|
color: var(--mote-accent-deep);
|
|
246
259
|
}
|
|
247
260
|
|
|
261
|
+
/* Flush-top cover media for cards: negative margins derived from the
|
|
262
|
+
card's own padding, clipped overflow, radius matched to the card. */
|
|
263
|
+
.mote-card-media {
|
|
264
|
+
margin: -1.25rem -1.5rem 1rem;
|
|
265
|
+
overflow: clip;
|
|
266
|
+
border-radius: calc(var(--mote-radius-lg) - var(--mote-border-width))
|
|
267
|
+
calc(var(--mote-radius-lg) - var(--mote-border-width)) 0 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.mote-card-media img,
|
|
271
|
+
.mote-card-media video {
|
|
272
|
+
display: block;
|
|
273
|
+
width: 100%;
|
|
274
|
+
max-width: none;
|
|
275
|
+
border-radius: inherit;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* Scrollable table wrapper: sticky thead, no page scroll, no margin jump */
|
|
279
|
+
.mote-table-scroll {
|
|
280
|
+
overflow-x: auto;
|
|
281
|
+
max-height: var(--mote-table-max, 60vh);
|
|
282
|
+
overflow-y: auto;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/* Chromium paints collapsed borders at the original flow position,
|
|
286
|
+
not with the sticky cell — separate borders belong to the cell. */
|
|
287
|
+
.mote-table-scroll table {
|
|
288
|
+
margin-block: 0;
|
|
289
|
+
border-collapse: separate;
|
|
290
|
+
border-spacing: 0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.mote-table-scroll thead th {
|
|
294
|
+
position: sticky;
|
|
295
|
+
top: 0;
|
|
296
|
+
background: var(--mote-bg);
|
|
297
|
+
}
|
|
298
|
+
|
|
248
299
|
/* Page footer: the quiet sibling of the site header */
|
|
249
300
|
:where(body > footer, .mote-footer) {
|
|
250
301
|
margin-block-start: 3rem;
|
|
@@ -502,7 +553,7 @@ html:where(:has(body > header)) {
|
|
|
502
553
|
/* Content stays inside the grid track — wide tables scroll here,
|
|
503
554
|
not the page. */
|
|
504
555
|
.mote-doc > main {
|
|
505
|
-
overflow-x:
|
|
556
|
+
overflow-x: auto;
|
|
506
557
|
}
|
|
507
558
|
|
|
508
559
|
/* nav = left rail */
|
|
@@ -513,7 +564,7 @@ html:where(:has(body > header)) {
|
|
|
513
564
|
align-self: start;
|
|
514
565
|
position: sticky;
|
|
515
566
|
top: var(--mote-rail-top, 1rem);
|
|
516
|
-
max-height: calc(100svh -
|
|
567
|
+
max-height: calc(100svh - var(--mote-rail-top, 1rem) - 1rem);
|
|
517
568
|
overflow: auto;
|
|
518
569
|
}
|
|
519
570
|
|
|
@@ -550,7 +601,9 @@ html:where(:has(body > header)) {
|
|
|
550
601
|
}
|
|
551
602
|
|
|
552
603
|
/* Rail headings: small label-scale for grouped navigation */
|
|
553
|
-
.mote-doc > nav :is(h2, h3)
|
|
604
|
+
.mote-doc > nav :is(h2, h3),
|
|
605
|
+
.mote-doc > aside :is(h2, h3),
|
|
606
|
+
nav[aria-label="toc"] :is(h2, h3) {
|
|
554
607
|
margin: 1rem 0 0.3rem;
|
|
555
608
|
padding-inline: 0.75rem;
|
|
556
609
|
font-size: 0.72rem;
|
|
@@ -574,6 +627,10 @@ html:where(:has(body > header)) {
|
|
|
574
627
|
grid-column: 2;
|
|
575
628
|
min-width: 0;
|
|
576
629
|
align-self: start;
|
|
630
|
+
position: sticky;
|
|
631
|
+
top: var(--mote-rail-top, 1rem);
|
|
632
|
+
max-height: calc(100svh - var(--mote-rail-top, 1rem) - 1rem);
|
|
633
|
+
overflow: auto;
|
|
577
634
|
}
|
|
578
635
|
|
|
579
636
|
.mote-doc:where(:has(> nav)) > aside {
|
|
@@ -600,6 +657,12 @@ html:where(:has(body > header)) {
|
|
|
600
657
|
grid-row: auto;
|
|
601
658
|
}
|
|
602
659
|
|
|
660
|
+
.mote-doc > aside {
|
|
661
|
+
position: static;
|
|
662
|
+
max-height: none;
|
|
663
|
+
overflow: visible;
|
|
664
|
+
}
|
|
665
|
+
|
|
603
666
|
.mote-doc > nav {
|
|
604
667
|
position: static;
|
|
605
668
|
max-height: none;
|
|
@@ -616,3 +679,8 @@ html:where(:has(body > header)) {
|
|
|
616
679
|
gives 3-wide pricing; 26rem gives 2-column content. */
|
|
617
680
|
grid-template-columns: repeat(auto-fill, minmax(min(var(--mote-grid-min, 16rem), 100%), 1fr));
|
|
618
681
|
}
|
|
682
|
+
|
|
683
|
+
/* Sparse grids: collapse empty tracks (footers, short card rows) */
|
|
684
|
+
.mote-grid-sparse {
|
|
685
|
+
grid-template-columns: repeat(auto-fit, minmax(min(var(--mote-grid-min, 16rem), 100%), 1fr));
|
|
686
|
+
}
|
package/mote.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* mote.css — a mote of styling for plain HTML.
|
|
3
|
-
* v0.
|
|
3
|
+
* v0.7.0 · MIT
|
|
4
4
|
* https://gitlab.com/abmach/mote · mirror: https://github.com/abmach/mote
|
|
5
5
|
*
|
|
6
6
|
* The smallest thing that can carry style:
|
|
@@ -219,7 +219,7 @@ a {
|
|
|
219
219
|
transition: color var(--mote-transition), text-decoration-color var(--mote-transition);
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
a:hover {
|
|
222
|
+
a:hover:where(:not(.mote-btn, .mote-ghost)) {
|
|
223
223
|
color: var(--mote-accent-deep);
|
|
224
224
|
text-decoration-color: currentColor;
|
|
225
225
|
}
|
|
@@ -335,6 +335,8 @@ kbd {
|
|
|
335
335
|
pre {
|
|
336
336
|
padding: 1rem 1.2rem;
|
|
337
337
|
overflow-x: auto;
|
|
338
|
+
font-family: var(--mote-font-mono);
|
|
339
|
+
font-size: 0.875rem;
|
|
338
340
|
border-radius: var(--mote-radius);
|
|
339
341
|
background: var(--mote-surface);
|
|
340
342
|
border: var(--mote-border-width) solid var(--mote-border);
|
|
@@ -372,7 +374,8 @@ caption {
|
|
|
372
374
|
}
|
|
373
375
|
|
|
374
376
|
th, td {
|
|
375
|
-
|
|
377
|
+
font-variant-numeric: tabular-nums;
|
|
378
|
+
padding: var(--mote-cell-pad, 0.6rem) var(--mote-cell-pad-inline, 0.8rem);
|
|
376
379
|
border-block-end: var(--mote-border-width) solid var(--mote-border);
|
|
377
380
|
text-align: start;
|
|
378
381
|
vertical-align: top;
|
|
@@ -409,12 +412,12 @@ fieldset {
|
|
|
409
412
|
border-radius: var(--mote-radius);
|
|
410
413
|
}
|
|
411
414
|
|
|
412
|
-
legend { padding-inline: 0.4rem; }
|
|
415
|
+
legend { padding-inline: 0.4rem; font-weight: 600; }
|
|
413
416
|
|
|
414
417
|
input, select, textarea {
|
|
415
418
|
font: inherit;
|
|
416
419
|
color: inherit;
|
|
417
|
-
padding: 0.5rem 0.75rem;
|
|
420
|
+
padding: var(--mote-control-pad, 0.5rem) var(--mote-control-pad-inline, 0.75rem);
|
|
418
421
|
background: var(--mote-surface);
|
|
419
422
|
border: var(--mote-border-width) solid var(--mote-border);
|
|
420
423
|
border-radius: var(--mote-radius-sm);
|
|
@@ -501,7 +504,7 @@ button, [type="button"], [type="submit"], [type="reset"] {
|
|
|
501
504
|
font: inherit;
|
|
502
505
|
font-weight: 500;
|
|
503
506
|
color: var(--mote-on-accent);
|
|
504
|
-
padding: 0.5rem 1.1rem;
|
|
507
|
+
padding: var(--mote-control-pad, 0.5rem) var(--mote-control-pad-inline, 1.1rem);
|
|
505
508
|
background: var(--mote-accent);
|
|
506
509
|
border: var(--mote-border-width) solid transparent;
|
|
507
510
|
border-radius: var(--mote-radius-sm);
|
|
@@ -532,10 +535,13 @@ button:hover, [type="button"]:hover, [type="submit"]:hover, [type="reset"]:hover
|
|
|
532
535
|
/* Ghost buttons: quiet, transparent fill, accent-tinted. Like solids,
|
|
533
536
|
status colors come from the button's own class, never from context. */
|
|
534
537
|
.mote-ghost {
|
|
538
|
+
display: inline-block;
|
|
539
|
+
font: inherit;
|
|
540
|
+
font-weight: 500;
|
|
535
541
|
background: none;
|
|
536
542
|
border: var(--mote-border-width) solid color-mix(in oklab, var(--mote-accent), transparent 55%);
|
|
537
543
|
color: var(--mote-accent-deep);
|
|
538
|
-
padding: 0.5rem 1.1rem;
|
|
544
|
+
padding: var(--mote-control-pad, 0.5rem) var(--mote-control-pad-inline, 1.1rem);
|
|
539
545
|
border-radius: var(--mote-radius-sm);
|
|
540
546
|
text-decoration: none;
|
|
541
547
|
cursor: pointer;
|
|
@@ -662,9 +668,20 @@ progress, meter {
|
|
|
662
668
|
|
|
663
669
|
.mote-push { margin-inline-start: auto; }
|
|
664
670
|
|
|
671
|
+
/* Hero: vertically center content in the remaining viewport height.
|
|
672
|
+
For error pages, login screens, empty states. */
|
|
673
|
+
.mote-hero {
|
|
674
|
+
min-height: calc(100svh - var(--mote-hero-offset, 12rem));
|
|
675
|
+
display: flex;
|
|
676
|
+
flex-direction: column;
|
|
677
|
+
justify-content: center;
|
|
678
|
+
align-items: center;
|
|
679
|
+
text-align: center;
|
|
680
|
+
}
|
|
681
|
+
|
|
665
682
|
/* Stacked forms: stretch fields, keep checkboxes/radios compact.
|
|
666
683
|
An opt-in alternative to the page-global width: 100% recipe. */
|
|
667
|
-
.mote-stack :is(input, select, textarea) {
|
|
684
|
+
.mote-stack :is(input, select, textarea, progress, meter) {
|
|
668
685
|
width: 100%;
|
|
669
686
|
}
|
|
670
687
|
|
|
@@ -672,6 +689,10 @@ progress, meter {
|
|
|
672
689
|
width: 1em;
|
|
673
690
|
}
|
|
674
691
|
|
|
692
|
+
.mote-stack :is(input, select, textarea):where(.mote-sr-only) {
|
|
693
|
+
width: 1px;
|
|
694
|
+
}
|
|
695
|
+
|
|
675
696
|
/* Solid button on any element — anchors, spans, divs.
|
|
676
697
|
Same recipe as the element-level button styles; status classes
|
|
677
698
|
gated identically (class on the element itself). */
|
|
@@ -680,7 +701,7 @@ progress, meter {
|
|
|
680
701
|
font: inherit;
|
|
681
702
|
font-weight: 500;
|
|
682
703
|
color: var(--mote-on-accent);
|
|
683
|
-
padding: 0.5rem 1.1rem;
|
|
704
|
+
padding: var(--mote-control-pad, 0.5rem) var(--mote-control-pad-inline, 1.1rem);
|
|
684
705
|
background: var(--mote-accent);
|
|
685
706
|
border: var(--mote-border-width) solid transparent;
|
|
686
707
|
border-radius: var(--mote-radius-sm);
|
|
@@ -727,6 +748,19 @@ progress, meter {
|
|
|
727
748
|
}
|
|
728
749
|
|
|
729
750
|
/* Visually hidden, screen-reader available */
|
|
751
|
+
/* Brand/wordmark: quiet non-nav link for site headers */
|
|
752
|
+
.mote-brand {
|
|
753
|
+
font-weight: 700;
|
|
754
|
+
color: var(--mote-fg);
|
|
755
|
+
text-decoration: none;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/* Numeric table column: right-align tabular figures */
|
|
759
|
+
.mote-num {
|
|
760
|
+
text-align: end;
|
|
761
|
+
font-variant-numeric: tabular-nums;
|
|
762
|
+
}
|
|
763
|
+
|
|
730
764
|
.mote-sr-only {
|
|
731
765
|
position: absolute;
|
|
732
766
|
width: 1px;
|
|
@@ -866,6 +900,18 @@ progress, meter {
|
|
|
866
900
|
/* Opt-in print helpers */
|
|
867
901
|
.mote-no-print { display: none !important; }
|
|
868
902
|
.mote-print-only { display: block; }
|
|
903
|
+
.mote-table-scroll { max-height: none; overflow: visible; }
|
|
869
904
|
}
|
|
870
905
|
|
|
871
|
-
|
|
906
|
+
@media not print {
|
|
907
|
+
.mote-print-only { display: none; }
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/* Theme switch: disable transitions during data-theme flips.
|
|
911
|
+
Chromium doesn't restart CSS transitions on custom-property changes,
|
|
912
|
+
so flipping data-theme leaves elements at the old theme's colors.
|
|
913
|
+
Apply this class before the flip, remove after one frame. */
|
|
914
|
+
.mote-theme-switch,
|
|
915
|
+
.mote-theme-switch * {
|
|
916
|
+
transition: none !important;
|
|
917
|
+
}
|