@fastwork/xosmoz-theme 0.41.0 → 0.45.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/llms.txt CHANGED
@@ -1,17 +1,21 @@
1
- # @fastwork/xosmoz-theme
1
+ # @fastwork/xosmoz-theme — Color Tokens & Usage Guide
2
2
 
3
- > Design tokens and theming system for the Xosmoz design system. Uses OKLCH color space for perceptually uniform colors. Supports light and dark themes via CSS variables with `data-theme` attribute switching.
3
+ > Design token system for Xosmoz. Uses OKLCH color space. Supports light and dark themes via CSS variables and `data-theme` attribute. This guide covers color tokens only (CSS variables).
4
4
 
5
- ## Installation
5
+ ---
6
+
7
+ ## Setup
8
+
9
+ ### Install
6
10
 
7
11
  ```bash
8
12
  npm install @fastwork/xosmoz-theme
9
13
  ```
10
14
 
11
- ## CSS Imports
15
+ ### CSS Imports
12
16
 
13
17
  ```css
14
- /* Base styles: CSS reset, font imports, typography/spacing/shadow tokens */
18
+ /* Base styles: CSS reset, font imports, typography/spacing tokens */
15
19
  @import '@fastwork/xosmoz-theme/base.css';
16
20
 
17
21
  /* All themes (light + dark) */
@@ -22,227 +26,239 @@ npm install @fastwork/xosmoz-theme
22
26
  @import '@fastwork/xosmoz-theme/themes/dark.css';
23
27
  ```
24
28
 
25
- ## Theme Switching
29
+ ### Theme Switching
26
30
 
27
- Set the theme via the `data-theme` attribute on the `<html>` element. Light theme is the default (no attribute needed).
31
+ Light theme is the default. Set `data-theme="dark"` on `<html>` for dark mode.
28
32
 
29
33
  ```html
30
- <html>...</html> <!-- Light theme (default) -->
31
- <html data-theme="dark">...</html> <!-- Dark theme -->
34
+ <html>...</html> <!-- Light theme (default) -->
35
+ <html data-theme="dark">...</html> <!-- Dark theme -->
32
36
  ```
33
37
 
34
38
  ```javascript
35
- // Switch theme at runtime
39
+ // Switch at runtime
36
40
  document.documentElement.setAttribute('data-theme', 'dark');
41
+ document.documentElement.removeAttribute('data-theme'); // back to light
42
+ ```
43
+
44
+ ---
37
45
 
38
- // Remove attribute to return to light
39
- document.documentElement.removeAttribute('data-theme');
46
+ ## Color Token Architecture
47
+
48
+ The system has two layers:
49
+
50
+ ### Layer 1 — Palette Tokens (primitives)
51
+ Eight raw color values. These are single CSS variables (no numbered scales). They are the same in both light and dark themes.
52
+
53
+ ```
54
+ --xz-color-fastwork (brand blue-purple)
55
+ --xz-color-gray
56
+ --xz-color-green
57
+ --xz-color-yellow
58
+ --xz-color-red
59
+ --xz-color-orange
60
+ --xz-color-purple
61
+ --xz-color-cyan
40
62
  ```
41
63
 
42
- ## CSS Variables Reference
64
+ **Rule: Do not use palette tokens directly in UI.** They exist as internal primitives. Always use semantic tokens instead.
43
65
 
44
- All variables use the `--xz-` prefix.
66
+ ### Layer 2 Semantic Tokens (theme-aware)
67
+ These tokens change values between light and dark themes. Always use these for UI components, text, borders, and backgrounds.
45
68
 
46
- ### Base Colors
69
+ Pattern: `--xz-color-{category}-{property}-{scale}`
47
70
 
48
- Surface colors that adapt between light and dark themes.
71
+ ---
49
72
 
50
- | Variable | Purpose |
51
- |----------|---------|
52
- | `--xz-color-surface-100` | Page background |
53
- | `--xz-color-surface-200` | Elevated surface (cards, modals) |
54
- | `--xz-color-surface-300` | Secondary surface |
55
- | `--xz-color-surface-400` | Tertiary surface / popovers |
56
- | `--xz-color-text-100` | Primary text color |
57
- | `--xz-color-text-200` | Secondary/muted text (70% opacity) |
58
- | `--xz-color-text-300` | Tertiary/disabled text (50% opacity) |
59
- | `--xz-color-bg-100` | Extreme base background (near-black in light, near-white in dark) |
60
- | `--xz-color-fg-100` | Text on bg-100 (white in light, black in dark) |
61
- | `--xz-color-soft-100` | Very subtle overlay (5% opacity of bg) |
62
- | `--xz-color-soft-200` | Subtle overlay (10% opacity of bg) |
63
- | `--xz-color-line-100` | Subtle borders |
64
- | `--xz-color-line-200` | Default borders |
65
- | `--xz-color-line-300` | Strong/emphasized borders |
73
+ ## Base Tokens
66
74
 
67
- ### Semantic Colors
75
+ Base tokens cover surfaces, text, borders, and neutral overlays. They are theme-aware (change in dark mode).
68
76
 
69
- Six semantic categories: `primary`, `danger`, `success`, `warning`, `info`, `neutral`.
77
+ | CSS Variable | Purpose |
78
+ |---|---|
79
+ | `--xz-color-surface-50` | Absolute white/darkest background (page canvas extreme) |
80
+ | `--xz-color-surface-100` | Default page background |
81
+ | `--xz-color-surface-200` | Elevated surface — cards, modals |
82
+ | `--xz-color-surface-300` | Secondary elevated surface |
83
+ | `--xz-color-surface-400` | Tertiary elevated surface — popovers, dropdowns |
84
+ | `--xz-color-bg-100` | Extreme base (near-black in light / near-white in dark) |
85
+ | `--xz-color-bg-200` | Secondary extreme base |
86
+ | `--xz-color-fg-100` | Text/icon on bg-100 and bg-200 |
87
+ | `--xz-color-text-100` | Primary text |
88
+ | `--xz-color-text-200` | Secondary / muted text (70% opacity) |
89
+ | `--xz-color-text-300` | Disabled / placeholder text (60% opacity) |
90
+ | `--xz-color-soft-100` | Very subtle neutral overlay (5% opacity) |
91
+ | `--xz-color-soft-200` | Subtle neutral overlay (10% opacity) |
92
+ | `--xz-color-line-100` | Subtle border |
93
+ | `--xz-color-line-200` | Default border |
94
+ | `--xz-color-line-300` | Emphasized border |
70
95
 
71
- Each category follows the same token structure. Replace `{name}` with the category name:
96
+ ---
72
97
 
73
- | Variable | Purpose |
74
- |----------|---------|
75
- | `--xz-color-{name}-soft-100` | Lightest tinted background |
76
- | `--xz-color-{name}-soft-200` | Stronger tinted background (hover states) |
98
+ ## Semantic Tokens
99
+
100
+ Eight categories, each with 11 tokens. Categories: `primary`, `danger`, `success`, `warning`, `info`, `neutral`, `orange`, `purple`.
101
+
102
+ ### Token Pattern per Category
103
+
104
+ Replace `{name}` with the category:
105
+
106
+ | CSS Variable | Purpose |
107
+ |---|---|
108
+ | `--xz-color-{name}-soft-100` | Tinted transparent background — lightest (10% opacity of base color) |
109
+ | `--xz-color-{name}-soft-200` | Tinted transparent background — stronger (16% opacity), use for hover |
110
+ | `--xz-color-{name}-soft-solid-100` | Opaque version of soft-100 (mixed into surface-100) — use on overlapping surfaces |
111
+ | `--xz-color-{name}-soft-solid-200` | Opaque version of soft-200 |
77
112
  | `--xz-color-{name}-line-100` | Subtle colored border |
78
113
  | `--xz-color-{name}-line-200` | Default colored border |
79
114
  | `--xz-color-{name}-line-300` | Strong colored border |
80
- | `--xz-color-{name}-bg-100` | Solid fill background (e.g. button bg) |
81
- | `--xz-color-{name}-bg-200` | Darker solid fill (e.g. hover state) |
82
- | `--xz-color-{name}-fg-100` | Text on solid bg — use over `{name}-bg-100`/`bg-200` (typically white) |
83
- | `--xz-color-{name}-text-100` | Colored text on surfaces (links, status labels) |
115
+ | `--xz-color-{name}-bg-100` | Solid fill background buttons, chips, badges |
116
+ | `--xz-color-{name}-bg-200` | Solid fill hover/pressed state |
117
+ | `--xz-color-{name}-fg-100` | Text/icon on solid bg — **always pair with bg-100 / bg-200** |
118
+ | `--xz-color-{name}-text-100` | Colored text on light surfaces links, status labels |
84
119
 
85
- **Important: `fg-100` is the foreground color for text on solid backgrounds (`bg-100`/`bg-200`).** Use `--xz-color-primary-fg-100` as the text color on a `--xz-color-primary-bg-100` button. This is typically white.
120
+ ### Key Rules for Semantic Tokens
86
121
 
87
- ### Raw Color Palettes
122
+ - **`bg-100` + `fg-100`**: Solid fill components (buttons, solid badges). `fg-100` provides correct contrast (white or dark depending on the category color).
123
+ - **`soft-100` + `text-100` + `line-100`**: Soft/tinted style (alerts, soft badges, highlighted rows).
124
+ - **`soft-solid-*`**: Use instead of `soft-*` when the component sits on a non-transparent surface (e.g., inside a card that has its own background).
125
+ - **`text-100`**: Use for colored text that sits on surface backgrounds (not on solid fills). Examples: link text, status label text, tag text.
126
+ - **`line-*`**: Colored borders. Use `line-200` as the default, `line-100` for subtle, `line-300` for strong/emphasized.
88
127
 
89
- 10-step scales (100–1000) for each palette. Available palettes: `fastwork`, `gray`, `green`, `mint`, `amber`, `red`, `orange`, `purple`, `cyan`, `black-alpha`, `white-alpha`.
128
+ ---
90
129
 
91
- ```
92
- --xz-color-{palette}-100 (lightest)
93
- --xz-color-{palette}-200
94
- ...
95
- --xz-color-{palette}-1000 (darkest)
96
- ```
130
+ ## Alpha & Overlay Tokens
97
131
 
98
- Alpha palettes (`black-alpha`, `white-alpha`) use opacity steps from 0.1 to 1.0.
132
+ These use a 100–1000 scale representing opacity from 0.1 to 1.0.
99
133
 
100
- ### Typography
101
-
102
- ```
103
- --xz-font-size-50 (0.5rem / 8px)
104
- --xz-font-size-100 (0.625rem / 10px)
105
- --xz-font-size-200 (0.75rem / 12px)
106
- --xz-font-size-300 (0.875rem / 14px)
107
- --xz-font-size-400 (1rem / 16px)
108
- --xz-font-size-500 (1.125rem / 18px)
109
- --xz-font-size-600 (1.25rem / 20px)
110
- --xz-font-size-700 (1.5rem / 24px)
111
- --xz-font-size-800 (1.625rem / 26px)
112
- --xz-font-size-900 (2rem / 32px)
113
- --xz-font-size-1000 (2.375rem / 38px)
114
- --xz-font-size-1100 (2.5rem / 40px)
115
- --xz-font-size-1200 (2.6875rem / 43px)
116
- --xz-font-size-1300 (3rem / 48px)
117
- --xz-font-size-1400 (3.5rem / 56px)
118
- --xz-font-size-1500 (4rem / 64px)
119
- --xz-font-size-1600 (4.5rem / 72px)
120
-
121
- --xz-font-family-primary (system-ui sans-serif stack)
122
- --xz-font-family-secondary ("Fastwork" + "Noto Sans Thai" + system fallbacks)
123
-
124
- --xz-line-height-100pct (1)
125
- --xz-line-height-125pct (1.25)
126
- --xz-line-height-135pct (1.35)
127
- --xz-line-height-150pct (1.5)
128
- --xz-line-height-165pct (1.65)
129
- --xz-line-height-200pct (2)
130
134
  ```
135
+ --xz-color-black-alpha-100 (black at 10% opacity)
136
+ --xz-color-black-alpha-200 (black at 20% opacity)
137
+ ...
138
+ --xz-color-black-alpha-1000 (black at 100% opacity)
131
139
 
132
- **Font shorthand tokens** (responsive desktop sizes, scales down on mobile ≤768px):
140
+ --xz-color-white-alpha-100 (white at 10% opacity)
141
+ ...
142
+ --xz-color-white-alpha-1000 (white at 100% opacity)
133
143
 
134
- ```
135
- --xz-font-heading1 through --xz-font-heading6 (secondary font, bold)
136
- --xz-font-title1 through --xz-font-title4 (primary font, bold)
137
- --xz-font-subtitle1-bold, --xz-font-subtitle1-regular
138
- --xz-font-subtitle2-bold, --xz-font-subtitle2-regular
139
- --xz-font-subtitle3-bold, --xz-font-subtitle3-regular
140
- --xz-font-body1 through --xz-font-body4 (primary font, regular)
144
+ --xz-color-overlay-100 (dark overlay at 10% opacity)
145
+ ...
146
+ --xz-color-overlay-1000 (dark overlay at 100% opacity)
141
147
  ```
142
148
 
143
- Usage: `font: var(--xz-font-heading1);`
149
+ Use `overlay-*` for modal/drawer backdrops. Use `black-alpha-*` / `white-alpha-*` for scrim layers or icon fills with transparency.
144
150
 
145
- ### Box Shadows
151
+ ---
146
152
 
147
- ```
148
- --xz-box-shadow-100 (subtle: 0 1px 2px)
149
- --xz-box-shadow-200 (small: 0 2px 6px)
150
- --xz-box-shadow-300 (medium: 0 4px 16px)
151
- --xz-box-shadow-400 (large: 0 8px 20px)
152
- ```
153
+ ## Usage Guidelines
154
+
155
+ ### Backgrounds & Surfaces
153
156
 
154
- ## JavaScript/TypeScript API
157
+ | Situation | Use |
158
+ |---|---|
159
+ | Page background | `--xz-color-surface-100` |
160
+ | Card, modal, dialog | `--xz-color-surface-200` |
161
+ | Nested card or secondary panel | `--xz-color-surface-300` |
162
+ | Popover, dropdown, tooltip | `--xz-color-surface-400` |
163
+ | Inverted/dark block on page | `--xz-color-bg-100` |
164
+ | Text on inverted block | `--xz-color-fg-100` |
155
165
 
156
- ### Theme objects
166
+ ### Text
157
167
 
158
- ```typescript
159
- import { lightTheme, darkTheme, themes, getTheme, getThemeNames } from '@fastwork/xosmoz-theme';
168
+ | Situation | Use |
169
+ |---|---|
170
+ | Body text, headings | `--xz-color-text-100` |
171
+ | Secondary / helper text | `--xz-color-text-200` |
172
+ | Placeholder / disabled text | `--xz-color-text-300` |
173
+ | Colored status text (link, tag, label) | `--xz-color-{name}-text-100` |
160
174
 
161
- // Access raw palette colors
162
- lightTheme.colors.fastwork[600] // 'oklch(0.613 0.233 260.608)'
163
- lightTheme.colors.gray[300] // raw palette value
175
+ ### Borders
164
176
 
165
- // Access semantic colors
166
- lightTheme.colors.primary.bg[100] // solid fill color
167
- lightTheme.colors.primary.fg[100] // white text for solid bg
168
- lightTheme.colors.primary.text[100] // colored text on surfaces
169
- lightTheme.colors.primary.soft[100] // tinted background
170
- lightTheme.colors.primary.line[200] // border color
177
+ | Situation | Use |
178
+ |---|---|
179
+ | Subtle separator, divider | `--xz-color-line-100` |
180
+ | Default input or card border | `--xz-color-line-200` |
181
+ | Strong border, active outline | `--xz-color-line-300` |
182
+ | Colored border (semantic) | `--xz-color-{name}-line-100/200/300` |
171
183
 
172
- // Access base tokens
173
- lightTheme.colors.surface[200] // card background
174
- lightTheme.colors.text[100] // primary text
184
+ ### Solid Components (Buttons, Solid Badges)
175
185
 
176
- // Access box shadows (on theme objects)
177
- lightTheme.boxShadows[100] // '0 1px 2px 0 rgba(0, 0, 0, 0.08)'
178
- lightTheme.boxShadows[200] // '0 2px 6px 0 rgba(0, 0, 0, 0.10)'
179
- lightTheme.boxShadows[300] // '0 4px 16px 0 rgba(0, 0, 0, 0.12)'
180
- lightTheme.boxShadows[400] // '0 8px 20px 0 rgba(0, 0, 0, 0.14)'
186
+ ```
187
+ background: --xz-color-{name}-bg-100
188
+ color: --xz-color-{name}-fg-100 ← always use fg-100 on bg-100
189
+ hover bg: --xz-color-{name}-bg-200
190
+ ```
181
191
 
182
- // Get theme by name
183
- const theme = getTheme('dark');
192
+ ### Soft/Tinted Components (Alerts, Soft Badges)
184
193
 
185
- // List available themes
186
- const names = getThemeNames(); // ['light', 'dark']
194
+ ```
195
+ background: --xz-color-{name}-soft-100
196
+ color: --xz-color-{name}-text-100
197
+ border: 1px solid --xz-color-{name}-line-100
187
198
  ```
188
199
 
189
- ### Design tokens
200
+ ### Outline/Ghost Components
190
201
 
191
- ```typescript
192
- import { fontSize, fontWeight, fontFamily, lineHeight, font, typography } from '@fastwork/xosmoz-theme/tokens';
202
+ ```
203
+ background: transparent
204
+ color: --xz-color-{name}-text-100
205
+ border: 1px solid --xz-color-{name}-line-200
206
+ ```
193
207
 
194
- fontSize[400] // '1rem'
195
- fontSize[700] // '1.5rem'
196
- fontWeight[700] // 700
197
- fontFamily.primary // system sans-serif stack
198
- fontFamily.secondary // "Fastwork" + fallbacks
199
- lineHeight['150pct'] // '1.5'
208
+ ### Focus Ring
200
209
 
201
- font.heading1 // { fontFamily, fontSize: { desktop, mobile }, fontWeight, lineHeight }
202
- font.title2
203
- font.subtitle1Bold
204
- font.body1
205
210
  ```
211
+ border-color: --xz-color-{name}-line-200
212
+ box-shadow: 0 0 0 3px --xz-color-{name}-soft-100
213
+ ```
214
+
215
+ ### Modal Backdrop
206
216
 
207
- ### Types
208
-
209
- ```typescript
210
- import type {
211
- ThemeConfig,
212
- ThemeName,
213
- ThemeRegistry,
214
- ColorToken,
215
- TypographyToken,
216
- TypographyScale,
217
- FontWeights,
218
- } from '@fastwork/xosmoz-theme';
219
217
  ```
218
+ background: --xz-color-overlay-600
219
+ ```
220
+
221
+ ---
220
222
 
221
- ## Common Patterns
223
+ ## Common UI Patterns
222
224
 
223
- ### Primary button
225
+ ### Primary Button
224
226
 
225
227
  ```css
226
- .button-primary {
228
+ .btn-primary {
227
229
  background: var(--xz-color-primary-bg-100);
228
- color: var(--xz-color-primary-fg-100); /* white text on solid bg */
229
- font: var(--xz-font-subtitle1-bold);
230
+ color: var(--xz-color-primary-fg-100);
230
231
  border: none;
231
- border-radius: 0.5rem;
232
232
  }
233
- .button-primary:hover {
233
+ .btn-primary:hover {
234
234
  background: var(--xz-color-primary-bg-200);
235
235
  }
236
236
  ```
237
237
 
238
- ### Secondary/outline button
238
+ ### Outline Button
239
239
 
240
240
  ```css
241
- .button-secondary {
241
+ .btn-outline {
242
242
  background: transparent;
243
243
  color: var(--xz-color-primary-text-100);
244
244
  border: 1px solid var(--xz-color-primary-line-200);
245
245
  }
246
+ .btn-outline:hover {
247
+ background: var(--xz-color-primary-soft-100);
248
+ }
249
+ ```
250
+
251
+ ### Danger Button
252
+
253
+ ```css
254
+ .btn-danger {
255
+ background: var(--xz-color-danger-bg-100);
256
+ color: var(--xz-color-danger-fg-100);
257
+ border: none;
258
+ }
259
+ .btn-danger:hover {
260
+ background: var(--xz-color-danger-bg-200);
261
+ }
246
262
  ```
247
263
 
248
264
  ### Card
@@ -252,44 +268,231 @@ import type {
252
268
  background: var(--xz-color-surface-200);
253
269
  color: var(--xz-color-text-100);
254
270
  border: 1px solid var(--xz-color-line-100);
255
- border-radius: 0.75rem;
256
- box-shadow: var(--xz-box-shadow-200);
257
271
  }
258
272
  ```
259
273
 
260
- ### Alert / status badge
274
+ ### Alert (soft style)
261
275
 
262
276
  ```css
277
+ /* Replace {name} with: success | danger | warning | info */
263
278
  .alert-success {
264
279
  background: var(--xz-color-success-soft-100);
265
280
  color: var(--xz-color-success-text-100);
266
281
  border: 1px solid var(--xz-color-success-line-100);
267
282
  }
283
+ .alert-danger {
284
+ background: var(--xz-color-danger-soft-100);
285
+ color: var(--xz-color-danger-text-100);
286
+ border: 1px solid var(--xz-color-danger-line-100);
287
+ }
288
+ .alert-warning {
289
+ background: var(--xz-color-warning-soft-100);
290
+ color: var(--xz-color-warning-text-100);
291
+ border: 1px solid var(--xz-color-warning-line-100);
292
+ }
293
+ .alert-info {
294
+ background: var(--xz-color-info-soft-100);
295
+ color: var(--xz-color-info-text-100);
296
+ border: 1px solid var(--xz-color-info-line-100);
297
+ }
298
+ ```
299
+
300
+ ### Badge — Soft
301
+
302
+ ```css
303
+ .badge-success {
304
+ background: var(--xz-color-success-soft-100);
305
+ color: var(--xz-color-success-text-100);
306
+ }
307
+ ```
268
308
 
269
- .badge-danger {
309
+ ### Badge — Solid
310
+
311
+ ```css
312
+ .badge-danger-solid {
270
313
  background: var(--xz-color-danger-bg-100);
271
- color: var(--xz-color-danger-fg-100); /* white text on solid bg */
314
+ color: var(--xz-color-danger-fg-100);
272
315
  }
273
316
  ```
274
317
 
275
- ### Form input
318
+ ### Form Input
276
319
 
277
320
  ```css
278
321
  .input {
279
322
  background: var(--xz-color-surface-100);
280
323
  color: var(--xz-color-text-100);
281
324
  border: 1px solid var(--xz-color-line-200);
282
- font: var(--xz-font-body1);
325
+ }
326
+ .input::placeholder {
327
+ color: var(--xz-color-text-300);
283
328
  }
284
329
  .input:focus {
285
330
  border-color: var(--xz-color-primary-line-200);
286
331
  box-shadow: 0 0 0 3px var(--xz-color-primary-soft-100);
332
+ outline: none;
333
+ }
334
+ .input.error {
335
+ border-color: var(--xz-color-danger-line-200);
336
+ box-shadow: 0 0 0 3px var(--xz-color-danger-soft-100);
287
337
  }
288
338
  ```
289
339
 
290
- ### Muted/secondary text
340
+ ### Text Hierarchy
291
341
 
292
342
  ```css
293
- .text-muted { color: var(--xz-color-text-200); }
294
- .text-disabled { color: var(--xz-color-text-300); }
343
+ .text-primary { color: var(--xz-color-text-100); }
344
+ .text-muted { color: var(--xz-color-text-200); }
345
+ .text-disabled { color: var(--xz-color-text-300); }
346
+ .text-link { color: var(--xz-color-primary-text-100); }
347
+ .text-danger { color: var(--xz-color-danger-text-100); }
348
+ .text-success { color: var(--xz-color-success-text-100); }
295
349
  ```
350
+
351
+ ---
352
+
353
+ ## Figma Variables Guide
354
+
355
+ Figma variables mirror the CSS token system exactly. Every CSS variable has a corresponding Figma variable in the same collection.
356
+
357
+ ### Collection Structure
358
+
359
+ - **Collection name**: `colors`
360
+ - **Modes**: `Light` and `Dark`
361
+ - **Total variables**: ~160 color variables
362
+
363
+ ### Naming Pattern
364
+
365
+ Figma uses slash-separated paths. The mapping to CSS is direct:
366
+
367
+ | Variable type | Figma path | CSS variable |
368
+ |---|---|---|
369
+ | Base theme token | `theme/base/{property}/{scale}` | `--xz-color-{property}-{scale}` |
370
+ | Semantic theme token | `theme/{category}/{property}/{scale}` | `--xz-color-{category}-{property}-{scale}` |
371
+ | Alpha token | `theme/blackAlpha/{scale}` | `--xz-color-black-alpha-{scale}` |
372
+ | Alpha token | `theme/whiteAlpha/{scale}` | `--xz-color-white-alpha-{scale}` |
373
+ | Overlay token | `theme/overlay/{scale}` | `--xz-color-overlay-{scale}` |
374
+ | Palette primitive | `palette/{name}` | `--xz-color-{name}` |
375
+
376
+ ### Complete Figma → CSS Mapping
377
+
378
+ #### Base (16 variables)
379
+
380
+ | Figma Variable | CSS Variable |
381
+ |---|---|
382
+ | `theme/base/bg/100` | `--xz-color-bg-100` |
383
+ | `theme/base/bg/200` | `--xz-color-bg-200` |
384
+ | `theme/base/surface/50` | `--xz-color-surface-50` |
385
+ | `theme/base/surface/100` | `--xz-color-surface-100` |
386
+ | `theme/base/surface/200` | `--xz-color-surface-200` |
387
+ | `theme/base/surface/300` | `--xz-color-surface-300` |
388
+ | `theme/base/surface/400` | `--xz-color-surface-400` |
389
+ | `theme/base/fg/100` | `--xz-color-fg-100` |
390
+ | `theme/base/soft/100` | `--xz-color-soft-100` |
391
+ | `theme/base/soft/200` | `--xz-color-soft-200` |
392
+ | `theme/base/text/100` | `--xz-color-text-100` |
393
+ | `theme/base/text/200` | `--xz-color-text-200` |
394
+ | `theme/base/text/300` | `--xz-color-text-300` |
395
+ | `theme/base/line/100` | `--xz-color-line-100` |
396
+ | `theme/base/line/200` | `--xz-color-line-200` |
397
+ | `theme/base/line/300` | `--xz-color-line-300` |
398
+
399
+ #### Semantic Categories (11 variables each)
400
+
401
+ Same pattern for all 8 categories: `primary`, `danger`, `success`, `warning`, `info`, `neutral`, `orange`, `purple`.
402
+
403
+ | Figma Variable | CSS Variable |
404
+ |---|---|
405
+ | `theme/{name}/soft/100` | `--xz-color-{name}-soft-100` |
406
+ | `theme/{name}/soft/200` | `--xz-color-{name}-soft-200` |
407
+ | `theme/{name}/softSolid/100` | `--xz-color-{name}-soft-solid-100` |
408
+ | `theme/{name}/softSolid/200` | `--xz-color-{name}-soft-solid-200` |
409
+ | `theme/{name}/line/100` | `--xz-color-{name}-line-100` |
410
+ | `theme/{name}/line/200` | `--xz-color-{name}-line-200` |
411
+ | `theme/{name}/line/300` | `--xz-color-{name}-line-300` |
412
+ | `theme/{name}/bg/100` | `--xz-color-{name}-bg-100` |
413
+ | `theme/{name}/bg/200` | `--xz-color-{name}-bg-200` |
414
+ | `theme/{name}/fg/100` | `--xz-color-{name}-fg-100` |
415
+ | `theme/{name}/text/100` | `--xz-color-{name}-text-100` |
416
+
417
+ #### Black Alpha (10 variables)
418
+
419
+ | Figma Variable | CSS Variable |
420
+ |---|---|
421
+ | `theme/blackAlpha/100` | `--xz-color-black-alpha-100` |
422
+ | `theme/blackAlpha/200` | `--xz-color-black-alpha-200` |
423
+ | `theme/blackAlpha/300` | `--xz-color-black-alpha-300` |
424
+ | `theme/blackAlpha/400` | `--xz-color-black-alpha-400` |
425
+ | `theme/blackAlpha/500` | `--xz-color-black-alpha-500` |
426
+ | `theme/blackAlpha/600` | `--xz-color-black-alpha-600` |
427
+ | `theme/blackAlpha/700` | `--xz-color-black-alpha-700` |
428
+ | `theme/blackAlpha/800` | `--xz-color-black-alpha-800` |
429
+ | `theme/blackAlpha/900` | `--xz-color-black-alpha-900` |
430
+ | `theme/blackAlpha/1000` | `--xz-color-black-alpha-1000` |
431
+
432
+ #### White Alpha (10 variables)
433
+
434
+ | Figma Variable | CSS Variable |
435
+ |---|---|
436
+ | `theme/whiteAlpha/100` | `--xz-color-white-alpha-100` |
437
+ | `theme/whiteAlpha/200` | `--xz-color-white-alpha-200` |
438
+ | `theme/whiteAlpha/300` | `--xz-color-white-alpha-300` |
439
+ | `theme/whiteAlpha/400` | `--xz-color-white-alpha-400` |
440
+ | `theme/whiteAlpha/500` | `--xz-color-white-alpha-500` |
441
+ | `theme/whiteAlpha/600` | `--xz-color-white-alpha-600` |
442
+ | `theme/whiteAlpha/700` | `--xz-color-white-alpha-700` |
443
+ | `theme/whiteAlpha/800` | `--xz-color-white-alpha-800` |
444
+ | `theme/whiteAlpha/900` | `--xz-color-white-alpha-900` |
445
+ | `theme/whiteAlpha/1000` | `--xz-color-white-alpha-1000` |
446
+
447
+ #### Overlay (10 variables)
448
+
449
+ | Figma Variable | CSS Variable |
450
+ |---|---|
451
+ | `theme/overlay/100` | `--xz-color-overlay-100` |
452
+ | `theme/overlay/200` | `--xz-color-overlay-200` |
453
+ | `theme/overlay/300` | `--xz-color-overlay-300` |
454
+ | `theme/overlay/400` | `--xz-color-overlay-400` |
455
+ | `theme/overlay/500` | `--xz-color-overlay-500` |
456
+ | `theme/overlay/600` | `--xz-color-overlay-600` |
457
+ | `theme/overlay/700` | `--xz-color-overlay-700` |
458
+ | `theme/overlay/800` | `--xz-color-overlay-800` |
459
+ | `theme/overlay/900` | `--xz-color-overlay-900` |
460
+ | `theme/overlay/1000` | `--xz-color-overlay-1000` |
461
+
462
+ #### Palette (8 variables)
463
+
464
+ | Figma Variable | CSS Variable |
465
+ |---|---|
466
+ | `palette/fastwork` | `--xz-color-fastwork` |
467
+ | `palette/gray` | `--xz-color-gray` |
468
+ | `palette/green` | `--xz-color-green` |
469
+ | `palette/yellow` | `--xz-color-yellow` |
470
+ | `palette/red` | `--xz-color-red` |
471
+ | `palette/orange` | `--xz-color-orange` |
472
+ | `palette/purple` | `--xz-color-purple` |
473
+ | `palette/cyan` | `--xz-color-cyan` |
474
+
475
+ ### How to Use Figma Variables in Designs
476
+
477
+ 1. Select a layer in Figma (frame, text, shape, etc.)
478
+ 2. In the Fill or Stroke panel, click the color swatch
479
+ 3. Switch to the **Variables** tab in the color picker
480
+ 4. Pick from the `colors` collection
481
+
482
+ **Rules for Figma:**
483
+ - Always use `theme/*` variables for component fills, text colors, and stroke colors
484
+ - Use `palette/*` variables only as references — not directly on components
485
+ - Use `theme/base/surface/100` for page backgrounds, `theme/base/surface/200` for cards
486
+ - Use `theme/{name}/bg/100` for solid-filled elements and `theme/{name}/fg/100` for text on top of them
487
+ - Switch between Light/Dark previews using the **Mode** toggle on the variable collection
488
+
489
+ ### Keeping Figma in Sync with Code
490
+
491
+ Variables are synced from the npm package via the **XOSMOZ Theme Sync** plugin:
492
+
493
+ 1. Open **Plugins → Development → XOSMOZ Theme Sync** in Figma
494
+ 2. Select your variable collection from the dropdown
495
+ 3. Click **"Check for Updates"** to see if any colors changed
496
+ 4. Click **"Update Variables"** to apply changes to both Light and Dark modes at once
497
+
498
+ If starting a new Figma file, use **"Create New Collection"** to generate all variables from scratch.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastwork/xosmoz-theme",
3
- "version": "0.41.0",
3
+ "version": "0.45.0",
4
4
  "description": "Xosmoz Theme - Design tokens and theming system for Xosmoz",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",