@mlola-ui/tokens 1.0.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/LICENSE +21 -0
- package/README.md +34 -0
- package/generated/foundations.css +154 -0
- package/generated/materials.css +55 -0
- package/generated/mlola.css +10 -0
- package/generated/motion.css +93 -0
- package/generated/recipes.css +6504 -0
- package/generated/tokens.css +812 -0
- package/package.json +47 -0
- package/tokens.css +10 -0
- package/tokens.json +4751 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mlola
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# @mlola-ui/tokens
|
|
2
|
+
|
|
3
|
+
The stable, compatibility CSS entry for Mlola UI. Importing it loads the ordered
|
|
4
|
+
cascade layers for tokens, foundations, materials, recipes, and motion, so a
|
|
5
|
+
consumer only needs one line.
|
|
6
|
+
|
|
7
|
+
`@mlola-ui/engine` is the source of truth; this package is the durable entry
|
|
8
|
+
point that does not move when the engine's file layout changes.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @mlola-ui/tokens
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Use
|
|
17
|
+
|
|
18
|
+
```css
|
|
19
|
+
@import "@mlola-ui/tokens/tokens.css";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<html data-theme="atelier" data-mode="light">
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Exports
|
|
27
|
+
|
|
28
|
+
| Path | What it is |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| `@mlola-ui/tokens` | the default stylesheet |
|
|
31
|
+
| `@mlola-ui/tokens/tokens.json` | DTCG token document |
|
|
32
|
+
| `@mlola-ui/tokens/<layer>.css` | a single layer when you want narrower boundaries |
|
|
33
|
+
|
|
34
|
+
MIT licensed. Part of [Mlola UI](https://ui.mlola.com).
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* Foundation layer. */
|
|
2
|
+
*,
|
|
3
|
+
*::before,
|
|
4
|
+
*::after {
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
html {
|
|
9
|
+
-webkit-text-size-adjust: 100%;
|
|
10
|
+
text-size-adjust: 100%;
|
|
11
|
+
font-family: var(--ml-font-sans);
|
|
12
|
+
background: var(--ml-background);
|
|
13
|
+
color: var(--ml-text);
|
|
14
|
+
scroll-behavior: smooth;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
body {
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
margin: 0;
|
|
20
|
+
background: var(--ml-background);
|
|
21
|
+
color: var(--ml-text);
|
|
22
|
+
font-family: var(--ml-font-sans);
|
|
23
|
+
font-size: 1rem;
|
|
24
|
+
line-height: var(--ml-body-leading);
|
|
25
|
+
letter-spacing: var(--ml-tracking);
|
|
26
|
+
font-synthesis: none;
|
|
27
|
+
text-rendering: optimizeLegibility;
|
|
28
|
+
-webkit-font-smoothing: antialiased;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:where(h1,h2,h3,h4,h5,h6,p,figure,blockquote,dl,dd) {
|
|
32
|
+
margin: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:where(ul,ol)[role="list"] {
|
|
36
|
+
list-style: none;
|
|
37
|
+
margin: 0;
|
|
38
|
+
padding: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
:where(img,picture,video,canvas,svg) {
|
|
42
|
+
display: block;
|
|
43
|
+
max-width: 100%;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
:where(button,input,textarea,select) {
|
|
47
|
+
font: inherit;
|
|
48
|
+
color: inherit;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
:where(button,[role="button"]) {
|
|
52
|
+
touch-action: manipulation;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
:where(button,input,select,textarea,a[href],[tabindex]:not([tabindex="-1"])) {
|
|
56
|
+
scroll-margin-block: 1rem;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:where(a) {
|
|
60
|
+
color: inherit;
|
|
61
|
+
text-decoration-thickness: .08em;
|
|
62
|
+
text-underline-offset: .18em;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:where(h1,h2,h3) {
|
|
66
|
+
font-family: var(--ml-font-display);
|
|
67
|
+
font-weight: var(--ml-display-weight);
|
|
68
|
+
line-height: 1.08;
|
|
69
|
+
letter-spacing: -.025em;
|
|
70
|
+
text-wrap: balance;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
h1 {
|
|
74
|
+
font-size: clamp(2.25rem,5vw,4.75rem);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
h2 {
|
|
78
|
+
font-size: clamp(1.75rem,3.2vw,3rem);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
h3 {
|
|
82
|
+
font-size: clamp(1.25rem,2vw,1.75rem);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
:where(code,kbd,samp,pre) {
|
|
86
|
+
font-family: var(--ml-font-mono);
|
|
87
|
+
font-size: .925em;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
:where(pre) {
|
|
91
|
+
max-width: 100%;
|
|
92
|
+
overflow: auto;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
::selection {
|
|
96
|
+
background: color-mix(in srgb,var(--ml-primary) 28%,transparent);
|
|
97
|
+
color: var(--ml-text);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
::placeholder {
|
|
101
|
+
color: var(--ml-text-faint);
|
|
102
|
+
opacity: 1;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
:where(a,button,input,select,textarea,[role="button"],[tabindex]):focus-visible {
|
|
106
|
+
outline: 2px solid var(--ml-focus);
|
|
107
|
+
outline-offset: 2px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
:where(button,input,select,textarea):disabled,
|
|
111
|
+
[aria-disabled="true"] {
|
|
112
|
+
cursor: not-allowed;
|
|
113
|
+
opacity: .5;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@media (pointer:coarse) {
|
|
117
|
+
:where(button,[role="button"],input:not([type="hidden"]),select,textarea) {
|
|
118
|
+
min-height: var(--ml-target-min);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@media (prefers-reduced-transparency:reduce) {
|
|
123
|
+
* {
|
|
124
|
+
backdrop-filter: none!important;
|
|
125
|
+
-webkit-backdrop-filter: none!important;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@media (forced-colors:active) {
|
|
130
|
+
:root {
|
|
131
|
+
--ml-border: CanvasText;
|
|
132
|
+
--ml-focus: Highlight;
|
|
133
|
+
--ml-primary: Highlight;
|
|
134
|
+
--ml-primary-foreground: HighlightText;
|
|
135
|
+
--ml-primary-text: LinkText;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:where(a,button,input,select,textarea,[role="button"]) {
|
|
139
|
+
forced-color-adjust: auto;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Box-shadow rings vanish in forced colours; the system highlight stands in. */
|
|
143
|
+
:focus-visible {
|
|
144
|
+
outline: 2px solid Highlight!important;
|
|
145
|
+
outline-offset: 2px!important;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* The page scrollbar is left to the platform: styling it with
|
|
150
|
+
::-webkit-scrollbar forces a classic, space-taking scrollbar even where the
|
|
151
|
+
system uses overlay scrollbars, and the page then shifts whenever an
|
|
152
|
+
overlay locks scrolling. The theme's color-scheme already tints it for dark
|
|
153
|
+
mode. Scroll areas inside components opt into a thin, themed scrollbar
|
|
154
|
+
with the standard properties in their own stylesheets. */
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* Material recipes: apply a material to one surface regardless of theme. */
|
|
2
|
+
.ml-material-solid {
|
|
3
|
+
background: var(--ml-surface);
|
|
4
|
+
border: var(--ml-border-width) solid var(--ml-border);
|
|
5
|
+
box-shadow: var(--ml-shadow-xs);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.ml-material-elevated {
|
|
9
|
+
background: var(--ml-surface-elevated);
|
|
10
|
+
border: var(--ml-border-width) solid var(--ml-border);
|
|
11
|
+
box-shadow: var(--ml-shadow-md);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.ml-material-glass {
|
|
15
|
+
background: color-mix(in srgb,var(--ml-surface) 86%,transparent);
|
|
16
|
+
border: var(--ml-border-width) solid color-mix(in srgb,var(--ml-border) 78%,transparent);
|
|
17
|
+
box-shadow: var(--ml-shadow-sm);
|
|
18
|
+
backdrop-filter: blur(calc(10px + 12px * var(--ml-theme-depth))) saturate(145%);
|
|
19
|
+
-webkit-backdrop-filter: blur(calc(10px + 12px * var(--ml-theme-depth))) saturate(145%);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ml-material-anodized {
|
|
23
|
+
background: linear-gradient(145deg,color-mix(in srgb,var(--ml-surface-elevated) 94%,var(--ml-text)),var(--ml-surface));
|
|
24
|
+
border: var(--ml-border-width) solid var(--ml-border);
|
|
25
|
+
box-shadow: inset 0 1px color-mix(in srgb,var(--ml-text) 10%,transparent),var(--ml-shadow-sm);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.ml-material-paper {
|
|
29
|
+
background-color: var(--ml-surface);
|
|
30
|
+
background-image: radial-gradient(color-mix(in srgb,var(--ml-text) calc(var(--ml-texture-opacity) * 100%),transparent) .6px,transparent .7px);
|
|
31
|
+
background-size: 4px 4px;
|
|
32
|
+
border: var(--ml-border-width) solid var(--ml-border);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.ml-material-specular {
|
|
36
|
+
position: relative;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
background: var(--ml-surface);
|
|
39
|
+
border: var(--ml-border-width) solid var(--ml-border);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.ml-material-specular::after {
|
|
43
|
+
content: "";
|
|
44
|
+
position: absolute;
|
|
45
|
+
inset: 0;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
background: linear-gradient(135deg,oklch(1 0 0/.2),transparent 46%,oklch(0 0 0/.05));
|
|
48
|
+
mix-blend-mode: soft-light;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@supports not (backdrop-filter:blur(1px)) {
|
|
52
|
+
.ml-material-glass {
|
|
53
|
+
background: var(--ml-surface-elevated);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* Generated by @mlola-ui/engine. React and Tailwind are not required. */
|
|
2
|
+
@layer mlola.tokens, mlola.foundations, mlola.materials, mlola.recipes, mlola.motion, mlola.accessibility;
|
|
3
|
+
@import "./tokens.css" layer(mlola.tokens);
|
|
4
|
+
/* The project theme is a token source too, imported last within the same
|
|
5
|
+
layer so a brand wins over every canonical theme. */
|
|
6
|
+
@import "./theme.css" layer(mlola.tokens);
|
|
7
|
+
@import "./foundations.css" layer(mlola.foundations);
|
|
8
|
+
@import "./materials.css" layer(mlola.materials);
|
|
9
|
+
@import "./recipes.css" layer(mlola.recipes);
|
|
10
|
+
@import "./motion.css" layer(mlola.motion);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* Motion and accessibility layer. */
|
|
2
|
+
@keyframes ml-spin { to{transform:rotate(360deg)} }
|
|
3
|
+
|
|
4
|
+
@keyframes ml-pulse { 50%{opacity:.5} }
|
|
5
|
+
|
|
6
|
+
@keyframes ml-fade-in { from{opacity:0}to{opacity:1} }
|
|
7
|
+
|
|
8
|
+
@keyframes ml-pop-in { from{opacity:0;transform:translateY(4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)} }
|
|
9
|
+
|
|
10
|
+
@keyframes ml-dialog-in { from{opacity:0;transform:translate(-50%,-48%) scale(.96)}to{opacity:1;transform:translate(-50%,-50%) scale(1)} }
|
|
11
|
+
|
|
12
|
+
@keyframes ml-toast-in { from{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)} }
|
|
13
|
+
|
|
14
|
+
@keyframes ml-slide-left { from{transform:translateX(100%)}to{transform:translateX(0)} }
|
|
15
|
+
|
|
16
|
+
@keyframes ml-slide-right { from{transform:translateX(-100%)}to{transform:translateX(0)} }
|
|
17
|
+
|
|
18
|
+
@keyframes ml-slide-up { from{transform:translateY(100%)}to{transform:translateY(0)} }
|
|
19
|
+
|
|
20
|
+
@keyframes ml-slide-down { from{transform:translateY(-100%)}to{transform:translateY(0)} }
|
|
21
|
+
|
|
22
|
+
/* An overlay panel entering from wherever it sits: the element sets
|
|
23
|
+
--ml-enter-from to the transform it starts at. */
|
|
24
|
+
@keyframes ml-panel-in { from{opacity:0;transform:var(--ml-enter-from)} }
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@keyframes ml-shimmer { from{background-position:200% center}to{background-position:-200% center} }
|
|
29
|
+
|
|
30
|
+
.ml-animate-pop {
|
|
31
|
+
animation: ml-pop-in var(--ml-duration-normal) var(--ml-ease-bounce) both;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.ml-animate-slide-left {
|
|
35
|
+
animation: ml-slide-left var(--ml-duration-normal) var(--ml-ease-spring) both;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.ml-text-shimmer {
|
|
39
|
+
color: var(--ml-primary-text);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@supports ((-webkit-background-clip:text) or (background-clip:text)) {
|
|
43
|
+
.ml-text-shimmer {
|
|
44
|
+
background: linear-gradient(90deg,var(--ml-text),var(--ml-primary),var(--ml-text));
|
|
45
|
+
background-size: 200% auto;
|
|
46
|
+
background-clip: text;
|
|
47
|
+
-webkit-background-clip: text;
|
|
48
|
+
color: transparent;
|
|
49
|
+
-webkit-text-fill-color: transparent;
|
|
50
|
+
animation: ml-shimmer 3s ease-in-out infinite;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Glyph motion: an animated glyph draws itself, stroke by stroke, and its
|
|
55
|
+
filled details fade in after. It runs once when a glyph becomes active
|
|
56
|
+
(a check on success, a bell on a new alert) and never while idle. Shapes
|
|
57
|
+
carry pathLength="1", so one dash length fits every stroke. */
|
|
58
|
+
@keyframes mlola-glyph-draw { from{stroke-dashoffset:1} }
|
|
59
|
+
|
|
60
|
+
@keyframes mlola-glyph-fill { from{opacity:0} }
|
|
61
|
+
|
|
62
|
+
.mlola-glyph[data-animated] > * {
|
|
63
|
+
stroke-dasharray: 1 1;
|
|
64
|
+
animation: mlola-glyph-draw var(--ml-duration-slow) var(--ml-ease-standard) both;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.mlola-glyph[data-animated] > *:nth-child(2) { animation-delay: 60ms; }
|
|
68
|
+
|
|
69
|
+
.mlola-glyph[data-animated] > *:nth-child(3) { animation-delay: 120ms; }
|
|
70
|
+
|
|
71
|
+
.mlola-glyph[data-animated] > *:nth-child(n+4) { animation-delay: 180ms; }
|
|
72
|
+
|
|
73
|
+
.mlola-glyph[data-animated] > [fill="currentColor"] {
|
|
74
|
+
stroke-dasharray: none;
|
|
75
|
+
animation-name: mlola-glyph-fill;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@media (prefers-reduced-motion:reduce) {
|
|
79
|
+
html {
|
|
80
|
+
scroll-behavior: auto;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
*,
|
|
84
|
+
*::before,
|
|
85
|
+
*::after {
|
|
86
|
+
animation-delay: 0s!important;
|
|
87
|
+
animation-duration: .01ms!important;
|
|
88
|
+
animation-iteration-count: 1!important;
|
|
89
|
+
scroll-behavior: auto!important;
|
|
90
|
+
transition-delay: 0s!important;
|
|
91
|
+
transition-duration: .01ms!important;
|
|
92
|
+
}
|
|
93
|
+
}
|