@mlola-ui/engine 1.1.0 → 1.1.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.
@@ -233,7 +233,7 @@
233
233
  },
234
234
  {
235
235
  "name": "ml-brand-mark",
236
- "note": ""
236
+ "note": "A brand's own logo takes the mark's place: no chip, the text color, the mark's size."
237
237
  },
238
238
  {
239
239
  "name": "ml-brand-name",
@@ -42,7 +42,8 @@ Set `data-theme` and `data-mode` on any ancestor. Nothing else changes.
42
42
  | `aerogel` | Aerogel Glass |
43
43
  | `nordic` | Nordic Earth |
44
44
 
45
- `data-mode` is `light` or `dark`.
45
+ `data-mode` is `light`, `dark`, or `system`, which follows the reader's own setting.
46
+ The themes' type reads `--font-inter`, `--font-newsreader` and `--font-jetbrains` before its fallbacks: load those fonts (next/font's `variable` option, or @font-face) and set the variables on the root, or the page uses the system's fonts.
46
47
 
47
48
  A project defines its own theme in one file, `mlola.theme.json`, which
48
49
  overrides fonts, colors, geometry, the spacing and type scale, and any
@@ -129,6 +130,7 @@ component, so a page built from them themes with the rest.
129
130
 
130
131
  `.ml-actions` `.ml-brand` `.ml-brand-mark` `.ml-brand-name` `.ml-chart` `.ml-chart-bar` `.ml-chart-bars` `.ml-chart-heading` `.ml-check-list` `.ml-cluster` `.ml-definition-list` `.ml-display` `.ml-divider` `.ml-empty-state` `.ml-eyebrow` `.ml-filter-chip` `.ml-filter-group` `.ml-fine-print` `.ml-form` `.ml-form-message` `.ml-form-options` `.ml-grid` `.ml-heading` `.ml-icon-chip` `.ml-inline-form` `.ml-inline-form-field` `.ml-label` `.ml-lede` `.ml-link` `.ml-page-shell` `.ml-person` `.ml-person-copy` `.ml-positive` `.ml-price` `.ml-required-mark` `.ml-section` `.ml-section-description` `.ml-section-header` `.ml-section-header-centered` `.ml-section-muted` `.ml-section-shell` `.ml-stack` `.ml-stat` `.ml-stat-card` `.ml-stat-grid` `.ml-stat-list` `.ml-stat-meta` `.ml-stat-value` `.ml-text-primary` `.ml-value`
131
132
 
133
+ - `.ml-brand-mark` — A brand's own logo takes the mark's place: no chip, the text color, the mark's size.
132
134
  - `.ml-check-list` — A list of benefits, each after a check. Pricing tiers and feature rows share it.
133
135
  - `.ml-link` — A glyph inside a link flows with the text instead of breaking the line.
134
136
  - `.ml-page-shell` — The navigation, main and footer are grid items; they may be narrower than their widest content (a table that scrolls), so the page never does.
@@ -151,6 +153,7 @@ correct. This table is read out of the stylesheet, so it is never stale.
151
153
  | `.ml-badge` | `data-size` | `lg`, `sm` |
152
154
  | `.ml-badge` | `data-tone` | `danger`, `info`, `primary`, `success`, `warning` |
153
155
  | `.ml-badge` | `data-variant` | `outline`, `solid` |
156
+ | `.ml-brand-mark` | `data-kind` | `logo` |
154
157
  | `.ml-breadcrumb-item` | `data-collapse-indicator` | _presence only_ |
155
158
  | `.ml-breadcrumb-item` | `data-collapsible` | _presence only_ |
156
159
  | `.ml-button` | `aria-disabled` | `true` |
@@ -60,6 +60,11 @@
60
60
  "solid"
61
61
  ]
62
62
  },
63
+ "ml-brand-mark": {
64
+ "data-kind": [
65
+ "logo"
66
+ ]
67
+ },
63
68
  "ml-breadcrumb-item": {
64
69
  "data-collapse-indicator": [],
65
70
  "data-collapsible": []
@@ -374,6 +374,18 @@
374
374
  font-weight: 800;
375
375
  }
376
376
 
377
+ /* A brand's own logo takes the mark's place: no chip, the text color, the mark's size. */
378
+ .ml-brand-mark[data-kind="logo"] {
379
+ background: none;
380
+ color: var(--ml-text);
381
+ }
382
+
383
+ .ml-brand-mark[data-kind="logo"] > :is(svg, img) {
384
+ width: 100%;
385
+ height: 100%;
386
+ object-fit: contain;
387
+ }
388
+
377
389
  .ml-brand-name {
378
390
  font-size: var(--ml-type-md);
379
391
  letter-spacing: -.02em;
@@ -200,6 +200,68 @@
200
200
  --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
201
201
  }
202
202
 
203
+ /* data-mode="system" follows the reader's setting: light by default, dark when they ask for it. */
204
+ @media (prefers-color-scheme: dark) {
205
+ :root[data-mode="system"],
206
+ :root[data-theme="graphite"][data-mode="system"],
207
+ [data-theme="graphite"][data-mode="system"] {
208
+ color-scheme: dark;
209
+ --ml-background: oklch(0.148 0.005 286);
210
+ --ml-background-subtle: oklch(0.206 0.005 286);
211
+ --ml-surface: oklch(0.18 0.005 286);
212
+ --ml-surface-elevated: oklch(0.215 0.005 286);
213
+ --ml-text: oklch(0.959 0.004 286);
214
+ --ml-text-muted: oklch(0.71 0.01 286);
215
+ --ml-text-faint: oklch(0.64 0.008 286);
216
+ --ml-border: oklch(0.31 0.006 286);
217
+ --ml-border-subtle: oklch(0.263 0.005 286);
218
+ --ml-primary: oklch(0.959 0.006 286);
219
+ --ml-primary-foreground: oklch(0.18 0.02 286);
220
+ --ml-primary-hover: oklch(0.862 0.005 286);
221
+ --ml-primary-text: oklch(0.959 0.006 286);
222
+ --ml-primary-subtle: oklch(0.236 0.005 286);
223
+ --ml-success: oklch(0.72 0.15 150);
224
+ --ml-success-foreground: oklch(0.18 0.02 150);
225
+ --ml-success-hover: oklch(0.651 0.132 150);
226
+ --ml-success-text: oklch(0.72 0.15 150);
227
+ --ml-warning: oklch(0.8 0.16 75);
228
+ --ml-warning-foreground: oklch(0.18 0.02 75);
229
+ --ml-warning-hover: oklch(0.722 0.141 75);
230
+ --ml-warning-text: oklch(0.8 0.16 75);
231
+ --ml-danger: oklch(0.7 0.191 25);
232
+ --ml-danger-foreground: oklch(0.18 0.02 25);
233
+ --ml-danger-hover: oklch(0.75 0.151 25);
234
+ --ml-danger-text: oklch(0.72 0.174 25);
235
+ --ml-info: oklch(0.74 0.14 250);
236
+ --ml-info-foreground: oklch(0.18 0.02 250);
237
+ --ml-info-hover: oklch(0.669 0.141 250);
238
+ --ml-info-text: oklch(0.74 0.14 250);
239
+ --ml-chart-1: oklch(0.74 0.136 255);
240
+ --ml-chart-2: oklch(0.74 0.138 50);
241
+ --ml-chart-3: oklch(0.74 0.138 145);
242
+ --ml-chart-4: oklch(0.74 0.138 300);
243
+ --ml-chart-5: oklch(0.74 0.13 185);
244
+ --ml-chart-6: oklch(0.74 0.138 10);
245
+ --ml-shadow-xs: 0 1px 2px oklch(0 0 0 / 0.1087);
246
+ --ml-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.0889), 0 2.052px 5.92px -1px oklch(0 0 0 / 0.1186);
247
+ --ml-shadow-md: 0 1px 2px oklch(0 0 0 / 0.079), 0 4.103px 13.32px -2px oklch(0 0 0 / 0.1581);
248
+ --ml-shadow-lg: 0 2px 4px oklch(0 0 0 / 0.0692), 0 8.206px 23.68px -4px oklch(0 0 0 / 0.1976);
249
+ --ml-shadow-xl: 0 4px 8px oklch(0 0 0 / 0.0593), 0 15.044px 41.44px -8px oklch(0 0 0 / 0.247);
250
+ --ml-shadow-tint: oklch(0 0 0 / 0.1581);
251
+ --ml-focus: var(--ml-primary-text);
252
+ --ml-fill-hover: color-mix(in oklab, var(--ml-text) 5%, transparent);
253
+ --ml-fill-active: color-mix(in oklab, var(--ml-text) 9%, transparent);
254
+ --ml-track: color-mix(in oklab, var(--ml-text) 12%, transparent);
255
+ --ml-control-border: var(--ml-text-faint);
256
+ --ml-ring: 0 0 0 3px color-mix(in oklab, var(--ml-focus) 24%, transparent);
257
+ --ml-scrim: oklch(from var(--ml-background) calc(l * 0.22) c h / calc(0.54 - l * 0.28));
258
+ --ml-highlight: oklch(1 0 0);
259
+ --ml-knob: var(--ml-highlight);
260
+ --ml-knob-shadow: 0 0 0 1px oklch(0 0 0 / 0.25), 0 1px 4px oklch(0 0 0 / 0.3);
261
+ --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
262
+ }
263
+ }
264
+
203
265
  @supports (transition-timing-function: linear(0, 1)) {
204
266
  :root,
205
267
  :root[data-theme="graphite"],
@@ -365,6 +427,67 @@
365
427
  --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
366
428
  }
367
429
 
430
+ /* data-mode="system" follows the reader's setting: light by default, dark when they ask for it. */
431
+ @media (prefers-color-scheme: dark) {
432
+ :root[data-theme="atelier"][data-mode="system"],
433
+ [data-theme="atelier"][data-mode="system"] {
434
+ color-scheme: dark;
435
+ --ml-background: oklch(0.134 0.022 260);
436
+ --ml-background-subtle: oklch(0.192 0.024 260);
437
+ --ml-surface: oklch(0.171 0.022 260);
438
+ --ml-surface-elevated: oklch(0.206 0.024 260);
439
+ --ml-text: oklch(0.954 0.01 80);
440
+ --ml-text-muted: oklch(0.705 0.022 80);
441
+ --ml-text-faint: oklch(0.635 0.016 80);
442
+ --ml-border: oklch(0.306 0.028 260);
443
+ --ml-border-subtle: oklch(0.257 0.024 260);
444
+ --ml-primary: oklch(0.75 0.16 68);
445
+ --ml-primary-foreground: oklch(0.18 0.02 68);
446
+ --ml-primary-hover: oklch(0.676 0.141 68);
447
+ --ml-primary-text: oklch(0.75 0.16 68);
448
+ --ml-primary-subtle: oklch(0.222 0.049 68);
449
+ --ml-success: oklch(0.72 0.15 150);
450
+ --ml-success-foreground: oklch(0.18 0.02 150);
451
+ --ml-success-hover: oklch(0.65 0.132 150);
452
+ --ml-success-text: oklch(0.72 0.15 150);
453
+ --ml-warning: oklch(0.8 0.16 75);
454
+ --ml-warning-foreground: oklch(0.18 0.02 75);
455
+ --ml-warning-hover: oklch(0.72 0.141 75);
456
+ --ml-warning-text: oklch(0.8 0.16 75);
457
+ --ml-danger: oklch(0.7 0.191 25);
458
+ --ml-danger-foreground: oklch(0.18 0.02 25);
459
+ --ml-danger-hover: oklch(0.75 0.151 25);
460
+ --ml-danger-text: oklch(0.72 0.174 25);
461
+ --ml-info: oklch(0.74 0.14 250);
462
+ --ml-info-foreground: oklch(0.18 0.02 250);
463
+ --ml-info-hover: oklch(0.667 0.141 250);
464
+ --ml-info-text: oklch(0.74 0.14 250);
465
+ --ml-chart-1: oklch(0.74 0.147 58);
466
+ --ml-chart-2: oklch(0.74 0.136 255);
467
+ --ml-chart-3: oklch(0.74 0.147 145);
468
+ --ml-chart-4: oklch(0.74 0.147 10);
469
+ --ml-chart-5: oklch(0.74 0.147 300);
470
+ --ml-chart-6: oklch(0.74 0.13 185);
471
+ --ml-shadow-xs: 0 1px 2px oklch(0 0 0 / 0.1735);
472
+ --ml-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.142), 0 3.189px 10.974px -1px oklch(0 0 0 / 0.1893);
473
+ --ml-shadow-md: 0 1px 2px oklch(0 0 0 / 0.1262), 0 6.378px 24.692px -2px oklch(0 0 0 / 0.2524);
474
+ --ml-shadow-lg: 0 2px 4px oklch(0 0 0 / 0.1104), 0 12.756px 43.898px -4px oklch(0 0 0 / 0.3155);
475
+ --ml-shadow-xl: 0 4px 8px oklch(0 0 0 / 0.0946), 0 23.387px 76.821px -8px oklch(0 0 0 / 0.3944);
476
+ --ml-shadow-tint: oklch(0 0 0 / 0.2524);
477
+ --ml-focus: var(--ml-primary-text);
478
+ --ml-fill-hover: color-mix(in oklab, var(--ml-text) 5%, transparent);
479
+ --ml-fill-active: color-mix(in oklab, var(--ml-text) 9%, transparent);
480
+ --ml-track: color-mix(in oklab, var(--ml-text) 12%, transparent);
481
+ --ml-control-border: var(--ml-text-faint);
482
+ --ml-ring: 0 0 0 3px color-mix(in oklab, var(--ml-focus) 24%, transparent);
483
+ --ml-scrim: oklch(from var(--ml-background) calc(l * 0.22) c h / calc(0.54 - l * 0.28));
484
+ --ml-highlight: oklch(1 0 0);
485
+ --ml-knob: var(--ml-highlight);
486
+ --ml-knob-shadow: 0 0 0 1px oklch(0 0 0 / 0.25), 0 1px 4px oklch(0 0 0 / 0.3);
487
+ --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
488
+ }
489
+ }
490
+
368
491
  @supports (transition-timing-function: linear(0, 1)) {
369
492
  :root[data-theme="atelier"],
370
493
  [data-theme="atelier"] {
@@ -529,6 +652,67 @@
529
652
  --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
530
653
  }
531
654
 
655
+ /* data-mode="system" follows the reader's setting: light by default, dark when they ask for it. */
656
+ @media (prefers-color-scheme: dark) {
657
+ :root[data-theme="machined"][data-mode="system"],
658
+ [data-theme="machined"][data-mode="system"] {
659
+ color-scheme: dark;
660
+ --ml-background: oklch(0.145 0.012 240);
661
+ --ml-background-subtle: oklch(0.203 0.013 240);
662
+ --ml-surface: oklch(0.177 0.012 240);
663
+ --ml-surface-elevated: oklch(0.212 0.013 240);
664
+ --ml-text: oklch(0.958 0.004 240);
665
+ --ml-text-muted: oklch(0.708 0.01 240);
666
+ --ml-text-faint: oklch(0.638 0.008 240);
667
+ --ml-border: oklch(0.309 0.016 240);
668
+ --ml-border-subtle: oklch(0.261 0.013 240);
669
+ --ml-primary: oklch(0.78 0.135 210);
670
+ --ml-primary-foreground: oklch(0.18 0.02 210);
671
+ --ml-primary-hover: oklch(0.704 0.122 210);
672
+ --ml-primary-text: oklch(0.78 0.135 210);
673
+ --ml-primary-subtle: oklch(0.233 0.04 210);
674
+ --ml-success: oklch(0.72 0.15 150);
675
+ --ml-success-foreground: oklch(0.18 0.02 150);
676
+ --ml-success-hover: oklch(0.651 0.132 150);
677
+ --ml-success-text: oklch(0.72 0.15 150);
678
+ --ml-warning: oklch(0.8 0.16 75);
679
+ --ml-warning-foreground: oklch(0.18 0.02 75);
680
+ --ml-warning-hover: oklch(0.721 0.141 75);
681
+ --ml-warning-text: oklch(0.8 0.16 75);
682
+ --ml-danger: oklch(0.7 0.191 25);
683
+ --ml-danger-foreground: oklch(0.18 0.02 25);
684
+ --ml-danger-hover: oklch(0.75 0.151 25);
685
+ --ml-danger-text: oklch(0.72 0.174 25);
686
+ --ml-info: oklch(0.74 0.14 250);
687
+ --ml-info-foreground: oklch(0.18 0.02 250);
688
+ --ml-info-hover: oklch(0.669 0.141 250);
689
+ --ml-info-text: oklch(0.74 0.14 250);
690
+ --ml-chart-1: oklch(0.74 0.136 255);
691
+ --ml-chart-2: oklch(0.74 0.138 50);
692
+ --ml-chart-3: oklch(0.74 0.138 145);
693
+ --ml-chart-4: oklch(0.74 0.138 300);
694
+ --ml-chart-5: oklch(0.74 0.13 185);
695
+ --ml-chart-6: oklch(0.74 0.138 10);
696
+ --ml-shadow-xs: 0 1px 2px oklch(0 0 0 / 0.1093);
697
+ --ml-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.0894), 0 1.914px 5.925px -1px oklch(0 0 0 / 0.1193);
698
+ --ml-shadow-md: 0 1px 2px oklch(0 0 0 / 0.0795), 0 3.828px 13.331px -2px oklch(0 0 0 / 0.159);
699
+ --ml-shadow-lg: 0 2px 4px oklch(0 0 0 / 0.0696), 0 7.655px 23.699px -4px oklch(0 0 0 / 0.1988);
700
+ --ml-shadow-xl: 0 4px 8px oklch(0 0 0 / 0.0596), 0 14.034px 41.474px -8px oklch(0 0 0 / 0.2485);
701
+ --ml-shadow-tint: oklch(0 0 0 / 0.159);
702
+ --ml-focus: var(--ml-primary-text);
703
+ --ml-fill-hover: color-mix(in oklab, var(--ml-text) 5%, transparent);
704
+ --ml-fill-active: color-mix(in oklab, var(--ml-text) 9%, transparent);
705
+ --ml-track: color-mix(in oklab, var(--ml-text) 12%, transparent);
706
+ --ml-control-border: var(--ml-text-faint);
707
+ --ml-ring: 0 0 0 3px color-mix(in oklab, var(--ml-focus) 24%, transparent);
708
+ --ml-scrim: oklch(from var(--ml-background) calc(l * 0.22) c h / calc(0.54 - l * 0.28));
709
+ --ml-highlight: oklch(1 0 0);
710
+ --ml-knob: var(--ml-highlight);
711
+ --ml-knob-shadow: 0 0 0 1px oklch(0 0 0 / 0.25), 0 1px 4px oklch(0 0 0 / 0.3);
712
+ --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
713
+ }
714
+ }
715
+
532
716
  @supports (transition-timing-function: linear(0, 1)) {
533
717
  :root[data-theme="machined"],
534
718
  [data-theme="machined"] {
@@ -693,6 +877,67 @@
693
877
  --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
694
878
  }
695
879
 
880
+ /* data-mode="system" follows the reader's setting: light by default, dark when they ask for it. */
881
+ @media (prefers-color-scheme: dark) {
882
+ :root[data-theme="aerogel"][data-mode="system"],
883
+ [data-theme="aerogel"][data-mode="system"] {
884
+ color-scheme: dark;
885
+ --ml-background: oklch(0.141 0.034 270);
886
+ --ml-background-subtle: oklch(0.199 0.037 270);
887
+ --ml-surface: oklch(0.185 0.034 270);
888
+ --ml-surface-elevated: oklch(0.22 0.037 270);
889
+ --ml-text: oklch(0.956 0.01 260);
890
+ --ml-text-muted: oklch(0.712 0.025 260);
891
+ --ml-text-faint: oklch(0.642 0.018 260);
892
+ --ml-border: oklch(0.309 0.044 270);
893
+ --ml-border-subtle: oklch(0.261 0.037 270);
894
+ --ml-primary: oklch(0.75 0.134 285);
895
+ --ml-primary-foreground: oklch(0.18 0.02 285);
896
+ --ml-primary-hover: oklch(0.677 0.176 285);
897
+ --ml-primary-text: oklch(0.75 0.134 285);
898
+ --ml-primary-subtle: oklch(0.229 0.07 285);
899
+ --ml-success: oklch(0.72 0.15 150);
900
+ --ml-success-foreground: oklch(0.18 0.02 150);
901
+ --ml-success-hover: oklch(0.651 0.132 150);
902
+ --ml-success-text: oklch(0.72 0.15 150);
903
+ --ml-warning: oklch(0.8 0.16 75);
904
+ --ml-warning-foreground: oklch(0.18 0.02 75);
905
+ --ml-warning-hover: oklch(0.721 0.141 75);
906
+ --ml-warning-text: oklch(0.8 0.16 75);
907
+ --ml-danger: oklch(0.7 0.191 25);
908
+ --ml-danger-foreground: oklch(0.18 0.02 25);
909
+ --ml-danger-hover: oklch(0.75 0.151 25);
910
+ --ml-danger-text: oklch(0.72 0.174 25);
911
+ --ml-info: oklch(0.74 0.14 250);
912
+ --ml-info-foreground: oklch(0.18 0.02 250);
913
+ --ml-info-hover: oklch(0.668 0.141 250);
914
+ --ml-info-text: oklch(0.74 0.14 250);
915
+ --ml-chart-1: oklch(0.74 0.14 285);
916
+ --ml-chart-2: oklch(0.74 0.156 145);
917
+ --ml-chart-3: oklch(0.74 0.156 50);
918
+ --ml-chart-4: oklch(0.74 0.156 10);
919
+ --ml-chart-5: oklch(0.74 0.13 185);
920
+ --ml-chart-6: oklch(0.74 0.136 255);
921
+ --ml-shadow-xs: 0 1px 2px oklch(0 0 0 / 0.2121);
922
+ --ml-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.1735), 0 4.909px 14.309px -1px oklch(0 0 0 / 0.2313);
923
+ --ml-shadow-md: 0 1px 2px oklch(0 0 0 / 0.1542), 0 9.818px 32.195px -2px oklch(0 0 0 / 0.3084);
924
+ --ml-shadow-lg: 0 2px 4px oklch(0 0 0 / 0.1349), 0 19.636px 57.235px -4px oklch(0 0 0 / 0.3855);
925
+ --ml-shadow-xl: 0 4px 8px oklch(0 0 0 / 0.1157), 0 35.999px 100.162px -8px oklch(0 0 0 / 0.4819);
926
+ --ml-shadow-tint: oklch(0 0 0 / 0.3084);
927
+ --ml-focus: var(--ml-primary-text);
928
+ --ml-fill-hover: color-mix(in oklab, var(--ml-text) 5%, transparent);
929
+ --ml-fill-active: color-mix(in oklab, var(--ml-text) 9%, transparent);
930
+ --ml-track: color-mix(in oklab, var(--ml-text) 12%, transparent);
931
+ --ml-control-border: var(--ml-text-faint);
932
+ --ml-ring: 0 0 0 3px color-mix(in oklab, var(--ml-focus) 24%, transparent);
933
+ --ml-scrim: oklch(from var(--ml-background) calc(l * 0.22) c h / calc(0.54 - l * 0.28));
934
+ --ml-highlight: oklch(1 0 0);
935
+ --ml-knob: var(--ml-highlight);
936
+ --ml-knob-shadow: 0 0 0 1px oklch(0 0 0 / 0.25), 0 1px 4px oklch(0 0 0 / 0.3);
937
+ --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
938
+ }
939
+ }
940
+
696
941
  @supports (transition-timing-function: linear(0, 1)) {
697
942
  :root[data-theme="aerogel"],
698
943
  [data-theme="aerogel"] {
@@ -857,6 +1102,67 @@
857
1102
  --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
858
1103
  }
859
1104
 
1105
+ /* data-mode="system" follows the reader's setting: light by default, dark when they ask for it. */
1106
+ @media (prefers-color-scheme: dark) {
1107
+ :root[data-theme="nordic"][data-mode="system"],
1108
+ [data-theme="nordic"][data-mode="system"] {
1109
+ color-scheme: dark;
1110
+ --ml-background: oklch(0.133 0.029 145);
1111
+ --ml-background-subtle: oklch(0.191 0.032 145);
1112
+ --ml-surface: oklch(0.167 0.029 145);
1113
+ --ml-surface-elevated: oklch(0.202 0.032 145);
1114
+ --ml-text: oklch(0.953 0.01 135);
1115
+ --ml-text-muted: oklch(0.701 0.025 135);
1116
+ --ml-text-faint: oklch(0.632 0.018 135);
1117
+ --ml-border: oklch(0.302 0.037 145);
1118
+ --ml-border-subtle: oklch(0.255 0.032 145);
1119
+ --ml-primary: oklch(0.72 0.15 150);
1120
+ --ml-primary-foreground: oklch(0.18 0.02 150);
1121
+ --ml-primary-hover: oklch(0.65 0.132 150);
1122
+ --ml-primary-text: oklch(0.72 0.15 150);
1123
+ --ml-primary-subtle: oklch(0.221 0.061 150);
1124
+ --ml-success: oklch(0.72 0.15 150);
1125
+ --ml-success-foreground: oklch(0.18 0.02 150);
1126
+ --ml-success-hover: oklch(0.65 0.132 150);
1127
+ --ml-success-text: oklch(0.72 0.15 150);
1128
+ --ml-warning: oklch(0.8 0.16 75);
1129
+ --ml-warning-foreground: oklch(0.18 0.02 75);
1130
+ --ml-warning-hover: oklch(0.72 0.141 75);
1131
+ --ml-warning-text: oklch(0.8 0.16 75);
1132
+ --ml-danger: oklch(0.7 0.191 25);
1133
+ --ml-danger-foreground: oklch(0.18 0.02 25);
1134
+ --ml-danger-hover: oklch(0.75 0.151 25);
1135
+ --ml-danger-text: oklch(0.72 0.174 25);
1136
+ --ml-info: oklch(0.74 0.14 250);
1137
+ --ml-info-foreground: oklch(0.18 0.02 250);
1138
+ --ml-info-hover: oklch(0.667 0.141 250);
1139
+ --ml-info-text: oklch(0.74 0.14 250);
1140
+ --ml-chart-1: oklch(0.74 0.129 150);
1141
+ --ml-chart-2: oklch(0.74 0.129 300);
1142
+ --ml-chart-3: oklch(0.74 0.129 50);
1143
+ --ml-chart-4: oklch(0.74 0.129 255);
1144
+ --ml-chart-5: oklch(0.74 0.129 10);
1145
+ --ml-chart-6: oklch(0.74 0.129 185);
1146
+ --ml-shadow-xs: 0 1px 2px oklch(0 0 0 / 0.1456);
1147
+ --ml-shadow-sm: 0 1px 2px oklch(0 0 0 / 0.1191), 0 2.444px 8.702px -1px oklch(0 0 0 / 0.1588);
1148
+ --ml-shadow-md: 0 1px 2px oklch(0 0 0 / 0.1059), 0 4.887px 19.58px -2px oklch(0 0 0 / 0.2118);
1149
+ --ml-shadow-lg: 0 2px 4px oklch(0 0 0 / 0.0927), 0 9.775px 34.81px -4px oklch(0 0 0 / 0.2647);
1150
+ --ml-shadow-xl: 0 4px 8px oklch(0 0 0 / 0.0794), 0 17.92px 60.917px -8px oklch(0 0 0 / 0.3309);
1151
+ --ml-shadow-tint: oklch(0 0 0 / 0.2118);
1152
+ --ml-focus: var(--ml-primary-text);
1153
+ --ml-fill-hover: color-mix(in oklab, var(--ml-text) 5%, transparent);
1154
+ --ml-fill-active: color-mix(in oklab, var(--ml-text) 9%, transparent);
1155
+ --ml-track: color-mix(in oklab, var(--ml-text) 12%, transparent);
1156
+ --ml-control-border: var(--ml-text-faint);
1157
+ --ml-ring: 0 0 0 3px color-mix(in oklab, var(--ml-focus) 24%, transparent);
1158
+ --ml-scrim: oklch(from var(--ml-background) calc(l * 0.22) c h / calc(0.54 - l * 0.28));
1159
+ --ml-highlight: oklch(1 0 0);
1160
+ --ml-knob: var(--ml-highlight);
1161
+ --ml-knob-shadow: 0 0 0 1px oklch(0 0 0 / 0.25), 0 1px 4px oklch(0 0 0 / 0.3);
1162
+ --ml-sheen: linear-gradient(135deg, color-mix(in oklab, var(--ml-highlight) 18%, transparent), transparent 46%, oklch(0 0 0 / 0.05));
1163
+ }
1164
+ }
1165
+
860
1166
  @supports (transition-timing-function: linear(0, 1)) {
861
1167
  :root[data-theme="nordic"],
862
1168
  [data-theme="nordic"] {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mlola-ui/engine",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Framework-free CSS, spring easings, and the machine-readable contract for Mlola UI",
5
5
  "type": "module",
6
6
  "sideEffects": [
package/src/theme-css.mjs CHANGED
@@ -17,13 +17,14 @@ function paletteLines(palette) {
17
17
  return Object.entries(palette).map(([token, value]) => `--ml-${token}: ${value}`);
18
18
  }
19
19
 
20
- function selectorList(spec, { root, aliases }, dark) {
20
+ /** The theme's selectors, for light (no mode), or for a mode: "dark", or "system" (dark only when the reader asks for it). */
21
+ function selectorList(spec, { root, aliases }, mode) {
21
22
  const attributes = [spec.id, ...aliases].map((name) => `[data-theme="${name}"]`);
22
23
  const list = [];
23
24
  if (root) list.push(":root");
24
25
  for (const attribute of attributes) list.push(`:root${attribute}`, attribute);
25
- if (!dark) return list.join(",\n");
26
- return list.map((selector) => (selector === ":root" ? ':root[data-mode="dark"]' : `${selector}[data-mode="dark"]`)).join(",\n");
26
+ if (!mode) return list.join(",\n");
27
+ return list.map((selector) => `${selector}[data-mode="${mode}"]`).join(",\n");
27
28
  }
28
29
 
29
30
  /**
@@ -45,6 +46,7 @@ export function renderSpecCss(spec, { root = false, aliases = [], banner = true
45
46
  const options = { root, aliases };
46
47
 
47
48
  const title = spec.label.replace(/\*\//g, "* /");
49
+ const darkBlock = ` color-scheme: dark;\n${indent(paletteLines(dark))}\n${indent(darkShadowDeclarations(spec.vector))}\n${indent(PALETTE_DERIVED)}`;
48
50
  return `${banner ? `/* ${title} — generated by @mlola-ui/engine from its theme spec. Do not hand edit. */\n` : ""}${selectorList(spec, options, false)} {
49
51
  color-scheme: light;
50
52
  ${indent(themeDeclarations(spec))}
@@ -52,11 +54,15 @@ ${indent(paletteLines(light))}
52
54
  ${indent(PALETTE_DERIVED)}
53
55
  }
54
56
 
55
- ${selectorList(spec, options, true)} {
56
- color-scheme: dark;
57
- ${indent(paletteLines(dark))}
58
- ${indent(darkShadowDeclarations(spec.vector))}
59
- ${indent(PALETTE_DERIVED)}
57
+ ${selectorList(spec, options, "dark")} {
58
+ ${darkBlock}
59
+ }
60
+
61
+ /* data-mode="system" follows the reader's setting: light by default, dark when they ask for it. */
62
+ @media (prefers-color-scheme: dark) {
63
+ ${selectorList(spec, options, "system")} {
64
+ ${darkBlock}
65
+ }
60
66
  }
61
67
 
62
68
  @supports (transition-timing-function: linear(0, 1)) {