@mlola-ui/engine 1.0.8 → 1.0.10

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/build.mjs CHANGED
@@ -34,6 +34,11 @@ const layers = {
34
34
 
35
35
  const layerOrder = "mlola.tokens, mlola.foundations, mlola.materials, mlola.recipes, mlola.motion, mlola.accessibility";
36
36
  const aggregate = `/* Generated by @mlola-ui/engine. React and Tailwind are not required. */
37
+ /* Where Mlola sits among a utility framework's layers, by Tailwind's names:
38
+ above its reset, so preflight never unstyles a component, whichever
39
+ stylesheet the app imports first. Without such a framework these layers
40
+ stay empty. */
41
+ @layer theme, base, mlola, components, utilities;
37
42
  @layer ${layerOrder};
38
43
  @import "./tokens.css" layer(mlola.tokens);
39
44
  /* The project theme is a token source too, imported last within the same
@@ -1376,13 +1376,13 @@
1376
1376
  "path": "download.svg",
1377
1377
  "role": "source",
1378
1378
  "bytes": 3444,
1379
- "integrity": "sha256-5cm99iahdj31U8SY6CmP2+i/Y7gqzep2xLhZSyR3lIw="
1379
+ "integrity": "sha256-BUz1gF+cjzSGX80cAXkBEbk2B/QfikfDVvMkXf9aetY="
1380
1380
  },
1381
1381
  {
1382
1382
  "path": "download.tsx",
1383
1383
  "role": "react",
1384
1384
  "bytes": 4359,
1385
- "integrity": "sha256-HCmxOC90IVFKx9MvBDtG9tuxSrYCOvS/yUm6Hxa6vN8="
1385
+ "integrity": "sha256-HqMG8B7wBduafDrBZ3k0PSxWpPZPWArZsJy3YXyv+Ew="
1386
1386
  }
1387
1387
  ],
1388
1388
  "themeable": true,
@@ -1673,7 +1673,7 @@
1673
1673
  "id": "link",
1674
1674
  "kind": "2d",
1675
1675
  "title": "Connected",
1676
- "summary": "Two interlocking metal links carrying a tiny shared signal.",
1676
+ "summary": "Two open chain links joined by a clear central bar with a restrained signal accent.",
1677
1677
  "tags": [
1678
1678
  "link",
1679
1679
  "connection",
@@ -1683,14 +1683,14 @@
1683
1683
  {
1684
1684
  "path": "link.svg",
1685
1685
  "role": "source",
1686
- "bytes": 2874,
1687
- "integrity": "sha256-dMvq0GVsY+/hNe6z8rZ5SJL7Jh/2RmtYFV6UX3+5GnY="
1686
+ "bytes": 2504,
1687
+ "integrity": "sha256-+gKXIfVp1G3qEUWS1veswBBwNwRcs5c04F1y3NKB7hs="
1688
1688
  },
1689
1689
  {
1690
1690
  "path": "link.tsx",
1691
1691
  "role": "react",
1692
- "bytes": 3737,
1693
- "integrity": "sha256-PmDMYKD2awnUZuEc/5AKBEk1wZefhKnwenG8MRSNpc8="
1692
+ "bytes": 3357,
1693
+ "integrity": "sha256-MGE+g1e9BmbGHP1XMzC/YKBCNqp3LO+b5Jb2DiN7wNU="
1694
1694
  }
1695
1695
  ],
1696
1696
  "themeable": true,
@@ -1841,7 +1841,7 @@
1841
1841
  "id": "notifications",
1842
1842
  "kind": "2d",
1843
1843
  "title": "Notifications",
1844
- "summary": "A small desk bell with one fresh notification card beside it.",
1844
+ "summary": "A softly outlined notification bell with a small clapper and one fresh message card.",
1845
1845
  "tags": [
1846
1846
  "notifications",
1847
1847
  "alerts",
@@ -1851,14 +1851,14 @@
1851
1851
  {
1852
1852
  "path": "notifications.svg",
1853
1853
  "role": "source",
1854
- "bytes": 3439,
1855
- "integrity": "sha256-+PZJkoooLoCtu8uoDJbdXAxR0oJPcA86j0uz9Ww2YyQ="
1854
+ "bytes": 3485,
1855
+ "integrity": "sha256-ihNfIqnU8XYhAQnwgl9t2ZOjN0m8XIC8HJmRsec7+EM="
1856
1856
  },
1857
1857
  {
1858
1858
  "path": "notifications.tsx",
1859
1859
  "role": "react",
1860
- "bytes": 4364,
1861
- "integrity": "sha256-c6x6JvSMARTd588qqW/pJ9RgdvEqINR2G6OxvvKOnAk="
1860
+ "bytes": 4431,
1861
+ "integrity": "sha256-8epIRgSRCUZLmlIjw/P2MZbmkYNXeIz4l5IiX6s22pc="
1862
1862
  }
1863
1863
  ],
1864
1864
  "themeable": true,
@@ -1949,6 +1949,62 @@
1949
1949
  "license": "MIT",
1950
1950
  "author": "Mlola"
1951
1951
  },
1952
+ {
1953
+ "id": "precise-layout",
1954
+ "kind": "2d",
1955
+ "title": "Precise layout",
1956
+ "summary": "A measured layout sheet and an extended tape, with aligned tick marks and a folded end hook.",
1957
+ "tags": [
1958
+ "measure",
1959
+ "layout",
1960
+ "design"
1961
+ ],
1962
+ "files": [
1963
+ {
1964
+ "path": "precise-layout.svg",
1965
+ "role": "source",
1966
+ "bytes": 4986,
1967
+ "integrity": "sha256-19uhMUCRTWI2J0Po8hbC3cyBmOhv2dxjMqLMsjHaFAo="
1968
+ },
1969
+ {
1970
+ "path": "precise-layout.tsx",
1971
+ "role": "react",
1972
+ "bytes": 6002,
1973
+ "integrity": "sha256-xUeKXphcaq5uFvfkci0bXbK3jzhh1QkRSSukH/BlG3k="
1974
+ }
1975
+ ],
1976
+ "themeable": true,
1977
+ "license": "MIT",
1978
+ "author": "Mlola"
1979
+ },
1980
+ {
1981
+ "id": "print-ready",
1982
+ "kind": "2d",
1983
+ "title": "Print ready",
1984
+ "summary": "A compact desktop printer with a fresh sheet feeding through a clearly defined output slot.",
1985
+ "tags": [
1986
+ "print",
1987
+ "documents",
1988
+ "export"
1989
+ ],
1990
+ "files": [
1991
+ {
1992
+ "path": "print-ready.svg",
1993
+ "role": "source",
1994
+ "bytes": 4240,
1995
+ "integrity": "sha256-Z5LuX5KA6LA/slehxyi5lJi2sMSmiVw5oGnzKqKxNAw="
1996
+ },
1997
+ {
1998
+ "path": "print-ready.tsx",
1999
+ "role": "react",
2000
+ "bytes": 5222,
2001
+ "integrity": "sha256-WI61gBtD0xRJYGOQLOxyo5utgw8obTyYad4Rjbvqunc="
2002
+ }
2003
+ ],
2004
+ "themeable": true,
2005
+ "license": "MIT",
2006
+ "author": "Mlola"
2007
+ },
1952
2008
  {
1953
2009
  "id": "quick-calculation",
1954
2010
  "kind": "2d",
@@ -1977,6 +2033,34 @@
1977
2033
  "license": "MIT",
1978
2034
  "author": "Mlola"
1979
2035
  },
2036
+ {
2037
+ "id": "quiet-workspace",
2038
+ "kind": "2d",
2039
+ "title": "Quiet workspace",
2040
+ "summary": "An articulated task lamp beside an open notebook, giving a single piece of work room to breathe.",
2041
+ "tags": [
2042
+ "workspace",
2043
+ "focus",
2044
+ "notes"
2045
+ ],
2046
+ "files": [
2047
+ {
2048
+ "path": "quiet-workspace.svg",
2049
+ "role": "source",
2050
+ "bytes": 4306,
2051
+ "integrity": "sha256-nQ8z7c5LiW6GkN6gPJqFP6fdjf7ZtgTL0KdLJzi5FAo="
2052
+ },
2053
+ {
2054
+ "path": "quiet-workspace.tsx",
2055
+ "role": "react",
2056
+ "bytes": 5307,
2057
+ "integrity": "sha256-18G80gjKTkOyudwlynL4CgJz2IhMjRl9H2s7w5yeOno="
2058
+ }
2059
+ ],
2060
+ "themeable": true,
2061
+ "license": "MIT",
2062
+ "author": "Mlola"
2063
+ },
1980
2064
  {
1981
2065
  "id": "responsive-layout",
1982
2066
  "kind": "2d",
@@ -2799,6 +2883,42 @@
2799
2883
  "license": "MIT",
2800
2884
  "author": "Mlola"
2801
2885
  },
2886
+ {
2887
+ "id": "measuring-tape",
2888
+ "kind": "3d",
2889
+ "title": "Measuring tape",
2890
+ "summary": "An enamel tape measure with a circular porcelain inset, evenly spaced marks and a folded metal end hook.",
2891
+ "tags": [
2892
+ "measure",
2893
+ "precision",
2894
+ "design"
2895
+ ],
2896
+ "files": [
2897
+ {
2898
+ "path": "measuring-tape.glb",
2899
+ "role": "source",
2900
+ "bytes": 592628,
2901
+ "integrity": "sha256-gjp8OVIjpEbmo0zeegc7p9W+gkYGeNqwETxuBfE43Js="
2902
+ },
2903
+ {
2904
+ "path": "measuring-tape-poster.webp",
2905
+ "role": "poster",
2906
+ "bytes": 16086,
2907
+ "integrity": "sha256-Ygzmwy/ttH5//dWsBUTsR+4XGQlD/YpodjI6y9caXuo="
2908
+ }
2909
+ ],
2910
+ "themeable": true,
2911
+ "materials": [
2912
+ "primary",
2913
+ "metal",
2914
+ "surface",
2915
+ "neutral",
2916
+ "accent",
2917
+ "ink"
2918
+ ],
2919
+ "license": "MIT",
2920
+ "author": "Mlola"
2921
+ },
2802
2922
  {
2803
2923
  "id": "notebook",
2804
2924
  "kind": "3d",
@@ -2936,6 +3056,41 @@
2936
3056
  "license": "MIT",
2937
3057
  "author": "Mlola"
2938
3058
  },
3059
+ {
3060
+ "id": "paper-printer",
3061
+ "kind": "3d",
3062
+ "title": "Paper printer",
3063
+ "summary": "A compact porcelain printer with a rear paper feed, inset output slot and a neatly printed sheet.",
3064
+ "tags": [
3065
+ "print",
3066
+ "documents",
3067
+ "workspace"
3068
+ ],
3069
+ "files": [
3070
+ {
3071
+ "path": "paper-printer.glb",
3072
+ "role": "source",
3073
+ "bytes": 457012,
3074
+ "integrity": "sha256-9sK7cA4R5ZYekDnTBrsZlUnYY4E/SUddQ/dCJGTtO9c="
3075
+ },
3076
+ {
3077
+ "path": "paper-printer-poster.webp",
3078
+ "role": "poster",
3079
+ "bytes": 16926,
3080
+ "integrity": "sha256-lRC0WaPykkZxEhtgEi4f0N93LFGoJ2uE0kfWbQOPR7Y="
3081
+ }
3082
+ ],
3083
+ "themeable": true,
3084
+ "materials": [
3085
+ "surface",
3086
+ "primary",
3087
+ "neutral",
3088
+ "ink",
3089
+ "accent"
3090
+ ],
3091
+ "license": "MIT",
3092
+ "author": "Mlola"
3093
+ },
2939
3094
  {
2940
3095
  "id": "rocket",
2941
3096
  "kind": "3d",
@@ -3040,6 +3195,41 @@
3040
3195
  "license": "MIT",
3041
3196
  "author": "Mlola"
3042
3197
  },
3198
+ {
3199
+ "id": "task-lamp",
3200
+ "kind": "3d",
3201
+ "title": "Task lamp",
3202
+ "summary": "An articulated desk lamp with aligned metal joints, an enamel light bar and a porcelain diffuser.",
3203
+ "tags": [
3204
+ "workspace",
3205
+ "focus",
3206
+ "lighting"
3207
+ ],
3208
+ "files": [
3209
+ {
3210
+ "path": "task-lamp.glb",
3211
+ "role": "source",
3212
+ "bytes": 283168,
3213
+ "integrity": "sha256-hAolZPXrmhkMW0DjUx/aB4iXTEBm3YFDnoTzOqsMtMc="
3214
+ },
3215
+ {
3216
+ "path": "task-lamp-poster.webp",
3217
+ "role": "poster",
3218
+ "bytes": 16676,
3219
+ "integrity": "sha256-KczARj6DGDO6U9YrYZ5LLTKCHK922mbXLvJtcmeMEfQ="
3220
+ }
3221
+ ],
3222
+ "themeable": true,
3223
+ "materials": [
3224
+ "surface",
3225
+ "neutral",
3226
+ "metal",
3227
+ "primary",
3228
+ "accent"
3229
+ ],
3230
+ "license": "MIT",
3231
+ "author": "Mlola"
3232
+ },
3043
3233
  {
3044
3234
  "id": "usb-stick",
3045
3235
  "kind": "3d",
@@ -1,4 +1,9 @@
1
1
  /* Generated by @mlola-ui/engine. React and Tailwind are not required. */
2
+ /* Where Mlola sits among a utility framework's layers, by Tailwind's names:
3
+ above its reset, so preflight never unstyles a component, whichever
4
+ stylesheet the app imports first. Without such a framework these layers
5
+ stay empty. */
6
+ @layer theme, base, mlola, components, utilities;
2
7
  @layer mlola.tokens, mlola.foundations, mlola.materials, mlola.recipes, mlola.motion, mlola.accessibility;
3
8
  @import "./tokens.css" layer(mlola.tokens);
4
9
  /* The project theme is a token source too, imported last within the same
@@ -7,9 +7,26 @@
7
7
  display: none !important;
8
8
  }
9
9
 
10
- /* Icons keep their size inside flex rows; a squeezed row shrinks text, not glyphs. */
10
+ /* Icons sit on the text's optical center and keep their size inside flex
11
+ rows; a squeezed row shrinks text, not glyphs. The same rules ship in
12
+ @mlola-ui/icons/glyphs.css for apps that use the icons without the engine. */
11
13
  :where(.mlola-glyph) {
14
+ display: inline-block;
12
15
  flex-shrink: 0;
16
+ overflow: visible;
17
+ vertical-align: -0.125em;
18
+ transform-box: fill-box;
19
+ transform-origin: center;
20
+ }
21
+
22
+ :where(.mlola-glyph[data-optical-size="small"]) {
23
+ --mlola-glyph-stroke: 2;
24
+ --mlola-glyph-optical-scale: 0.94;
25
+ }
26
+
27
+ :where(.mlola-glyph[data-optical-size="large"]) {
28
+ --mlola-glyph-stroke: 1.5;
29
+ --mlola-glyph-optical-scale: 1.03;
13
30
  }
14
31
 
15
32
  .ml-visually-hidden {
@@ -54,7 +54,7 @@
54
54
  "id": "atelier",
55
55
  "label": "Atelier Umami",
56
56
  "name": "Atelier Umami",
57
- "swatch": "oklch(0.638 0.153 58)",
57
+ "swatch": "oklch(0.532 0.127 58)",
58
58
  "material": "paper",
59
59
  "theme": {
60
60
  "type": 0.82,
@@ -267,9 +267,9 @@
267
267
  --ml-text-faint: oklch(0.492 0.018 260);
268
268
  --ml-border: oklch(0.878 0.023 80);
269
269
  --ml-border-subtle: oklch(0.916 0.018 80);
270
- --ml-primary: oklch(0.638 0.153 58);
271
- --ml-primary-foreground: oklch(0.18 0.02 58);
272
- --ml-primary-hover: oklch(0.678 0.141 58);
270
+ --ml-primary: oklch(0.532 0.127 58);
271
+ --ml-primary-foreground: oklch(0.99 0 0);
272
+ --ml-primary-hover: oklch(0.482 0.115 58);
273
273
  --ml-primary-text: oklch(0.497 0.119 58);
274
274
  --ml-primary-subtle: oklch(0.95 0.031 58);
275
275
  --ml-success: oklch(0.507 0.14 150);
@@ -1361,8 +1361,8 @@
1361
1361
  "$value": {
1362
1362
  "colorSpace": "oklch",
1363
1363
  "components": [
1364
- 0.638,
1365
- 0.153,
1364
+ 0.532,
1365
+ 0.127,
1366
1366
  58
1367
1367
  ],
1368
1368
  "alpha": 1
@@ -1373,9 +1373,9 @@
1373
1373
  "$value": {
1374
1374
  "colorSpace": "oklch",
1375
1375
  "components": [
1376
- 0.18,
1377
- 0.02,
1378
- 58
1376
+ 0.99,
1377
+ 0,
1378
+ 0
1379
1379
  ],
1380
1380
  "alpha": 1
1381
1381
  }
@@ -1385,8 +1385,8 @@
1385
1385
  "$value": {
1386
1386
  "colorSpace": "oklch",
1387
1387
  "components": [
1388
- 0.678,
1389
- 0.141,
1388
+ 0.482,
1389
+ 0.115,
1390
1390
  58
1391
1391
  ],
1392
1392
  "alpha": 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mlola-ui/engine",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Framework-free CSS, spring easings, and the machine-readable contract for Mlola UI",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -8,8 +8,6 @@
8
8
  * ledger entry remains.
9
9
  */
10
10
 
11
- export const CURRENT_VERSION = "0.3.0";
12
-
13
11
  export const DEPRECATIONS = [
14
12
  // 1.0 removed data-skin, the shadcn --background/--chart-*/--sidebar-*
15
13
  // aliases, the .ml-button-* class variants and every other duplicate
package/src/palette.mjs CHANGED
@@ -126,13 +126,15 @@ const isAchromatic = (color) => color.C < 0.03;
126
126
 
127
127
  /**
128
128
  * WCAG 2's ratio favours dark ink on mid-tone saturated colors, but eyes read
129
- * white on a violet, blue, green or red far better. In light mode a chromatic,
130
- * non-warm fill darkens a little (at most 0.12 L) so white clears the target;
131
- * yellows and oranges keep dark ink, as convention expects.
129
+ * white on a violet, blue, green, red or burnt orange far better: dark ink on
130
+ * a mid orange reads as dark on dark. In light mode a chromatic fill darkens a
131
+ * little (at most 0.12 L) so white clears the target. Ambers and yellows keep
132
+ * dark ink, as convention expects, and so does an orange too bright to reach
133
+ * white within that step.
132
134
  */
133
135
  function deepenForWhite(fill, mode) {
134
- const warm = fill.H > 40 && fill.H < 130;
135
- if (mode !== "light" || isAchromatic(fill) || warm || contrast(WHITE, fill) >= TARGETS.body) return fill;
136
+ const yellow = fill.H >= 65 && fill.H < 130;
137
+ if (mode !== "light" || isAchromatic(fill) || yellow || contrast(WHITE, fill) >= TARGETS.body) return fill;
136
138
  const deeper = solveLightness(fill, WHITE, TARGETS.body, "darker");
137
139
  return fill.L - deeper.L <= 0.12 ? deeper : fill;
138
140
  }