mote.css 0.4.0 → 0.5.1
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 +112 -4
- package/README.md +13 -5
- package/mote.components.css +49 -3
- package/mote.css +121 -8
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,115 @@ 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.5.1] - 2026-10-20
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Pagination: the current page (`aria-current`) kept its pill state on
|
|
13
|
+
hover — previously the generic link hover overrode the accent pill,
|
|
14
|
+
making "you are here" indistinguishable from hovering any other page.
|
|
15
|
+
The current page now deepens on hover (same accent-mix pattern as solid
|
|
16
|
+
buttons); non-current links keep the soft-tint hover. Docs recommend a
|
|
17
|
+
`<span>` for the current page (you are already there — not a link).
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Logo: a cinematic photograph of a single dust mote floating in warm
|
|
22
|
+
golden sunbeams (docs/img/mote-logo.jpg), integrated into the docs hero.
|
|
23
|
+
- Repositioned from "classless" to "class-optional" throughout — more
|
|
24
|
+
honest now that the library ships ~25 opt-in classes for statuses,
|
|
25
|
+
components, helpers, and layout. The core promise is unchanged:
|
|
26
|
+
zero classes required, semantic elements are the default.
|
|
27
|
+
- Pagination documentation: code sample and live example in the Layout
|
|
28
|
+
section, alongside the breadcrumbs it mirrors.
|
|
29
|
+
|
|
30
|
+
## [0.5.0] - 2026-10-20
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- Semantic buttons: solid buttons take a status class (`.mote-success`,
|
|
35
|
+
`.mote-warning`, `.mote-error`, `.mote-info`, `.mote-muted`) — gated, so
|
|
36
|
+
the class must be on the button itself. Themed sections (error notes,
|
|
37
|
+
toasts, page-level status) never recolor the actions inside them; the
|
|
38
|
+
intent of an action is declared at the action site. Text color on
|
|
39
|
+
semantic solids is `--mote-on-status` (set by the status classes to the
|
|
40
|
+
page color, AA-verified in both themes).
|
|
41
|
+
- Ghost buttons (`.mote-ghost`): transparent fill, status-tinted border
|
|
42
|
+
and text. Gated like solids — the status class on the element itself
|
|
43
|
+
provides the tint, never the surrounding context.
|
|
44
|
+
- `.mote-default` and `.mote-reset`: control status inheritance for
|
|
45
|
+
the non-gated consumers (badges, notes, spinners, …). Default forces the
|
|
46
|
+
accent down the tree; reset clears the inherited status so each
|
|
47
|
+
element's own classes decide.
|
|
48
|
+
- `.mote-row` + `.mote-push`: flex row helper + right-align helper —
|
|
49
|
+
for headers, footers, toolbars, chip lists, form rows.
|
|
50
|
+
- `.mote-display` + `--mote-display` token: opt-in display/hero scale.
|
|
51
|
+
- `--mote-grid-min` variable on `.mote-grid`: density without a class API.
|
|
52
|
+
- `.mote-sr-only`: visually-hidden helper; doubles as a skip link when
|
|
53
|
+
focused.
|
|
54
|
+
- Semantic pagination: `nav[aria-label="pagination"]` — flex row of
|
|
55
|
+
pills with `aria-current` state, no class (mirrors breadcrumbs).
|
|
56
|
+
- Footer baseline: `body > footer` gets a top border and block padding
|
|
57
|
+
(the quiet sibling of the site header).
|
|
58
|
+
- `.mote-card` is now `display: flex; flex-direction: column` —
|
|
59
|
+
CTA-in-bottom-of-card aligns with `margin-block-start: auto` for free.
|
|
60
|
+
- Theme-aware hover deepening for buttons: `color-mix(accent/status,
|
|
61
|
+
fg 14%)` — darkens in light themes, brightens in dark ones.
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- Docs: buttons and statuses section (gating rationale, ghost inheritance),
|
|
66
|
+
`.mote-default`/`.mote-reset` guidance, new component table entries.
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
Layout shell (`mote.components.css`), from the ten-app evaluation:
|
|
71
|
+
- `.mote-doc` mobile: nav/main/aside overlapped in one grid cell — the
|
|
72
|
+
collapse media query now resets `grid-row: auto`.
|
|
73
|
+
- `.mote-doc` blowout on wide content: content tracks are `minmax(0, 1fr)`
|
|
74
|
+
(+ `min-width: 0` on items); a wide table scrolls inside `main`, never the page.
|
|
75
|
+
- Rail nav no longer renders as the horizontal pill row: pill styles scoped
|
|
76
|
+
to `body > header nav`; rails get a quiet vertical list with
|
|
77
|
+
`aria-current` states.
|
|
78
|
+
Sticky rails and anchored content clear the site header via
|
|
79
|
+
`--mote-rail-top` (token) and automatic `scroll-padding` when
|
|
80
|
+
`body > header` exists. `body.mote-doc` gains page gutters.
|
|
81
|
+
|
|
82
|
+
Core (`mote.css`):
|
|
83
|
+
- `:user-invalid` kept its error border through hover and focus
|
|
84
|
+
(`:is(input, select, textarea):user-invalid`, placed to win the cascade) —
|
|
85
|
+
previously the field the user must fix showed the accent focus border.
|
|
86
|
+
- `--mote-accent-deep` now brightens in dark mode (`color-mix(accent,
|
|
87
|
+
white 14%)`); dark hovers, badges and notes no longer dim.
|
|
88
|
+
- `input[type="range"]` stripped of text-input chrome; `select[multiple]`
|
|
89
|
+
restored to native listbox appearance.
|
|
90
|
+
- `[role="status"]` / `[role="alert"]` read `--mote-status` (semantic
|
|
91
|
+
colors as fallback) instead of hard-coding.
|
|
92
|
+
- `.mote-note` gains block margin; `.mote-badge` line-height tamed in
|
|
93
|
+
headings; `blockquote` code no longer italic; `.mote-card` first/last-child
|
|
94
|
+
rules moved into `:where()` so page classes win; dialogs get
|
|
95
|
+
`max-width: min(90vw, 44rem)`; `.mote-avatar` sized by
|
|
96
|
+
`--mote-avatar` token; `.mote-skeleton` gets intrinsic size.
|
|
97
|
+
- Print: the light palette is forced on paper — dark fills (zebra, notes,
|
|
98
|
+
open details) no longer print as near-black bands.
|
|
99
|
+
- Focus rings no longer fade in (box-shadow removed from transitions).
|
|
100
|
+
|
|
101
|
+
Components:
|
|
102
|
+
- Popovers and dialogs now animate on exit, not just entrance
|
|
103
|
+
(closed-state deltas for the `allow-discrete` transitions).
|
|
104
|
+
- `details[name]` content padding fixed for multiple children
|
|
105
|
+
(was padding every child; now only the last).
|
|
106
|
+
- Toasts documented with `popover="manual"` (auto popovers light-dismiss);
|
|
107
|
+
samples corrected.
|
|
108
|
+
|
|
109
|
+
### Changed
|
|
110
|
+
|
|
111
|
+
- README and docs CDN snippets use `mote.css@0` (range pin) so they never go
|
|
112
|
+
stale; exact-version pinning documented for reproducible builds.
|
|
113
|
+
- Docs: wide-table wrapper recipe, form-width guidance, document-shell
|
|
114
|
+
real-page notes (gutters, rail-top token), print caveats for exclusive
|
|
115
|
+
accordions, toast stacking guidance; section numbering fixed.
|
|
116
|
+
|
|
8
117
|
## [0.4.0] - 2026-10-20
|
|
9
118
|
|
|
10
119
|
### Fixed
|
|
@@ -165,11 +274,10 @@ Components:
|
|
|
165
274
|
- Element gallery demo page (`demo.html`).
|
|
166
275
|
|
|
167
276
|
[0.3.0]: https://gitlab.com/abmach/mote/compare/v0.2.1...v0.3.0
|
|
277
|
+
[0.5.1]: https://gitlab.com/abmach/mote/compare/v0.5.0...v0.5.1
|
|
278
|
+
[0.5.0]: https://gitlab.com/abmach/mote/compare/v0.4.0...v0.5.0
|
|
168
279
|
[0.4.0]: https://gitlab.com/abmach/mote/compare/v0.3.0...v0.4.0
|
|
280
|
+
[0.3.0]: https://gitlab.com/abmach/mote/compare/v0.2.1...v0.3.0
|
|
169
281
|
[0.2.1]: https://gitlab.com/abmach/mote/compare/v0.2.0...v0.2.1
|
|
170
282
|
[0.2.0]: https://gitlab.com/abmach/mote/compare/v0.1.0...v0.2.0
|
|
171
283
|
[0.1.0]: https://gitlab.com/abmach/mote/-/tags/v0.1.0
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
Copyright (c) 2026 Arthur Biazon Machado. All rights reserved.
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# mote.css
|
|
2
2
|
|
|
3
|
-
> The smallest thing that can carry style — a tiny, semantic,
|
|
3
|
+
> The smallest thing that can carry style — a tiny, semantic, class-optional CSS layer for plain HTML.
|
|
4
4
|
|
|
5
|
-
A mote of styling for plain HTML: **zero dependencies, zero build step, zero classes required
|
|
5
|
+
A mote of styling for plain HTML: **zero dependencies, zero build step, zero classes required** — but opt-in classes exist for statuses, components, and layout when you want them. Write semantic HTML, drop in one file, and it looks like a place you'd want to stay a while — modern, warm, unobtrusive. Inspired by the quiet excellence of [oat](https://github.com/knadh/oat), with its own cozy voice.
|
|
6
6
|
|
|
7
7
|
Source on [GitLab](https://gitlab.com/abmach/mote) · mirrored on [GitHub](https://github.com/abmach/mote).
|
|
8
8
|
|
|
@@ -23,7 +23,7 @@ Source on [GitLab](https://gitlab.com/abmach/mote) · mirrored on [GitHub](https
|
|
|
23
23
|
|
|
24
24
|
## Principles
|
|
25
25
|
|
|
26
|
-
- **Semantic HTML is the API.** mote styles elements by what they *are* — headings, forms, `dialog`, `menu` — not by the classes they wear.
|
|
26
|
+
- **Semantic HTML is the API.** mote styles elements by what they *are* — headings, forms, `dialog`, `menu` — not by the classes they wear. Zero classes are required; optional classes exist as opt-in conveniences for statuses, components, and helpers.
|
|
27
27
|
- **The platform before the library.** Interactive components ride on native features: `popover`, `dialog`, `<details name>`, `:user-invalid`. Where the browser can do it, mote never ships JavaScript to do it worse.
|
|
28
28
|
- **Tokens all the way down.** Every color, radius, shadow, font and status is a `--mote-*` custom property, and derived tones are computed with `color-mix()`. Status classes set tokens and nothing else — one override re-skins every note, badge and toast. Re-theme by overriding variables, never by fighting selectors.
|
|
29
29
|
- **Weightless by default.** `mote.css` styles your elements; `mote.components.css` is opt-in and CSS-only. You ship zero bytes of library JavaScript, ever.
|
|
@@ -125,7 +125,7 @@ Or self-host with `npm install @fontsource-variable/inter @fontsource/commit-mon
|
|
|
125
125
|
|
|
126
126
|
## Opt-in helpers
|
|
127
127
|
|
|
128
|
-
mote is
|
|
128
|
+
mote is class-optional by design — elements are styled from tags alone; these classes are opt-in conveniences, never a required API:
|
|
129
129
|
|
|
130
130
|
| Class | Purpose |
|
|
131
131
|
|---|---|
|
|
@@ -141,7 +141,15 @@ mote is classless by design; these are the only escape hatches, plus status clas
|
|
|
141
141
|
| Component | Hook |
|
|
142
142
|
|---|---|
|
|
143
143
|
| Document layout (landmark grid) | `.mote-doc` on `<body>` — `:has()` reads your `header`/`nav`/`main`/`aside`/`footer` |
|
|
144
|
-
| Sticky site header / nav pills | `body > header` —
|
|
144
|
+
| Sticky site header / nav pills | `body > header` — semantic; `.mote-header`/`.mote-nav` only for shells wrapped in a `<div>` |
|
|
145
|
+
| Semantic buttons (gated) | `class="mote-success"` etc. on the button itself — themed sections never recolor actions |
|
|
146
|
+
| Ghost buttons | `.mote-ghost` — transparent fill; status tints from the button's own class (gated like solids) |
|
|
147
|
+
| Display text | `.mote-display` — opt-in hero/error-code scale via `--mote-display` |
|
|
148
|
+
| Content rows | `.mote-row` + `.mote-push` — flex row, right-align helper |
|
|
149
|
+
| Pagination | `nav[aria-label="pagination"]` — semantic, no class |
|
|
150
|
+
| Footer baseline | `body > footer` — semantic top-border + padding |
|
|
151
|
+
| Screen-reader helper | `.mote-sr-only` (doubles as a skip link when focused) |
|
|
152
|
+
| Status inheritance control | `.mote-default` (force accent) · `.mote-reset` (clear inherited status) |
|
|
145
153
|
| Breadcrumbs | `nav[aria-label="breadcrumb"]` — semantic, no class |
|
|
146
154
|
| Card grids | `.mote-grid` — auto-fill columns from the container, no breakpoints |
|
|
147
155
|
| Cards | `.mote-card` |
|
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.5.1 · 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).
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* ------------------------------------------------------------------------- */
|
|
16
16
|
|
|
17
17
|
.mote-card {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
18
20
|
padding: 1.25rem 1.5rem;
|
|
19
21
|
border: var(--mote-border-width) solid var(--mote-border);
|
|
20
22
|
border-radius: var(--mote-radius-lg);
|
|
@@ -108,7 +110,7 @@
|
|
|
108
110
|
/* ---------------------------------------------------------------------------
|
|
109
111
|
* 6. Site header and nav
|
|
110
112
|
*
|
|
111
|
-
* The page shell is styled
|
|
113
|
+
* The page shell is styled semantically: a header that is a direct
|
|
112
114
|
* child of <body> is the site bar, its nav the pill row. The classes
|
|
113
115
|
* exist for the one case landmarks cannot express — a shell wrapped
|
|
114
116
|
* in a <div> (common with frameworks), where body > header cannot
|
|
@@ -178,6 +180,48 @@ nav[aria-label="breadcrumb"] [aria-current="page"] {
|
|
|
178
180
|
font-weight: 500;
|
|
179
181
|
}
|
|
180
182
|
|
|
183
|
+
/* Pagination — semantic selector, no class (mirrors breadcrumbs) */
|
|
184
|
+
nav[aria-label="pagination"] ul {
|
|
185
|
+
display: flex;
|
|
186
|
+
gap: 0.25rem;
|
|
187
|
+
padding: 0;
|
|
188
|
+
margin: 0;
|
|
189
|
+
list-style: none;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
nav[aria-label="pagination"] a {
|
|
193
|
+
display: inline-block;
|
|
194
|
+
min-width: 2.2rem;
|
|
195
|
+
padding: 0.35rem 0.6rem;
|
|
196
|
+
border-radius: var(--mote-radius-sm);
|
|
197
|
+
text-align: center;
|
|
198
|
+
text-decoration: none;
|
|
199
|
+
color: var(--mote-fg);
|
|
200
|
+
transition: background var(--mote-transition), color var(--mote-transition);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
nav[aria-label="pagination"] a:hover:not([aria-current]) {
|
|
204
|
+
background: var(--mote-accent-soft);
|
|
205
|
+
color: var(--mote-accent-deep);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
nav[aria-label="pagination"] [aria-current="page"] {
|
|
209
|
+
background: var(--mote-accent);
|
|
210
|
+
color: var(--mote-on-accent);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
nav[aria-label="pagination"] [aria-current="page"]:hover {
|
|
214
|
+
background: color-mix(in oklab, var(--mote-accent), var(--mote-fg) 14%);
|
|
215
|
+
color: var(--mote-on-accent);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Page footer: the quiet sibling of the site header */
|
|
219
|
+
:where(body > footer, .mote-footer) {
|
|
220
|
+
margin-block-start: 3rem;
|
|
221
|
+
padding-block: 1.5rem;
|
|
222
|
+
border-block-start: var(--mote-border-width) solid var(--mote-border);
|
|
223
|
+
}
|
|
224
|
+
|
|
181
225
|
/* ---------------------------------------------------------------------------
|
|
182
226
|
* 8. Popover surfaces — tooltips, menus, toasts
|
|
183
227
|
*
|
|
@@ -520,5 +564,7 @@ html:where(:has(body > header)) {
|
|
|
520
564
|
.mote-grid {
|
|
521
565
|
display: grid;
|
|
522
566
|
gap: 1.25rem;
|
|
523
|
-
|
|
567
|
+
/* Density is a variable, not a class API: --mote-grid-min: 22rem
|
|
568
|
+
gives 3-wide pricing; 26rem gives 2-column content. */
|
|
569
|
+
grid-template-columns: repeat(auto-fill, minmax(min(var(--mote-grid-min, 16rem), 100%), 1fr));
|
|
524
570
|
}
|
package/mote.css
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* mote.css — a mote of styling for plain HTML.
|
|
3
|
-
* v0.
|
|
3
|
+
* v0.5.1 · 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:
|
|
7
|
-
* framework-agnostic, semantic,
|
|
7
|
+
* framework-agnostic, semantic, class-optional, zero dependencies.
|
|
8
8
|
*
|
|
9
9
|
* MIT License. Fonts (Inter, Commit Mono) are NOT bundled.
|
|
10
10
|
* See the README for one-line self-hosting instructions.
|
|
@@ -44,6 +44,8 @@
|
|
|
44
44
|
"Liberation Mono", monospace;
|
|
45
45
|
--mote-line-height: 1.65;
|
|
46
46
|
--mote-tracking: -0.011em;
|
|
47
|
+
/* Display scale — opt-in, for heroes and error pages; body scale untouched */
|
|
48
|
+
--mote-display: clamp(2.75rem, 1.5rem + 4vw, 5rem);
|
|
47
49
|
|
|
48
50
|
/* Shape & depth */
|
|
49
51
|
--mote-radius: 10px;
|
|
@@ -500,10 +502,51 @@ button, [type="button"], [type="submit"], [type="reset"] {
|
|
|
500
502
|
}
|
|
501
503
|
|
|
502
504
|
button:hover, [type="button"]:hover, [type="submit"]:hover, [type="reset"]:hover {
|
|
503
|
-
|
|
505
|
+
/* Theme-aware deepening: fg is dark in light themes, light in dark ones. */
|
|
506
|
+
background: color-mix(in oklab, var(--mote-accent), var(--mote-fg) 14%);
|
|
504
507
|
box-shadow: var(--mote-shadow-sm);
|
|
505
508
|
}
|
|
506
509
|
|
|
510
|
+
/* Semantic solids are gated: the status class must sit on the button
|
|
511
|
+
itself, so a themed section (body.mote-error, a note, a toast) never
|
|
512
|
+
recolors the actions inside it. The token read below is therefore
|
|
513
|
+
the button's own, never an inherited one. */
|
|
514
|
+
:is(button, [type="button"], [type="submit"], [type="reset"]):where(.mote-success, .mote-warning, .mote-error, .mote-info, .mote-muted):where(:not(.mote-ghost)) {
|
|
515
|
+
background: var(--mote-status);
|
|
516
|
+
color: var(--mote-on-status, var(--mote-bg));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
:is(button, [type="button"], [type="submit"], [type="reset"]):where(.mote-success, .mote-warning, .mote-error, .mote-info, .mote-muted):where(:not(.mote-ghost)):hover {
|
|
520
|
+
background: color-mix(in oklab, var(--mote-status), var(--mote-fg) 14%);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/* Ghost buttons: quiet, transparent fill, accent-tinted. Like solids,
|
|
524
|
+
status colors come from the button's own class, never from context. */
|
|
525
|
+
.mote-ghost {
|
|
526
|
+
background: none;
|
|
527
|
+
border: var(--mote-border-width) solid color-mix(in oklab, var(--mote-accent), transparent 55%);
|
|
528
|
+
color: var(--mote-accent-deep);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.mote-ghost:hover {
|
|
532
|
+
background: var(--mote-accent-soft);
|
|
533
|
+
color: var(--mote-accent-deep);
|
|
534
|
+
box-shadow: none;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/* Gated ghost+status: the status class on the element itself tints the
|
|
538
|
+
border and text (same gating as the solid buttons). Works on buttons
|
|
539
|
+
and anchors alike — .mote-ghost is element-agnostic. */
|
|
540
|
+
.mote-ghost:where(.mote-success, .mote-warning, .mote-error, .mote-info, .mote-muted) {
|
|
541
|
+
border-color: color-mix(in oklab, var(--mote-status), transparent 55%);
|
|
542
|
+
color: var(--mote-status);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.mote-ghost:where(.mote-success, .mote-warning, .mote-error, .mote-info, .mote-muted):hover {
|
|
546
|
+
background: var(--mote-status-soft);
|
|
547
|
+
color: var(--mote-status);
|
|
548
|
+
}
|
|
549
|
+
|
|
507
550
|
button:active, [type="button"]:active, [type="submit"]:active, [type="reset"]:active {
|
|
508
551
|
transform: translateY(1px);
|
|
509
552
|
}
|
|
@@ -582,7 +625,8 @@ progress, meter {
|
|
|
582
625
|
/* ---------------------------------------------------------------------------
|
|
583
626
|
* 11. Opt-in helpers
|
|
584
627
|
*
|
|
585
|
-
* mote is
|
|
628
|
+
* mote is class-optional by design — elements are styled from tags
|
|
629
|
+
* alone; these classes are opt-in conveniences, never a required API.
|
|
586
630
|
* ------------------------------------------------------------------------- */
|
|
587
631
|
|
|
588
632
|
/* Centered page wrapper: <main class="mote-container"> */
|
|
@@ -594,6 +638,47 @@ progress, meter {
|
|
|
594
638
|
/* Dimmed text: <small class="mote-muted"> */
|
|
595
639
|
.mote-muted { color: var(--mote-muted); }
|
|
596
640
|
|
|
641
|
+
/* Row of things: headers, footers, toolbars, chip lists.
|
|
642
|
+
.mote-push on a child right-aligns it (and everything after). */
|
|
643
|
+
.mote-row {
|
|
644
|
+
display: flex;
|
|
645
|
+
align-items: center;
|
|
646
|
+
gap: 1rem;
|
|
647
|
+
flex-wrap: wrap;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
.mote-push { margin-inline-start: auto; }
|
|
651
|
+
|
|
652
|
+
/* Visually hidden, screen-reader available */
|
|
653
|
+
.mote-sr-only {
|
|
654
|
+
position: absolute;
|
|
655
|
+
width: 1px;
|
|
656
|
+
height: 1px;
|
|
657
|
+
padding: 0;
|
|
658
|
+
margin: -1px;
|
|
659
|
+
overflow: hidden;
|
|
660
|
+
clip-path: inset(50%);
|
|
661
|
+
white-space: nowrap;
|
|
662
|
+
border: 0;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/* Skip link: sr-only until focused, then a fixed pill */
|
|
666
|
+
.mote-sr-only:focus-visible {
|
|
667
|
+
position: fixed;
|
|
668
|
+
top: 1rem;
|
|
669
|
+
left: 1rem;
|
|
670
|
+
width: auto;
|
|
671
|
+
height: auto;
|
|
672
|
+
margin: 0;
|
|
673
|
+
padding: 0.5rem 1rem;
|
|
674
|
+
clip-path: none;
|
|
675
|
+
z-index: 20;
|
|
676
|
+
background: var(--mote-accent);
|
|
677
|
+
color: var(--mote-on-accent);
|
|
678
|
+
border-radius: var(--mote-radius-sm);
|
|
679
|
+
text-decoration: none;
|
|
680
|
+
}
|
|
681
|
+
|
|
597
682
|
/* ---------------------------------------------------------------------------
|
|
598
683
|
* 12. Status classes
|
|
599
684
|
*
|
|
@@ -608,10 +693,10 @@ progress, meter {
|
|
|
608
693
|
* inline: style="--mote-status: rebeccapurple".
|
|
609
694
|
* ------------------------------------------------------------------------- */
|
|
610
695
|
|
|
611
|
-
.mote-success { --mote-status: var(--mote-success); --mote-status-soft: var(--mote-success-soft); }
|
|
612
|
-
.mote-warning { --mote-status: var(--mote-warning); --mote-status-soft: var(--mote-warning-soft); }
|
|
613
|
-
.mote-error { --mote-status: var(--mote-error); --mote-status-soft: var(--mote-error-soft); }
|
|
614
|
-
.mote-info { --mote-status: var(--mote-info); --mote-status-soft: var(--mote-info-soft); }
|
|
696
|
+
.mote-success { --mote-status: var(--mote-success); --mote-status-soft: var(--mote-success-soft); --mote-on-status: var(--mote-bg); }
|
|
697
|
+
.mote-warning { --mote-status: var(--mote-warning); --mote-status-soft: var(--mote-warning-soft); --mote-on-status: var(--mote-bg); }
|
|
698
|
+
.mote-error { --mote-status: var(--mote-error); --mote-status-soft: var(--mote-error-soft); --mote-on-status: var(--mote-bg); }
|
|
699
|
+
.mote-info { --mote-status: var(--mote-info); --mote-status-soft: var(--mote-info-soft); --mote-on-status: var(--mote-bg); }
|
|
615
700
|
|
|
616
701
|
/* .mote-muted does double duty: dimmed text where nothing consumes the
|
|
617
702
|
tokens, and a neutral status where something does. */
|
|
@@ -619,6 +704,25 @@ progress, meter {
|
|
|
619
704
|
color: var(--mote-muted);
|
|
620
705
|
--mote-status: var(--mote-muted);
|
|
621
706
|
--mote-status-soft: color-mix(in oklab, var(--mote-fg) 7%, transparent);
|
|
707
|
+
--mote-on-status: var(--mote-bg);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/* .mote-default: the accent as an explicit status — "keep this (and its
|
|
711
|
+
descendants) plum" inside a themed section. Unlike the semantics, this
|
|
712
|
+
IS meant to be applied contextually. */
|
|
713
|
+
.mote-default {
|
|
714
|
+
--mote-status: var(--mote-accent);
|
|
715
|
+
--mote-status-soft: var(--mote-accent-soft);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/* .mote-reset: clear an inherited status for a subtree — consumers inside
|
|
719
|
+
fall back to their own defaults; their own classes re-apply locally.
|
|
720
|
+
Where .mote-default forces the accent down the tree, .mote-reset
|
|
721
|
+
removes the theme and lets each element speak for itself. */
|
|
722
|
+
.mote-reset {
|
|
723
|
+
--mote-status: initial;
|
|
724
|
+
--mote-status-soft: initial;
|
|
725
|
+
--mote-on-status: initial;
|
|
622
726
|
}
|
|
623
727
|
|
|
624
728
|
/* Themed message surfaces — base shape only; status via the token classes */
|
|
@@ -630,6 +734,15 @@ progress, meter {
|
|
|
630
734
|
background: var(--mote-status-soft, var(--mote-accent-soft));
|
|
631
735
|
}
|
|
632
736
|
|
|
737
|
+
/* Display text: opt-in hero / error-code scale. Widen per use with
|
|
738
|
+
style="--mote-display: clamp(6rem, 24vw, 12rem)". */
|
|
739
|
+
.mote-display {
|
|
740
|
+
font-size: var(--mote-display);
|
|
741
|
+
line-height: 1.1;
|
|
742
|
+
letter-spacing: var(--mote-tracking);
|
|
743
|
+
text-wrap: balance;
|
|
744
|
+
}
|
|
745
|
+
|
|
633
746
|
/* ---------------------------------------------------------------------------
|
|
634
747
|
* 13. Motion preferences & print
|
|
635
748
|
* ------------------------------------------------------------------------- */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mote.css",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A mote of styling for plain HTML — tiny, semantic,
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "A mote of styling for plain HTML — tiny, semantic, class-optional CSS with zero dependencies and no build step.",
|
|
5
5
|
"style": "mote.css",
|
|
6
6
|
"files": [
|
|
7
7
|
"mote.css",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"keywords": [
|
|
14
14
|
"css",
|
|
15
|
-
"
|
|
15
|
+
"class-optional",
|
|
16
16
|
"semantic",
|
|
17
17
|
"framework-agnostic",
|
|
18
18
|
"dark-mode",
|