mote.css 0.6.0 → 0.6.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 CHANGED
@@ -5,7 +5,48 @@ 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.6.0] - 2026-10-20
8
+ ## [0.6.1] - 2026-10-20
9
+
10
+ ### Fixed
11
+
12
+ - `.mote-print-only` now actually displays in print (the unconditional
13
+ `display: none` was after the print block at equal specificity —
14
+ scoped to `@media not print` and moved before it).
15
+ - `.mote-stack` no longer stretches `.mote-sr-only` inputs to 100%
16
+ width (hidden file inputs were creating invisible horizontal scroll).
17
+ - `.mote-doc > main` now uses `overflow-x: auto` (was `clip`, which
18
+ made wide tables invisible rather than scrollable).
19
+ - `.mote-theme-switch` shipped in mote.css: disables transitions during
20
+ `data-theme` flips so Chromium doesn't wedge elements at stale colors
21
+ (custom-property changes don't restart CSS transitions). The docs'
22
+ toggle snippet now includes it; the demo uses it.
23
+ - `.mote-doc > aside` gets the same sticky treatment as the nav rail
24
+ (top, max-height, overflow) — TOCs and aside content no longer scroll
25
+ out of view.
26
+ - Nav rail `max-height` accounts for `--mote-rail-top` (was
27
+ `calc(100svh - 2rem)` regardless of header height).
28
+ - Rail heading treatment (small uppercase labels) now applies to
29
+ `.mote-doc > aside` and `nav[aria-label="toc"]` headings too.
30
+ - `legend` gets `font-weight: 600` so the group caption reads stronger
31
+ than the field labels inside it.
32
+
33
+ ### Added
34
+
35
+ - `tabular-nums` on all `td` — figures align in data tables without
36
+ any page CSS (invisible on non-numeric content).
37
+ - `.mote-table-scroll`: scrollable table wrapper with sticky `thead`,
38
+ no margin jump on scroll start, and no page-level horizontal scroll.
39
+ - `.mote-grid-sparse`: auto-fit variant that collapses empty grid
40
+ tracks (footers, short card rows).
41
+ - `--mote-control-pad` / `--mote-control-pad-inline` and
42
+ `--mote-cell-pad` / `--mote-cell-pad-inline` density tokens.
43
+ - Docs: toggle snippet includes the theme-switch workaround; Chromium
44
+ note references the shipped class.
45
+
46
+ ### Changed
47
+
48
+ - Third ten-app evaluation completed against v0.6.0; all round-2 fixes
49
+ verified holding. Round-3 findings addressed in this patch release.
9
50
 
10
51
  ### Fixed
11
52
 
@@ -335,6 +376,7 @@ Components:
335
376
  - Element gallery demo page (`demo.html`).
336
377
 
337
378
  [0.3.0]: https://gitlab.com/abmach/mote/compare/v0.2.1...v0.3.0
379
+ [0.6.1]: https://gitlab.com/abmach/mote/compare/v0.6.0...v0.6.1
338
380
  [0.6.0]: https://gitlab.com/abmach/mote/compare/v0.5.1...v0.6.0
339
381
  [0.5.1]: https://gitlab.com/abmach/mote/compare/v0.5.0...v0.5.1
340
382
  [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
 
@@ -152,11 +154,15 @@ mote is class-optional by design — elements are styled from tags alone; these
152
154
  | Media objects | `.mote-media` — avatar/icon beside body (flex, last child grows) |
153
155
  | Display text | `.mote-display` — opt-in hero/error-code scale via `--mote-display` |
154
156
  | Content rows | `.mote-row` + `.mote-push` — flex row, right-align helper |
157
+ | Stacked forms | `.mote-stack` — opt-in full-width fields, checkboxes stay 1em |
158
+ | Scrollable tables | `.mote-table-scroll` — sticky `thead`, no page scroll, no margin jump |
159
+ | Sparse grids | `.mote-grid-sparse` — auto-fit variant, collapses empty tracks |
155
160
  | Pagination | `nav[aria-label="pagination"]` — semantic, no class |
156
161
  | Table of contents | `nav[aria-label="toc"]` — semantic, no class |
157
162
  | Footer baseline | `body > footer` — semantic top-border + padding |
158
163
  | Screen-reader helper | `.mote-sr-only` (doubles as a skip link when focused) |
159
164
  | Print helpers | `.mote-no-print` / `.mote-print-only` |
165
+ | Theme-switch guard | `.mote-theme-switch` — prevents Chromium stale-color bug on `data-theme` flips |
160
166
  | Status inheritance control | `.mote-default` (force accent) · `.mote-reset` (clear inherited status) |
161
167
  | Breadcrumbs | `nav[aria-label="breadcrumb"]` — semantic, no class |
162
168
  | Card grids | `.mote-grid` — auto-fill columns from the container, no breakpoints |
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * mote.components.css — opt-in components for mote.css.
3
- * v0.6.0 · MIT
3
+ * v0.6.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).
@@ -245,6 +245,23 @@ nav[aria-label="toc"] a:hover {
245
245
  color: var(--mote-accent-deep);
246
246
  }
247
247
 
248
+ /* Scrollable table wrapper: sticky thead, no page scroll, no margin jump */
249
+ .mote-table-scroll {
250
+ overflow-x: auto;
251
+ max-height: 60vh;
252
+ overflow-y: auto;
253
+ }
254
+
255
+ .mote-table-scroll table {
256
+ margin-block: 0;
257
+ }
258
+
259
+ .mote-table-scroll thead th {
260
+ position: sticky;
261
+ top: 0;
262
+ background: var(--mote-bg);
263
+ }
264
+
248
265
  /* Page footer: the quiet sibling of the site header */
249
266
  :where(body > footer, .mote-footer) {
250
267
  margin-block-start: 3rem;
@@ -502,7 +519,7 @@ html:where(:has(body > header)) {
502
519
  /* Content stays inside the grid track — wide tables scroll here,
503
520
  not the page. */
504
521
  .mote-doc > main {
505
- overflow-x: clip;
522
+ overflow-x: auto;
506
523
  }
507
524
 
508
525
  /* nav = left rail */
@@ -513,7 +530,7 @@ html:where(:has(body > header)) {
513
530
  align-self: start;
514
531
  position: sticky;
515
532
  top: var(--mote-rail-top, 1rem);
516
- max-height: calc(100svh - 2rem);
533
+ max-height: calc(100svh - var(--mote-rail-top, 1rem) - 1rem);
517
534
  overflow: auto;
518
535
  }
519
536
 
@@ -550,7 +567,9 @@ html:where(:has(body > header)) {
550
567
  }
551
568
 
552
569
  /* Rail headings: small label-scale for grouped navigation */
553
- .mote-doc > nav :is(h2, h3) {
570
+ .mote-doc > nav :is(h2, h3),
571
+ .mote-doc > aside :is(h2, h3),
572
+ nav[aria-label="toc"] :is(h2, h3) {
554
573
  margin: 1rem 0 0.3rem;
555
574
  padding-inline: 0.75rem;
556
575
  font-size: 0.72rem;
@@ -574,6 +593,10 @@ html:where(:has(body > header)) {
574
593
  grid-column: 2;
575
594
  min-width: 0;
576
595
  align-self: start;
596
+ position: sticky;
597
+ top: var(--mote-rail-top, 1rem);
598
+ max-height: calc(100svh - var(--mote-rail-top, 1rem) - 1rem);
599
+ overflow: auto;
577
600
  }
578
601
 
579
602
  .mote-doc:where(:has(> nav)) > aside {
@@ -616,3 +639,8 @@ html:where(:has(body > header)) {
616
639
  gives 3-wide pricing; 26rem gives 2-column content. */
617
640
  grid-template-columns: repeat(auto-fill, minmax(min(var(--mote-grid-min, 16rem), 100%), 1fr));
618
641
  }
642
+
643
+ /* Sparse grids: collapse empty tracks (footers, short card rows) */
644
+ .mote-grid-sparse {
645
+ grid-template-columns: repeat(auto-fit, minmax(min(var(--mote-grid-min, 16rem), 100%), 1fr));
646
+ }
package/mote.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * mote.css — a mote of styling for plain HTML.
3
- * v0.6.0 · MIT
3
+ * v0.6.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:
@@ -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
  }
@@ -372,7 +372,8 @@ caption {
372
372
  }
373
373
 
374
374
  th, td {
375
- padding: 0.6rem 0.8rem;
375
+ font-variant-numeric: tabular-nums;
376
+ padding: var(--mote-cell-pad, 0.6rem) var(--mote-cell-pad-inline, 0.8rem);
376
377
  border-block-end: var(--mote-border-width) solid var(--mote-border);
377
378
  text-align: start;
378
379
  vertical-align: top;
@@ -409,7 +410,7 @@ fieldset {
409
410
  border-radius: var(--mote-radius);
410
411
  }
411
412
 
412
- legend { padding-inline: 0.4rem; }
413
+ legend { padding-inline: 0.4rem; font-weight: 600; }
413
414
 
414
415
  input, select, textarea {
415
416
  font: inherit;
@@ -501,7 +502,7 @@ button, [type="button"], [type="submit"], [type="reset"] {
501
502
  font: inherit;
502
503
  font-weight: 500;
503
504
  color: var(--mote-on-accent);
504
- padding: 0.5rem 1.1rem;
505
+ padding: var(--mote-control-pad, 0.5rem) var(--mote-control-pad-inline, 1.1rem);
505
506
  background: var(--mote-accent);
506
507
  border: var(--mote-border-width) solid transparent;
507
508
  border-radius: var(--mote-radius-sm);
@@ -532,10 +533,13 @@ button:hover, [type="button"]:hover, [type="submit"]:hover, [type="reset"]:hover
532
533
  /* Ghost buttons: quiet, transparent fill, accent-tinted. Like solids,
533
534
  status colors come from the button's own class, never from context. */
534
535
  .mote-ghost {
536
+ display: inline-block;
537
+ font: inherit;
538
+ font-weight: 500;
535
539
  background: none;
536
540
  border: var(--mote-border-width) solid color-mix(in oklab, var(--mote-accent), transparent 55%);
537
541
  color: var(--mote-accent-deep);
538
- padding: 0.5rem 1.1rem;
542
+ padding: var(--mote-control-pad, 0.5rem) var(--mote-control-pad-inline, 1.1rem);
539
543
  border-radius: var(--mote-radius-sm);
540
544
  text-decoration: none;
541
545
  cursor: pointer;
@@ -672,6 +676,10 @@ progress, meter {
672
676
  width: 1em;
673
677
  }
674
678
 
679
+ .mote-stack :is(input, select, textarea):where(.mote-sr-only) {
680
+ width: 1px;
681
+ }
682
+
675
683
  /* Solid button on any element — anchors, spans, divs.
676
684
  Same recipe as the element-level button styles; status classes
677
685
  gated identically (class on the element itself). */
@@ -868,4 +876,15 @@ progress, meter {
868
876
  .mote-print-only { display: block; }
869
877
  }
870
878
 
871
- .mote-print-only { display: none; }
879
+ @media not print {
880
+ .mote-print-only { display: none; }
881
+ }
882
+
883
+ /* Theme switch: disable transitions during data-theme flips.
884
+ Chromium doesn't restart CSS transitions on custom-property changes,
885
+ so flipping data-theme leaves elements at the old theme's colors.
886
+ Apply this class before the flip, remove after one frame. */
887
+ .mote-theme-switch,
888
+ .mote-theme-switch * {
889
+ transition: none !important;
890
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mote.css",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
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": [