mote.css 0.4.0 → 0.5.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 CHANGED
@@ -5,6 +5,93 @@ 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.0] - 2026-10-20
9
+
10
+ ### Added
11
+
12
+ - Semantic buttons: solid buttons take a status class (`.mote-success`,
13
+ `.mote-warning`, `.mote-error`, `.mote-info`, `.mote-muted`) — gated, so
14
+ the class must be on the button itself. Themed sections (error notes,
15
+ toasts, page-level status) never recolor the actions inside them; the
16
+ intent of an action is declared at the action site. Text color on
17
+ semantic solids is `--mote-on-status` (set by the status classes to the
18
+ page color, AA-verified in both themes).
19
+ - Ghost buttons (`.mote-ghost`): transparent fill, status-tinted border
20
+ and text. Gated like solids — the status class on the element itself
21
+ provides the tint, never the surrounding context.
22
+ - `.mote-default` and `.mote-reset`: control status inheritance for
23
+ the non-gated consumers (badges, notes, spinners, …). Default forces the
24
+ accent down the tree; reset clears the inherited status so each
25
+ element's own classes decide.
26
+ - `.mote-row` + `.mote-push`: flex row helper + right-align helper —
27
+ for headers, footers, toolbars, chip lists, form rows.
28
+ - `.mote-display` + `--mote-display` token: opt-in display/hero scale.
29
+ - `--mote-grid-min` variable on `.mote-grid`: density without a class API.
30
+ - `.mote-sr-only`: visually-hidden helper; doubles as a skip link when
31
+ focused.
32
+ - Semantic pagination: `nav[aria-label="pagination"]` — flex row of
33
+ pills with `aria-current` state, no class (mirrors breadcrumbs).
34
+ - Footer baseline: `body > footer` gets a top border and block padding
35
+ (the quiet sibling of the site header).
36
+ - `.mote-card` is now `display: flex; flex-direction: column` —
37
+ CTA-in-bottom-of-card aligns with `margin-block-start: auto` for free.
38
+ - Theme-aware hover deepening for buttons: `color-mix(accent/status,
39
+ fg 14%)` — darkens in light themes, brightens in dark ones.
40
+
41
+ ### Changed
42
+
43
+ - Docs: buttons and statuses section (gating rationale, ghost inheritance),
44
+ `.mote-default`/`.mote-reset` guidance, new component table entries.
45
+
46
+ ### Fixed
47
+
48
+ Layout shell (`mote.components.css`), from the ten-app evaluation:
49
+ - `.mote-doc` mobile: nav/main/aside overlapped in one grid cell — the
50
+ collapse media query now resets `grid-row: auto`.
51
+ - `.mote-doc` blowout on wide content: content tracks are `minmax(0, 1fr)`
52
+ (+ `min-width: 0` on items); a wide table scrolls inside `main`, never the page.
53
+ - Rail nav no longer renders as the horizontal pill row: pill styles scoped
54
+ to `body > header nav`; rails get a quiet vertical list with
55
+ `aria-current` states.
56
+ Sticky rails and anchored content clear the site header via
57
+ `--mote-rail-top` (token) and automatic `scroll-padding` when
58
+ `body > header` exists. `body.mote-doc` gains page gutters.
59
+
60
+ Core (`mote.css`):
61
+ - `:user-invalid` kept its error border through hover and focus
62
+ (`:is(input, select, textarea):user-invalid`, placed to win the cascade) —
63
+ previously the field the user must fix showed the accent focus border.
64
+ - `--mote-accent-deep` now brightens in dark mode (`color-mix(accent,
65
+ white 14%)`); dark hovers, badges and notes no longer dim.
66
+ - `input[type="range"]` stripped of text-input chrome; `select[multiple]`
67
+ restored to native listbox appearance.
68
+ - `[role="status"]` / `[role="alert"]` read `--mote-status` (semantic
69
+ colors as fallback) instead of hard-coding.
70
+ - `.mote-note` gains block margin; `.mote-badge` line-height tamed in
71
+ headings; `blockquote` code no longer italic; `.mote-card` first/last-child
72
+ rules moved into `:where()` so page classes win; dialogs get
73
+ `max-width: min(90vw, 44rem)`; `.mote-avatar` sized by
74
+ `--mote-avatar` token; `.mote-skeleton` gets intrinsic size.
75
+ - Print: the light palette is forced on paper — dark fills (zebra, notes,
76
+ open details) no longer print as near-black bands.
77
+ - Focus rings no longer fade in (box-shadow removed from transitions).
78
+
79
+ Components:
80
+ - Popovers and dialogs now animate on exit, not just entrance
81
+ (closed-state deltas for the `allow-discrete` transitions).
82
+ - `details[name]` content padding fixed for multiple children
83
+ (was padding every child; now only the last).
84
+ - Toasts documented with `popover="manual"` (auto popovers light-dismiss);
85
+ samples corrected.
86
+
87
+ ### Changed
88
+
89
+ - README and docs CDN snippets use `mote.css@0` (range pin) so they never go
90
+ stale; exact-version pinning documented for reproducible builds.
91
+ - Docs: wide-table wrapper recipe, form-width guidance, document-shell
92
+ real-page notes (gutters, rail-top token), print caveats for exclusive
93
+ accordions, toast stacking guidance; section numbering fixed.
94
+
8
95
  ## [0.4.0] - 2026-10-20
9
96
 
10
97
  ### Fixed
@@ -165,11 +252,9 @@ Components:
165
252
  - Element gallery demo page (`demo.html`).
166
253
 
167
254
  [0.3.0]: https://gitlab.com/abmach/mote/compare/v0.2.1...v0.3.0
255
+ [0.5.0]: https://gitlab.com/abmach/mote/compare/v0.4.0...v0.5.0
168
256
  [0.4.0]: https://gitlab.com/abmach/mote/compare/v0.3.0...v0.4.0
257
+ [0.3.0]: https://gitlab.com/abmach/mote/compare/v0.2.1...v0.3.0
169
258
  [0.2.1]: https://gitlab.com/abmach/mote/compare/v0.2.0...v0.2.1
170
259
  [0.2.0]: https://gitlab.com/abmach/mote/compare/v0.1.0...v0.2.0
171
260
  [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
@@ -142,6 +142,14 @@ mote is classless by design; these are the only escape hatches, plus status clas
142
142
  |---|---|
143
143
  | Document layout (landmark grid) | `.mote-doc` on `<body>` — `:has()` reads your `header`/`nav`/`main`/`aside`/`footer` |
144
144
  | Sticky site header / nav pills | `body > header` — classless; `.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` — classless 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` |
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * mote.components.css — opt-in components for mote.css.
3
- * v0.4.0 · MIT
3
+ * v0.5.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).
@@ -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);
@@ -178,6 +180,43 @@ 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 {
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
+ /* Page footer: the quiet sibling of the site header */
214
+ :where(body > footer, .mote-footer) {
215
+ margin-block-start: 3rem;
216
+ padding-block: 1.5rem;
217
+ border-block-start: var(--mote-border-width) solid var(--mote-border);
218
+ }
219
+
181
220
  /* ---------------------------------------------------------------------------
182
221
  * 8. Popover surfaces — tooltips, menus, toasts
183
222
  *
@@ -520,5 +559,7 @@ html:where(:has(body > header)) {
520
559
  .mote-grid {
521
560
  display: grid;
522
561
  gap: 1.25rem;
523
- grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
562
+ /* Density is a variable, not a class API: --mote-grid-min: 22rem
563
+ gives 3-wide pricing; 26rem gives 2-column content. */
564
+ grid-template-columns: repeat(auto-fill, minmax(min(var(--mote-grid-min, 16rem), 100%), 1fr));
524
565
  }
package/mote.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * mote.css — a mote of styling for plain HTML.
3
- * v0.4.0 · MIT
3
+ * v0.5.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:
@@ -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
- background: var(--mote-accent-deep);
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
  }
@@ -594,6 +637,47 @@ progress, meter {
594
637
  /* Dimmed text: <small class="mote-muted"> */
595
638
  .mote-muted { color: var(--mote-muted); }
596
639
 
640
+ /* Row of things: headers, footers, toolbars, chip lists.
641
+ .mote-push on a child right-aligns it (and everything after). */
642
+ .mote-row {
643
+ display: flex;
644
+ align-items: center;
645
+ gap: 1rem;
646
+ flex-wrap: wrap;
647
+ }
648
+
649
+ .mote-push { margin-inline-start: auto; }
650
+
651
+ /* Visually hidden, screen-reader available */
652
+ .mote-sr-only {
653
+ position: absolute;
654
+ width: 1px;
655
+ height: 1px;
656
+ padding: 0;
657
+ margin: -1px;
658
+ overflow: hidden;
659
+ clip-path: inset(50%);
660
+ white-space: nowrap;
661
+ border: 0;
662
+ }
663
+
664
+ /* Skip link: sr-only until focused, then a fixed pill */
665
+ .mote-sr-only:focus-visible {
666
+ position: fixed;
667
+ top: 1rem;
668
+ left: 1rem;
669
+ width: auto;
670
+ height: auto;
671
+ margin: 0;
672
+ padding: 0.5rem 1rem;
673
+ clip-path: none;
674
+ z-index: 20;
675
+ background: var(--mote-accent);
676
+ color: var(--mote-on-accent);
677
+ border-radius: var(--mote-radius-sm);
678
+ text-decoration: none;
679
+ }
680
+
597
681
  /* ---------------------------------------------------------------------------
598
682
  * 12. Status classes
599
683
  *
@@ -608,10 +692,10 @@ progress, meter {
608
692
  * inline: style="--mote-status: rebeccapurple".
609
693
  * ------------------------------------------------------------------------- */
610
694
 
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); }
695
+ .mote-success { --mote-status: var(--mote-success); --mote-status-soft: var(--mote-success-soft); --mote-on-status: var(--mote-bg); }
696
+ .mote-warning { --mote-status: var(--mote-warning); --mote-status-soft: var(--mote-warning-soft); --mote-on-status: var(--mote-bg); }
697
+ .mote-error { --mote-status: var(--mote-error); --mote-status-soft: var(--mote-error-soft); --mote-on-status: var(--mote-bg); }
698
+ .mote-info { --mote-status: var(--mote-info); --mote-status-soft: var(--mote-info-soft); --mote-on-status: var(--mote-bg); }
615
699
 
616
700
  /* .mote-muted does double duty: dimmed text where nothing consumes the
617
701
  tokens, and a neutral status where something does. */
@@ -619,6 +703,25 @@ progress, meter {
619
703
  color: var(--mote-muted);
620
704
  --mote-status: var(--mote-muted);
621
705
  --mote-status-soft: color-mix(in oklab, var(--mote-fg) 7%, transparent);
706
+ --mote-on-status: var(--mote-bg);
707
+ }
708
+
709
+ /* .mote-default: the accent as an explicit status — "keep this (and its
710
+ descendants) plum" inside a themed section. Unlike the semantics, this
711
+ IS meant to be applied contextually. */
712
+ .mote-default {
713
+ --mote-status: var(--mote-accent);
714
+ --mote-status-soft: var(--mote-accent-soft);
715
+ }
716
+
717
+ /* .mote-reset: clear an inherited status for a subtree — consumers inside
718
+ fall back to their own defaults; their own classes re-apply locally.
719
+ Where .mote-default forces the accent down the tree, .mote-reset
720
+ removes the theme and lets each element speak for itself. */
721
+ .mote-reset {
722
+ --mote-status: initial;
723
+ --mote-status-soft: initial;
724
+ --mote-on-status: initial;
622
725
  }
623
726
 
624
727
  /* Themed message surfaces — base shape only; status via the token classes */
@@ -630,6 +733,15 @@ progress, meter {
630
733
  background: var(--mote-status-soft, var(--mote-accent-soft));
631
734
  }
632
735
 
736
+ /* Display text: opt-in hero / error-code scale. Widen per use with
737
+ style="--mote-display: clamp(6rem, 24vw, 12rem)". */
738
+ .mote-display {
739
+ font-size: var(--mote-display);
740
+ line-height: 1.1;
741
+ letter-spacing: var(--mote-tracking);
742
+ text-wrap: balance;
743
+ }
744
+
633
745
  /* ---------------------------------------------------------------------------
634
746
  * 13. Motion preferences & print
635
747
  * ------------------------------------------------------------------------- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mote.css",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "A mote of styling for plain HTML — tiny, semantic, classless CSS with zero dependencies and no build step.",
5
5
  "style": "mote.css",
6
6
  "files": [