@handamade/psi-tokens 0.7.1 → 0.8.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dmitry Kurkin
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/dist/base.css CHANGED
@@ -51,6 +51,7 @@
51
51
  --psi-text-16-20-regular: 400 1rem/1.25rem var(--psi-font-sans);
52
52
  --psi-text-16-24-regular: 400 1rem/1.5rem var(--psi-font-sans);
53
53
  --psi-text-16-24-medium: 500 1rem/1.5rem var(--psi-font-sans);
54
+ --psi-text-18-28-regular: 400 1.125rem/1.75rem var(--psi-font-sans);
54
55
  --psi-text-18-28-medium: 500 1.125rem/1.75rem var(--psi-font-sans);
55
56
  --psi-text-20-28-semibold: 600 1.25rem/1.75rem var(--psi-font-sans);
56
57
  --psi-text-24-32-medium: 500 1.5rem/2rem var(--psi-font-sans);
@@ -35,5 +35,26 @@
35
35
  --psi-button-outline-fg-hover: var(--psi-button-accent-fg);
36
36
  --psi-button-outline-border: var(--psi-border-strong);
37
37
  --psi-button-focus-ring: var(--psi-border-focus);
38
+ --psi-button-radius: var(--psi-control-radius);
39
+ --psi-button-24-height: var(--psi-control-24-height);
40
+ --psi-button-32-height: var(--psi-control-32-height);
41
+ --psi-button-40-height: var(--psi-control-40-height);
42
+ --psi-button-48-height: var(--psi-control-48-height);
43
+ --psi-button-24-padding-inline: var(--psi-control-24-padding-inline);
44
+ --psi-button-32-padding-inline: var(--psi-control-32-padding-inline);
45
+ --psi-button-40-padding-inline: var(--psi-control-40-padding-inline);
46
+ --psi-button-48-padding-inline: var(--psi-control-48-padding-inline);
47
+ --psi-button-24-padding-inline-icon: var(--psi-control-24-padding-inline-icon);
48
+ --psi-button-32-padding-inline-icon: var(--psi-control-32-padding-inline-icon);
49
+ --psi-button-40-padding-inline-icon: var(--psi-control-40-padding-inline-icon);
50
+ --psi-button-48-padding-inline-icon: var(--psi-control-48-padding-inline-icon);
51
+ --psi-button-24-gap: var(--psi-control-24-gap);
52
+ --psi-button-32-gap: var(--psi-control-32-gap);
53
+ --psi-button-40-gap: var(--psi-control-40-gap);
54
+ --psi-button-48-gap: var(--psi-control-48-gap);
55
+ --psi-button-24-font: var(--psi-control-24-font);
56
+ --psi-button-32-font: var(--psi-control-32-font);
57
+ --psi-button-40-font: var(--psi-control-40-font);
58
+ --psi-button-48-font: var(--psi-control-48-font);
38
59
  }
39
60
  }
@@ -5,6 +5,7 @@
5
5
  --psi-checkbox-box-border: var(--psi-border-neutral);
6
6
  --psi-checkbox-box-bg-checked: var(--psi-fill-accent);
7
7
  --psi-checkbox-box-border-checked: var(--psi-fill-accent);
8
+ --psi-checkbox-box-radius: min(var(--psi-control-radius), var(--psi-radius-4));
8
9
  --psi-checkbox-check-fg: var(--psi-fg-on-accent);
9
10
  --psi-checkbox-focus-ring: var(--psi-border-focus);
10
11
  }
@@ -0,0 +1,33 @@
1
+ @layer psi.components {
2
+ :where(:root, [data-psi-theme]) {
3
+ --psi-control-24-height: var(--psi-size-24);
4
+ --psi-control-32-height: var(--psi-size-32);
5
+ --psi-control-40-height: var(--psi-size-40);
6
+ --psi-control-48-height: var(--psi-size-48);
7
+ --psi-control-24-gap: var(--psi-space-4);
8
+ --psi-control-32-gap: var(--psi-space-8);
9
+ --psi-control-40-gap: var(--psi-space-8);
10
+ --psi-control-48-gap: var(--psi-space-8);
11
+ --psi-control-24-padding-inline: var(--psi-space-8);
12
+ --psi-control-32-padding-inline: var(--psi-space-12);
13
+ --psi-control-40-padding-inline: var(--psi-space-16);
14
+ --psi-control-48-padding-inline: var(--psi-space-20);
15
+ --psi-control-24-padding-inline-icon: var(--psi-space-6);
16
+ --psi-control-32-padding-inline-icon: var(--psi-space-8);
17
+ --psi-control-40-padding-inline-icon: var(--psi-space-12);
18
+ --psi-control-48-padding-inline-icon: var(--psi-space-16);
19
+ --psi-control-24-font: var(--psi-text-12-16-medium);
20
+ --psi-control-32-font: var(--psi-text-14-20-medium);
21
+ --psi-control-40-font: var(--psi-text-16-24-medium);
22
+ --psi-control-48-font: var(--psi-text-18-28-medium);
23
+ --psi-control-value-24-padding-inline: var(--psi-space-8);
24
+ --psi-control-value-32-padding-inline: var(--psi-space-8);
25
+ --psi-control-value-40-padding-inline: var(--psi-space-12);
26
+ --psi-control-value-48-padding-inline: var(--psi-space-16);
27
+ --psi-control-value-24-font: var(--psi-text-12-16-regular);
28
+ --psi-control-value-32-font: var(--psi-text-14-20-regular);
29
+ --psi-control-value-40-font: var(--psi-text-16-24-regular);
30
+ --psi-control-value-48-font: var(--psi-text-18-28-regular);
31
+ --psi-control-radius: var(--psi-radius-8);
32
+ }
33
+ }
@@ -7,5 +7,18 @@
7
7
  --psi-input-border-hover: var(--psi-border-strong);
8
8
  --psi-input-border-error: var(--psi-fg-danger);
9
9
  --psi-input-focus-ring: var(--psi-border-focus);
10
+ --psi-input-radius: var(--psi-control-radius);
11
+ --psi-input-24-height: var(--psi-control-24-height);
12
+ --psi-input-32-height: var(--psi-control-32-height);
13
+ --psi-input-40-height: var(--psi-control-40-height);
14
+ --psi-input-48-height: var(--psi-control-48-height);
15
+ --psi-input-24-padding-inline: var(--psi-control-value-24-padding-inline);
16
+ --psi-input-32-padding-inline: var(--psi-control-value-32-padding-inline);
17
+ --psi-input-40-padding-inline: var(--psi-control-value-40-padding-inline);
18
+ --psi-input-48-padding-inline: var(--psi-control-value-48-padding-inline);
19
+ --psi-input-24-font: var(--psi-control-value-24-font);
20
+ --psi-input-32-font: var(--psi-control-value-32-font);
21
+ --psi-input-40-font: var(--psi-control-value-40-font);
22
+ --psi-input-48-font: var(--psi-control-value-48-font);
10
23
  }
11
24
  }
@@ -0,0 +1,15 @@
1
+ @layer psi.components {
2
+ :where(:root, [data-psi-theme]) {
3
+ --psi-menu-bg: var(--psi-surface-bg);
4
+ --psi-menu-border: var(--psi-surface-border);
5
+ --psi-menu-radius: var(--psi-surface-radius);
6
+ --psi-menu-fg: var(--psi-fg-primary);
7
+ --psi-menu-item-bg: transparent;
8
+ --psi-menu-item-bg-hover: var(--psi-fill-neutral3);
9
+ --psi-menu-item-bg-active: var(--psi-fill-neutral4);
10
+ --psi-menu-item-fg: var(--psi-fg-primary);
11
+ --psi-menu-item-fg-danger: var(--psi-fg-danger);
12
+ --psi-menu-item-fg-disabled: var(--psi-fg-quaternary);
13
+ --psi-menu-separator-border: var(--psi-border-faint);
14
+ }
15
+ }
@@ -8,5 +8,26 @@
8
8
  --psi-select-border-error: var(--psi-fg-danger);
9
9
  --psi-select-focus-ring: var(--psi-border-focus);
10
10
  --psi-select-chevron-fg: var(--psi-fg-secondary);
11
+ --psi-select-radius: var(--psi-control-radius);
12
+ --psi-select-24-height: var(--psi-control-24-height);
13
+ --psi-select-32-height: var(--psi-control-32-height);
14
+ --psi-select-40-height: var(--psi-control-40-height);
15
+ --psi-select-48-height: var(--psi-control-48-height);
16
+ --psi-select-24-padding-inline: var(--psi-control-value-24-padding-inline);
17
+ --psi-select-32-padding-inline: var(--psi-control-value-32-padding-inline);
18
+ --psi-select-40-padding-inline: var(--psi-control-value-40-padding-inline);
19
+ --psi-select-48-padding-inline: var(--psi-control-value-48-padding-inline);
20
+ --psi-select-24-font: var(--psi-control-value-24-font);
21
+ --psi-select-32-font: var(--psi-control-value-32-font);
22
+ --psi-select-40-font: var(--psi-control-value-40-font);
23
+ --psi-select-48-font: var(--psi-control-value-48-font);
24
+ --psi-select-24-chevron-offset: var(--psi-control-value-24-padding-inline);
25
+ --psi-select-32-chevron-offset: var(--psi-control-value-32-padding-inline);
26
+ --psi-select-40-chevron-offset: var(--psi-control-value-40-padding-inline);
27
+ --psi-select-48-chevron-offset: var(--psi-control-value-48-padding-inline);
28
+ --psi-select-24-padding-inline-end: calc(var(--psi-control-value-24-padding-inline) + var(--psi-space-16));
29
+ --psi-select-32-padding-inline-end: calc(var(--psi-control-value-32-padding-inline) + var(--psi-space-16));
30
+ --psi-select-40-padding-inline-end: calc(var(--psi-control-value-40-padding-inline) + var(--psi-space-16));
31
+ --psi-select-48-padding-inline-end: calc(var(--psi-control-value-48-padding-inline) + var(--psi-space-16));
11
32
  }
12
33
  }
@@ -2,5 +2,6 @@
2
2
  :where(:root, [data-psi-theme]) {
3
3
  --psi-tooltip-bg: var(--psi-bg-inverted);
4
4
  --psi-tooltip-fg: var(--psi-fg-on-inverted);
5
+ --psi-tooltip-radius: min(var(--psi-control-radius), var(--psi-radius-6));
5
6
  }
6
7
  }
@@ -35,6 +35,27 @@
35
35
  --psi-button-outline-fg-hover: var(--psi-button-accent-fg);
36
36
  --psi-button-outline-border: var(--psi-border-strong);
37
37
  --psi-button-focus-ring: var(--psi-border-focus);
38
+ --psi-button-radius: var(--psi-control-radius);
39
+ --psi-button-24-height: var(--psi-control-24-height);
40
+ --psi-button-32-height: var(--psi-control-32-height);
41
+ --psi-button-40-height: var(--psi-control-40-height);
42
+ --psi-button-48-height: var(--psi-control-48-height);
43
+ --psi-button-24-padding-inline: var(--psi-control-24-padding-inline);
44
+ --psi-button-32-padding-inline: var(--psi-control-32-padding-inline);
45
+ --psi-button-40-padding-inline: var(--psi-control-40-padding-inline);
46
+ --psi-button-48-padding-inline: var(--psi-control-48-padding-inline);
47
+ --psi-button-24-padding-inline-icon: var(--psi-control-24-padding-inline-icon);
48
+ --psi-button-32-padding-inline-icon: var(--psi-control-32-padding-inline-icon);
49
+ --psi-button-40-padding-inline-icon: var(--psi-control-40-padding-inline-icon);
50
+ --psi-button-48-padding-inline-icon: var(--psi-control-48-padding-inline-icon);
51
+ --psi-button-24-gap: var(--psi-control-24-gap);
52
+ --psi-button-32-gap: var(--psi-control-32-gap);
53
+ --psi-button-40-gap: var(--psi-control-40-gap);
54
+ --psi-button-48-gap: var(--psi-control-48-gap);
55
+ --psi-button-24-font: var(--psi-control-24-font);
56
+ --psi-button-32-font: var(--psi-control-32-font);
57
+ --psi-button-40-font: var(--psi-control-40-font);
58
+ --psi-button-48-font: var(--psi-control-48-font);
38
59
  }
39
60
  }
40
61
 
@@ -54,11 +75,46 @@
54
75
  --psi-checkbox-box-border: var(--psi-border-neutral);
55
76
  --psi-checkbox-box-bg-checked: var(--psi-fill-accent);
56
77
  --psi-checkbox-box-border-checked: var(--psi-fill-accent);
78
+ --psi-checkbox-box-radius: min(var(--psi-control-radius), var(--psi-radius-4));
57
79
  --psi-checkbox-check-fg: var(--psi-fg-on-accent);
58
80
  --psi-checkbox-focus-ring: var(--psi-border-focus);
59
81
  }
60
82
  }
61
83
 
84
+ @layer psi.components {
85
+ :where(:root, [data-psi-theme]) {
86
+ --psi-control-24-height: var(--psi-size-24);
87
+ --psi-control-32-height: var(--psi-size-32);
88
+ --psi-control-40-height: var(--psi-size-40);
89
+ --psi-control-48-height: var(--psi-size-48);
90
+ --psi-control-24-gap: var(--psi-space-4);
91
+ --psi-control-32-gap: var(--psi-space-8);
92
+ --psi-control-40-gap: var(--psi-space-8);
93
+ --psi-control-48-gap: var(--psi-space-8);
94
+ --psi-control-24-padding-inline: var(--psi-space-8);
95
+ --psi-control-32-padding-inline: var(--psi-space-12);
96
+ --psi-control-40-padding-inline: var(--psi-space-16);
97
+ --psi-control-48-padding-inline: var(--psi-space-20);
98
+ --psi-control-24-padding-inline-icon: var(--psi-space-6);
99
+ --psi-control-32-padding-inline-icon: var(--psi-space-8);
100
+ --psi-control-40-padding-inline-icon: var(--psi-space-12);
101
+ --psi-control-48-padding-inline-icon: var(--psi-space-16);
102
+ --psi-control-24-font: var(--psi-text-12-16-medium);
103
+ --psi-control-32-font: var(--psi-text-14-20-medium);
104
+ --psi-control-40-font: var(--psi-text-16-24-medium);
105
+ --psi-control-48-font: var(--psi-text-18-28-medium);
106
+ --psi-control-value-24-padding-inline: var(--psi-space-8);
107
+ --psi-control-value-32-padding-inline: var(--psi-space-8);
108
+ --psi-control-value-40-padding-inline: var(--psi-space-12);
109
+ --psi-control-value-48-padding-inline: var(--psi-space-16);
110
+ --psi-control-value-24-font: var(--psi-text-12-16-regular);
111
+ --psi-control-value-32-font: var(--psi-text-14-20-regular);
112
+ --psi-control-value-40-font: var(--psi-text-16-24-regular);
113
+ --psi-control-value-48-font: var(--psi-text-18-28-regular);
114
+ --psi-control-radius: var(--psi-radius-8);
115
+ }
116
+ }
117
+
62
118
  @layer psi.components {
63
119
  :where(:root, [data-psi-theme]) {
64
120
  --psi-dialog-bg: var(--psi-surface-bg);
@@ -89,6 +145,19 @@
89
145
  --psi-input-border-hover: var(--psi-border-strong);
90
146
  --psi-input-border-error: var(--psi-fg-danger);
91
147
  --psi-input-focus-ring: var(--psi-border-focus);
148
+ --psi-input-radius: var(--psi-control-radius);
149
+ --psi-input-24-height: var(--psi-control-24-height);
150
+ --psi-input-32-height: var(--psi-control-32-height);
151
+ --psi-input-40-height: var(--psi-control-40-height);
152
+ --psi-input-48-height: var(--psi-control-48-height);
153
+ --psi-input-24-padding-inline: var(--psi-control-value-24-padding-inline);
154
+ --psi-input-32-padding-inline: var(--psi-control-value-32-padding-inline);
155
+ --psi-input-40-padding-inline: var(--psi-control-value-40-padding-inline);
156
+ --psi-input-48-padding-inline: var(--psi-control-value-48-padding-inline);
157
+ --psi-input-24-font: var(--psi-control-value-24-font);
158
+ --psi-input-32-font: var(--psi-control-value-32-font);
159
+ --psi-input-40-font: var(--psi-control-value-40-font);
160
+ --psi-input-48-font: var(--psi-control-value-48-font);
92
161
  }
93
162
  }
94
163
 
@@ -98,6 +167,22 @@
98
167
  }
99
168
  }
100
169
 
170
+ @layer psi.components {
171
+ :where(:root, [data-psi-theme]) {
172
+ --psi-menu-bg: var(--psi-surface-bg);
173
+ --psi-menu-border: var(--psi-surface-border);
174
+ --psi-menu-radius: var(--psi-surface-radius);
175
+ --psi-menu-fg: var(--psi-fg-primary);
176
+ --psi-menu-item-bg: transparent;
177
+ --psi-menu-item-bg-hover: var(--psi-fill-neutral3);
178
+ --psi-menu-item-bg-active: var(--psi-fill-neutral4);
179
+ --psi-menu-item-fg: var(--psi-fg-primary);
180
+ --psi-menu-item-fg-danger: var(--psi-fg-danger);
181
+ --psi-menu-item-fg-disabled: var(--psi-fg-quaternary);
182
+ --psi-menu-separator-border: var(--psi-border-faint);
183
+ }
184
+ }
185
+
101
186
  @layer psi.components {
102
187
  :where(:root, [data-psi-theme]) {
103
188
  --psi-navbar-height: 4rem;
@@ -129,6 +214,27 @@
129
214
  --psi-select-border-error: var(--psi-fg-danger);
130
215
  --psi-select-focus-ring: var(--psi-border-focus);
131
216
  --psi-select-chevron-fg: var(--psi-fg-secondary);
217
+ --psi-select-radius: var(--psi-control-radius);
218
+ --psi-select-24-height: var(--psi-control-24-height);
219
+ --psi-select-32-height: var(--psi-control-32-height);
220
+ --psi-select-40-height: var(--psi-control-40-height);
221
+ --psi-select-48-height: var(--psi-control-48-height);
222
+ --psi-select-24-padding-inline: var(--psi-control-value-24-padding-inline);
223
+ --psi-select-32-padding-inline: var(--psi-control-value-32-padding-inline);
224
+ --psi-select-40-padding-inline: var(--psi-control-value-40-padding-inline);
225
+ --psi-select-48-padding-inline: var(--psi-control-value-48-padding-inline);
226
+ --psi-select-24-font: var(--psi-control-value-24-font);
227
+ --psi-select-32-font: var(--psi-control-value-32-font);
228
+ --psi-select-40-font: var(--psi-control-value-40-font);
229
+ --psi-select-48-font: var(--psi-control-value-48-font);
230
+ --psi-select-24-chevron-offset: var(--psi-control-value-24-padding-inline);
231
+ --psi-select-32-chevron-offset: var(--psi-control-value-32-padding-inline);
232
+ --psi-select-40-chevron-offset: var(--psi-control-value-40-padding-inline);
233
+ --psi-select-48-chevron-offset: var(--psi-control-value-48-padding-inline);
234
+ --psi-select-24-padding-inline-end: calc(var(--psi-control-value-24-padding-inline) + var(--psi-space-16));
235
+ --psi-select-32-padding-inline-end: calc(var(--psi-control-value-32-padding-inline) + var(--psi-space-16));
236
+ --psi-select-40-padding-inline-end: calc(var(--psi-control-value-40-padding-inline) + var(--psi-space-16));
237
+ --psi-select-48-padding-inline-end: calc(var(--psi-control-value-48-padding-inline) + var(--psi-space-16));
132
238
  }
133
239
  }
134
240
 
@@ -181,5 +287,6 @@
181
287
  :where(:root, [data-psi-theme]) {
182
288
  --psi-tooltip-bg: var(--psi-bg-inverted);
183
289
  --psi-tooltip-fg: var(--psi-fg-on-inverted);
290
+ --psi-tooltip-radius: min(var(--psi-control-radius), var(--psi-radius-6));
184
291
  }
185
292
  }
@@ -673,6 +673,15 @@
673
673
  "fontWeight": 500
674
674
  }
675
675
  },
676
+ "18-28-regular": {
677
+ "$type": "typography",
678
+ "$value": {
679
+ "fontFamily": "{fontFamily.sans}",
680
+ "fontSize": "18px",
681
+ "lineHeight": "28px",
682
+ "fontWeight": 400
683
+ }
684
+ },
676
685
  "18-28-medium": {
677
686
  "$type": "typography",
678
687
  "$value": {
@@ -673,6 +673,15 @@
673
673
  "fontWeight": 500
674
674
  }
675
675
  },
676
+ "18-28-regular": {
677
+ "$type": "typography",
678
+ "$value": {
679
+ "fontFamily": "{fontFamily.sans}",
680
+ "fontSize": "18px",
681
+ "lineHeight": "28px",
682
+ "fontWeight": 400
683
+ }
684
+ },
676
685
  "18-28-medium": {
677
686
  "$type": "typography",
678
687
  "$value": {
@@ -673,6 +673,15 @@
673
673
  "fontWeight": 500
674
674
  }
675
675
  },
676
+ "18-28-regular": {
677
+ "$type": "typography",
678
+ "$value": {
679
+ "fontFamily": "{fontFamily.sans}",
680
+ "fontSize": "18px",
681
+ "lineHeight": "28px",
682
+ "fontWeight": 400
683
+ }
684
+ },
676
685
  "18-28-medium": {
677
686
  "$type": "typography",
678
687
  "$value": {
@@ -673,6 +673,15 @@
673
673
  "fontWeight": 500
674
674
  }
675
675
  },
676
+ "18-28-regular": {
677
+ "$type": "typography",
678
+ "$value": {
679
+ "fontFamily": "{fontFamily.sans}",
680
+ "fontSize": "18px",
681
+ "lineHeight": "28px",
682
+ "fontWeight": 400
683
+ }
684
+ },
676
685
  "18-28-medium": {
677
686
  "$type": "typography",
678
687
  "$value": {
@@ -128,5 +128,63 @@
128
128
  "status": "success | warning | danger"
129
129
  },
130
130
  "tagApi": "On Tag, subtle is a boolean prop, not part of the variant union: accent-subtle is spelled variant=\"accent\" subtle (Tag variants: neutral | accent | success | warning | danger)."
131
+ },
132
+ "geometry": {
133
+ "sizes": [
134
+ 24,
135
+ 32,
136
+ 40,
137
+ 48
138
+ ],
139
+ "label": {
140
+ "paddingInline": [
141
+ 8,
142
+ 12,
143
+ 16,
144
+ 20
145
+ ],
146
+ "paddingInlineIcon": [
147
+ 6,
148
+ 8,
149
+ 12,
150
+ 16
151
+ ],
152
+ "gap": [
153
+ 4,
154
+ 8,
155
+ 8,
156
+ 8
157
+ ],
158
+ "font": [
159
+ "12-16-medium",
160
+ "14-20-medium",
161
+ "16-24-medium",
162
+ "18-28-medium"
163
+ ]
164
+ },
165
+ "value": {
166
+ "paddingInline": [
167
+ 8,
168
+ 8,
169
+ 12,
170
+ 16
171
+ ],
172
+ "font": [
173
+ "12-16-regular",
174
+ "14-20-regular",
175
+ "16-24-regular",
176
+ "18-28-regular"
177
+ ]
178
+ },
179
+ "components": {
180
+ "Button": "label",
181
+ "IconButton": "height-only",
182
+ "Input": "value",
183
+ "Select": "value"
184
+ },
185
+ "note": "Per-size geometry is data, not CSS literals (D54). Arrays are indexed by sizes[]. Read a value as --psi-control-{size}-{prop} for the label ramp and --psi-control-value-{size}-{prop} for the value ramp; components alias these as --psi-{component}-{size}-{prop}, which is the layer to override. The value ramp is one step tighter than the label ramp because a left-aligned value wants less air than a centred label (D55).",
186
+ "iconInset": "A leading icon sits one step closer to the edge than text — an icon is a solid shape with no side bearing (D55). Applied by .size{n}:has(> svg:first-child) on Button. IconButton is height-only: it is square with padding 0, so no padding/gap/font token applies to it.",
187
+ "iconInsetLimits": "The selector matches on element order, and :first-child ignores text nodes. Two consequences. (1) An icon wrapped in a <span> never matches — fails safe, no inset; set --psi-button-{size}-padding-inline-icon yourself. (2) A TRAILING icon (<Button>Next<IconChevronRight /></Button>) makes the svg the first ELEMENT child, so the rule fires and narrows the start (text) side while the icon keeps full padding — the inverse of the intent. CSS cannot tell the two apart without a DOM signal. Put the icon first, or override --psi-button-{size}-padding-inline-icon to match --psi-button-{size}-padding-inline to disable the inset.",
188
+ "radius": "Control radius is size-invariant (D56) — it does NOT ride the size ramp, because border-radius sits on each component's base rule and all four sizes resolve to radius-8. One dial, --psi-control-radius, is the layer to override, aliased per component: --psi-button-radius (Button, and IconButton via the same token), --psi-input-radius, --psi-select-radius, --psi-checkbox-box-radius, and --psi-tooltip-radius. Checkbox and Tooltip cap themselves with min(var(--psi-control-radius), var(--psi-radius-4)) and min(…, var(--psi-radius-6)) respectively so neither over-rounds a small object — but the published radius scale's floor is radius-4, so Checkbox's cap is a no-op for every on-scale value a theme can set; it only bites at an off-scale value like 0px. Tooltip's higher ceiling does track a sharper theme, down to radius-4. Tag and Switch stay --psi-radius-full: pill-ness is component identity, not theme expression. A theme retunes every control's shape by setting --psi-control-radius once. Psi now has two radius dials, not one: --psi-control-radius (here, for interactive controls) and --psi-surface-radius (for elevated surfaces — Dialog, Panel, Menu). --psi-card-radius sits on neither dial, so a theme that retunes controls or surfaces leaves Card at its own default of radius-8."
131
189
  }
132
190
  }
@@ -629,6 +629,13 @@
629
629
  "weight": "medium",
630
630
  "cssWeight": 500
631
631
  },
632
+ {
633
+ "name": "18-28-regular",
634
+ "fontSize": 18,
635
+ "lineHeight": 28,
636
+ "weight": "regular",
637
+ "cssWeight": 400
638
+ },
632
639
  {
633
640
  "name": "18-28-medium",
634
641
  "fontSize": 18,
@@ -629,6 +629,13 @@
629
629
  "weight": "medium",
630
630
  "cssWeight": 500
631
631
  },
632
+ {
633
+ "name": "18-28-regular",
634
+ "fontSize": 18,
635
+ "lineHeight": 28,
636
+ "weight": "regular",
637
+ "cssWeight": 400
638
+ },
632
639
  {
633
640
  "name": "18-28-medium",
634
641
  "fontSize": 18,
@@ -629,6 +629,13 @@
629
629
  "weight": "medium",
630
630
  "cssWeight": 500
631
631
  },
632
+ {
633
+ "name": "18-28-regular",
634
+ "fontSize": 18,
635
+ "lineHeight": 28,
636
+ "weight": "regular",
637
+ "cssWeight": 400
638
+ },
632
639
  {
633
640
  "name": "18-28-medium",
634
641
  "fontSize": 18,
@@ -629,6 +629,13 @@
629
629
  "weight": "medium",
630
630
  "cssWeight": 500
631
631
  },
632
+ {
633
+ "name": "18-28-regular",
634
+ "fontSize": 18,
635
+ "lineHeight": 28,
636
+ "weight": "regular",
637
+ "cssWeight": 400
638
+ },
632
639
  {
633
640
  "name": "18-28-medium",
634
641
  "fontSize": 18,
@@ -9,7 +9,8 @@
9
9
  ],
10
10
  "surface": [
11
11
  "background",
12
- "background-color"
12
+ "background-color",
13
+ "accent-color"
13
14
  ],
14
15
  "border": [
15
16
  "border",
@@ -350,6 +351,36 @@
350
351
  "input-border-error": [
351
352
  "border"
352
353
  ],
354
+ "menu-bg": [
355
+ "surface"
356
+ ],
357
+ "menu-border": [
358
+ "border"
359
+ ],
360
+ "menu-fg": [
361
+ "text"
362
+ ],
363
+ "menu-item-bg": [
364
+ "surface"
365
+ ],
366
+ "menu-item-bg-hover": [
367
+ "surface"
368
+ ],
369
+ "menu-item-bg-active": [
370
+ "surface"
371
+ ],
372
+ "menu-item-fg": [
373
+ "text"
374
+ ],
375
+ "menu-item-fg-danger": [
376
+ "text"
377
+ ],
378
+ "menu-item-fg-disabled": [
379
+ "text"
380
+ ],
381
+ "menu-separator-border": [
382
+ "border"
383
+ ],
353
384
  "navbar-bg": [
354
385
  "surface"
355
386
  ],
@@ -128,6 +128,7 @@
128
128
  .psi-text-16-20-regular { font: var(--psi-text-16-20-regular); }
129
129
  .psi-text-16-24-regular { font: var(--psi-text-16-24-regular); }
130
130
  .psi-text-16-24-medium { font: var(--psi-text-16-24-medium); }
131
+ .psi-text-18-28-regular { font: var(--psi-text-18-28-regular); }
131
132
  .psi-text-18-28-medium { font: var(--psi-text-18-28-medium); }
132
133
  .psi-text-20-28-semibold { font: var(--psi-text-20-28-semibold); }
133
134
  .psi-text-24-32-medium { font: var(--psi-text-24-32-medium); }
package/llms.txt CHANGED
@@ -14,7 +14,7 @@ OKLCH formula-based design tokens. Code is the source of truth; all artifacts ge
14
14
  - Override --psi-{component}-* tokens for one-off component theming; never fork semantic tokens.
15
15
  - Scales are pixel-true: --psi-space-8 is 8px (0.5rem). Typography: --psi-text-{size}-{lh}-{weight}.
16
16
  - Themes: import base.css + {theme}.css + components.css + utilities.css; set data-psi-theme="{name}" ({light,dark,acme,ember}).
17
- - Scoped tokens bind only their declared property groups (D46): fg* → text properties, bg*/fill*/scrim* → surfaces, border* → borders, --psi-space-* → gaps/padding/margin. Cross-family bindings that are design decisions carry both scopes (fgDanger: text+border for error borders; fillAccent: surface+border for selected controls). The token build enforces component bindings; stylelint (psi/token-scopes) enforces consumer CSS.
17
+ - Scoped tokens bind only their declared property groups (D46): fg* → text properties, bg*/fill*/scrim* → surfaces, border* → borders, --psi-space-* → gaps/padding/margin. Cross-family bindings that are design decisions carry both scopes (fgDanger: text+border for error borders; fillAccent: surface+border for selected controls). The token build enforces component bindings; the repo's stylelint rule (psi/token-scopes) enforces first-party consumer CSS (component modules + apps/). External consumers aren't gated automatically — dist/scope-map.json carries the machine-readable scopes to lint against.
18
18
 
19
19
  ## Motion (--psi-duration-*, --psi-ease-*)
20
20
  - Durations: 150/200/350/450/600ms. Easings: --psi-ease-standard, --psi-ease-in-out, --psi-ease-soft.
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@handamade/psi-tokens",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
+ "license": "MIT",
4
5
  "type": "module",
5
6
  "exports": {
6
7
  "./*.css": "./dist/*.css",