@fastwork/xosmoz-theme 0.15.0 → 0.16.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/README.md +318 -168
- package/dist/index.js +29 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -29
- package/dist/index.mjs.map +1 -1
- package/dist/themes/dark.css +15 -15
- package/dist/themes/light.css +14 -14
- package/dist/themes.css +29 -29
- package/llms.txt +59 -35
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @fastwork/xosmoz-theme
|
|
2
2
|
|
|
3
|
-
Design tokens and theming system for the Xosmoz design system.
|
|
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 custom properties with `data-theme` attribute switching.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,32 +8,23 @@ Design tokens and theming system for the Xosmoz design system.
|
|
|
8
8
|
npm install @fastwork/xosmoz-theme
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
### Multi-Theme System (DaisyUI-style) 🎨
|
|
14
|
-
|
|
15
|
-
Xosmoz includes a powerful multi-theme system inspired by DaisyUI. Choose from predefined themes or create your own!
|
|
16
|
-
|
|
17
|
-
#### Available Themes
|
|
18
|
-
|
|
19
|
-
- **light** - Clean, modern light theme (default)
|
|
20
|
-
- **dark** - Elegant dark theme
|
|
21
|
-
|
|
22
|
-
#### Quick Start
|
|
11
|
+
## Quick Start
|
|
23
12
|
|
|
24
13
|
```css
|
|
25
|
-
/*
|
|
14
|
+
/* Base styles: CSS reset, font imports, typography/spacing/shadow tokens */
|
|
26
15
|
@import '@fastwork/xosmoz-theme/base.css';
|
|
27
16
|
|
|
28
|
-
/*
|
|
17
|
+
/* All themes (light + dark) */
|
|
29
18
|
@import '@fastwork/xosmoz-theme/themes.css';
|
|
30
19
|
|
|
31
|
-
/* OR import specific theme only */
|
|
20
|
+
/* OR import a specific theme only */
|
|
32
21
|
@import '@fastwork/xosmoz-theme/themes/light.css';
|
|
33
22
|
/* @import '@fastwork/xosmoz-theme/themes/dark.css'; */
|
|
34
23
|
```
|
|
35
24
|
|
|
36
|
-
|
|
25
|
+
## Theme Switching
|
|
26
|
+
|
|
27
|
+
Set the theme via the `data-theme` attribute on the `<html>` element. Light theme is the default (no attribute needed).
|
|
37
28
|
|
|
38
29
|
```html
|
|
39
30
|
<!-- Light theme (default) -->
|
|
@@ -43,219 +34,378 @@ Then set the theme via HTML attribute:
|
|
|
43
34
|
<html data-theme="dark">...</html>
|
|
44
35
|
```
|
|
45
36
|
|
|
46
|
-
|
|
37
|
+
```javascript
|
|
38
|
+
// Switch theme at runtime
|
|
39
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
// Remove attribute to return to light (default)
|
|
42
|
+
document.documentElement.removeAttribute('data-theme');
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
padding: var(--xz-spacing-4);
|
|
55
|
-
border-radius: var(--xz-radius-md);
|
|
44
|
+
// Persist across sessions
|
|
45
|
+
function setTheme(name) {
|
|
46
|
+
document.documentElement.setAttribute('data-theme', name);
|
|
47
|
+
localStorage.setItem('theme', name);
|
|
56
48
|
}
|
|
57
49
|
|
|
58
|
-
.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
const savedTheme = localStorage.getItem('theme') || 'light';
|
|
51
|
+
document.documentElement.setAttribute('data-theme', savedTheme);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## CSS Variables Reference
|
|
55
|
+
|
|
56
|
+
All variables use the `--xz-` prefix.
|
|
57
|
+
|
|
58
|
+
### Base Colors
|
|
59
|
+
|
|
60
|
+
Surface and layout colors that adapt between light and dark themes.
|
|
61
|
+
|
|
62
|
+
| Variable | Purpose |
|
|
63
|
+
|----------|---------|
|
|
64
|
+
| `--xz-color-surface-100` | Primary page background |
|
|
65
|
+
| `--xz-color-surface-200` | Elevated surface (cards, modals) |
|
|
66
|
+
| `--xz-color-surface-300` | Table headers, sidebars |
|
|
67
|
+
| `--xz-color-surface-400` | Popovers, tooltips |
|
|
68
|
+
| `--xz-color-text-100` | Primary text |
|
|
69
|
+
| `--xz-color-text-200` | Secondary/muted text (70% opacity) |
|
|
70
|
+
| `--xz-color-text-300` | Tertiary/disabled text (50% opacity) |
|
|
71
|
+
| `--xz-color-bg-100` | Extreme base background (near-black in light, near-white in dark) |
|
|
72
|
+
| `--xz-color-fg-100` | Text on `bg-100` (white in light, black in dark) |
|
|
73
|
+
| `--xz-color-soft-100` | Very subtle overlay (5% opacity of bg) |
|
|
74
|
+
| `--xz-color-soft-200` | Subtle overlay (10% opacity of bg) |
|
|
75
|
+
| `--xz-color-line-100` | Subtle borders |
|
|
76
|
+
| `--xz-color-line-200` | Default borders |
|
|
77
|
+
| `--xz-color-line-300` | Strong/emphasized borders |
|
|
78
|
+
|
|
79
|
+
### Semantic Colors
|
|
80
|
+
|
|
81
|
+
Six semantic categories: `primary`, `danger`, `success`, `warning`, `info`, `neutral`.
|
|
82
|
+
|
|
83
|
+
Each category follows the same token structure — replace `{name}` with the category:
|
|
84
|
+
|
|
85
|
+
| Variable | Purpose |
|
|
86
|
+
|----------|---------|
|
|
87
|
+
| `--xz-color-{name}-soft-100` | Lightest tinted background (badges, highlights) |
|
|
88
|
+
| `--xz-color-{name}-soft-200` | Stronger tinted background (hover states) |
|
|
89
|
+
| `--xz-color-{name}-line-100` | Subtle colored border |
|
|
90
|
+
| `--xz-color-{name}-line-200` | Default colored border (input focus) |
|
|
91
|
+
| `--xz-color-{name}-line-300` | Strong colored border (active states) |
|
|
92
|
+
| `--xz-color-{name}-bg-100` | Solid fill (buttons, tags) |
|
|
93
|
+
| `--xz-color-{name}-bg-200` | Darker solid fill (hover state) |
|
|
94
|
+
| `--xz-color-{name}-fg-100` | Text on solid backgrounds — pair with `bg-100`/`bg-200` (typically white) |
|
|
95
|
+
| `--xz-color-{name}-text-100` | Colored text on surfaces (links, labels) |
|
|
96
|
+
|
|
97
|
+
**Usage example:**
|
|
98
|
+
|
|
99
|
+
```css
|
|
100
|
+
/* Primary button */
|
|
101
|
+
.btn-primary {
|
|
102
|
+
background: var(--xz-color-primary-bg-100);
|
|
103
|
+
color: var(--xz-color-primary-fg-100); /* white text on solid bg */
|
|
104
|
+
}
|
|
105
|
+
.btn-primary:hover {
|
|
106
|
+
background: var(--xz-color-primary-bg-200);
|
|
63
107
|
}
|
|
64
108
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
109
|
+
/* Soft badge */
|
|
110
|
+
.badge-success {
|
|
111
|
+
background: var(--xz-color-success-soft-100);
|
|
112
|
+
color: var(--xz-color-success-text-100);
|
|
113
|
+
border: 1px solid var(--xz-color-success-line-100);
|
|
68
114
|
}
|
|
69
115
|
```
|
|
70
116
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```javascript
|
|
74
|
-
function setTheme(themeName) {
|
|
75
|
-
document.documentElement.setAttribute('data-theme', themeName);
|
|
76
|
-
localStorage.setItem('theme', themeName);
|
|
77
|
-
}
|
|
117
|
+
### Raw Color Palettes
|
|
78
118
|
|
|
79
|
-
|
|
80
|
-
setTheme('dark'); // Switch to dark theme
|
|
81
|
-
setTheme('light'); // Switch to light theme
|
|
119
|
+
10-step scales (100–1000) for each palette. Available palettes: `fastwork`, `gray`, `green`, `mint`, `amber`, `red`, `orange`, `purple`, `cyan`, `black-alpha`, `white-alpha`.
|
|
82
120
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
121
|
+
```css
|
|
122
|
+
--xz-color-{palette}-100 /* lightest */
|
|
123
|
+
--xz-color-{palette}-200
|
|
124
|
+
/* ... */
|
|
125
|
+
--xz-color-{palette}-1000 /* darkest */
|
|
86
126
|
```
|
|
87
127
|
|
|
88
|
-
|
|
128
|
+
Alpha palettes (`black-alpha`, `white-alpha`) use opacity steps from 0.1 to 1.0.
|
|
129
|
+
|
|
130
|
+
### Typography
|
|
131
|
+
|
|
132
|
+
**Font sizes** (50–1600 numeric scale):
|
|
133
|
+
|
|
134
|
+
| Variable | Value |
|
|
135
|
+
|----------|-------|
|
|
136
|
+
| `--xz-font-size-50` | 0.5rem / 8px |
|
|
137
|
+
| `--xz-font-size-100` | 0.625rem / 10px |
|
|
138
|
+
| `--xz-font-size-200` | 0.75rem / 12px |
|
|
139
|
+
| `--xz-font-size-300` | 0.875rem / 14px |
|
|
140
|
+
| `--xz-font-size-400` | 1rem / 16px |
|
|
141
|
+
| `--xz-font-size-500` | 1.125rem / 18px |
|
|
142
|
+
| `--xz-font-size-600` | 1.25rem / 20px |
|
|
143
|
+
| `--xz-font-size-700` | 1.5rem / 24px |
|
|
144
|
+
| `--xz-font-size-800` | 1.625rem / 26px |
|
|
145
|
+
| `--xz-font-size-900` | 2rem / 32px |
|
|
146
|
+
| `--xz-font-size-1000` | 2.375rem / 38px |
|
|
147
|
+
| `--xz-font-size-1100` | 2.5rem / 40px |
|
|
148
|
+
| `--xz-font-size-1200` | 2.6875rem / 43px |
|
|
149
|
+
| `--xz-font-size-1300` | 3rem / 48px |
|
|
150
|
+
| `--xz-font-size-1400` | 3.5rem / 56px |
|
|
151
|
+
| `--xz-font-size-1500` | 4rem / 64px |
|
|
152
|
+
| `--xz-font-size-1600` | 4.5rem / 72px |
|
|
153
|
+
|
|
154
|
+
**Font families:**
|
|
89
155
|
|
|
90
|
-
|
|
156
|
+
```css
|
|
157
|
+
--xz-font-family-primary /* system-ui sans-serif stack */
|
|
158
|
+
--xz-font-family-secondary /* "Fastwork" + "Noto Sans Thai" + system fallbacks */
|
|
159
|
+
```
|
|
91
160
|
|
|
92
|
-
**
|
|
161
|
+
**Line heights:**
|
|
93
162
|
|
|
94
163
|
```css
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
--xz-color-primary-text: oklch(1 0 0);
|
|
102
|
-
/* ... other theme variables */
|
|
103
|
-
}
|
|
164
|
+
--xz-line-height-100pct /* 1 */
|
|
165
|
+
--xz-line-height-125pct /* 1.25 */
|
|
166
|
+
--xz-line-height-135pct /* 1.35 */
|
|
167
|
+
--xz-line-height-150pct /* 1.5 */
|
|
168
|
+
--xz-line-height-165pct /* 1.65 */
|
|
169
|
+
--xz-line-height-200pct /* 2 */
|
|
104
170
|
```
|
|
105
171
|
|
|
106
|
-
**
|
|
172
|
+
**Font shorthand tokens** — responsive, with desktop sizes scaling down on mobile (≤768px):
|
|
107
173
|
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
174
|
+
```css
|
|
175
|
+
/* Headings — secondary font, bold */
|
|
176
|
+
--xz-font-heading1 /* 72px desktop / 48px mobile */
|
|
177
|
+
--xz-font-heading2 /* 64px desktop / 43px mobile */
|
|
178
|
+
--xz-font-heading3 /* 56px desktop / 38px mobile */
|
|
179
|
+
--xz-font-heading4 /* 48px desktop / 32px mobile */
|
|
180
|
+
--xz-font-heading5 /* 40px desktop / 26px mobile */
|
|
181
|
+
--xz-font-heading6 /* 32px desktop / 24px mobile */
|
|
182
|
+
|
|
183
|
+
/* Titles — primary font, bold */
|
|
184
|
+
--xz-font-title1 /* 24px desktop / 20px mobile */
|
|
185
|
+
--xz-font-title2 /* 20px desktop / 18px mobile */
|
|
186
|
+
--xz-font-title3 /* 18px desktop / 16px mobile */
|
|
187
|
+
--xz-font-title4 /* 16px desktop / 14px mobile */
|
|
188
|
+
|
|
189
|
+
/* Subtitles — primary font, bold or regular */
|
|
190
|
+
--xz-font-subtitle1-bold
|
|
191
|
+
--xz-font-subtitle1-regular /* 16px desktop / 14px mobile */
|
|
192
|
+
--xz-font-subtitle2-bold
|
|
193
|
+
--xz-font-subtitle2-regular /* 14px desktop / 12px mobile */
|
|
194
|
+
--xz-font-subtitle3-bold
|
|
195
|
+
--xz-font-subtitle3-regular /* 12px desktop / 10px mobile */
|
|
196
|
+
|
|
197
|
+
/* Body — primary font, regular */
|
|
198
|
+
--xz-font-body1 /* 16px desktop / 14px mobile */
|
|
199
|
+
--xz-font-body2 /* 14px desktop / 12px mobile */
|
|
200
|
+
--xz-font-body3 /* 12px desktop / 10px mobile */
|
|
201
|
+
--xz-font-body4 /* 10px desktop / 8px mobile */
|
|
127
202
|
```
|
|
128
203
|
|
|
129
|
-
|
|
204
|
+
Usage: `font: var(--xz-font-heading1);`
|
|
130
205
|
|
|
131
|
-
|
|
206
|
+
### Box Shadows
|
|
132
207
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
208
|
+
```css
|
|
209
|
+
--xz-box-shadow-100 /* 0 1px 2px — subtle */
|
|
210
|
+
--xz-box-shadow-200 /* 0 2px 6px — small */
|
|
211
|
+
--xz-box-shadow-300 /* 0 4px 16px — medium */
|
|
212
|
+
--xz-box-shadow-400 /* 0 8px 20px — large */
|
|
213
|
+
```
|
|
139
214
|
|
|
140
|
-
|
|
141
|
-
- `--xz-color-{name}-soft-100/200/300` - Soft background colors
|
|
142
|
-
- `--xz-color-{name}-line-100/200/300` - Border colors
|
|
143
|
-
- `--xz-color-{name}-bg-100` - Main solid background color
|
|
144
|
-
- `--xz-color-{name}-bg-200` - Hover/darker background color
|
|
145
|
-
- `--xz-color-{name}-fg-100` - Text on solid backgrounds (white)
|
|
146
|
-
- `--xz-color-{name}-text-100` - Main foreground/text color
|
|
147
|
-
- `--xz-color-{name}-text-200` - Emphasized foreground/text color
|
|
215
|
+
## JavaScript/TypeScript API
|
|
148
216
|
|
|
149
|
-
###
|
|
217
|
+
### Theme Objects
|
|
150
218
|
|
|
151
219
|
```typescript
|
|
152
|
-
import { lightTheme, darkTheme,
|
|
220
|
+
import { lightTheme, darkTheme, themes, getTheme, getThemeNames } from '@fastwork/xosmoz-theme';
|
|
221
|
+
|
|
222
|
+
// Access raw palette colors
|
|
223
|
+
lightTheme.colors.fastwork[600] // 'oklch(0.613 0.233 260.608)'
|
|
224
|
+
lightTheme.colors.gray[300] // 'oklch(0.792 0.006 264.532)'
|
|
225
|
+
|
|
226
|
+
// Access semantic colors
|
|
227
|
+
lightTheme.colors.primary.bg[100] // solid fill color
|
|
228
|
+
lightTheme.colors.primary.fg[100] // 'oklch(1 0 0 / 0.95)' — white for text on solid bg
|
|
229
|
+
lightTheme.colors.primary.text[100] // colored text
|
|
153
230
|
|
|
154
|
-
// Access
|
|
155
|
-
|
|
156
|
-
|
|
231
|
+
// Access base tokens
|
|
232
|
+
lightTheme.colors.surface[200] // card background
|
|
233
|
+
lightTheme.colors.text[100] // primary text
|
|
157
234
|
|
|
158
|
-
// Access
|
|
159
|
-
|
|
235
|
+
// Access box shadows
|
|
236
|
+
lightTheme.boxShadows[200] // '0 2px 6px 0 rgba(0, 0, 0, 0.10)'
|
|
160
237
|
|
|
161
|
-
//
|
|
162
|
-
|
|
238
|
+
// Get theme by name
|
|
239
|
+
const theme = getTheme('dark');
|
|
240
|
+
|
|
241
|
+
// List available themes
|
|
242
|
+
const names = getThemeNames(); // ['light', 'dark']
|
|
163
243
|
```
|
|
164
244
|
|
|
165
|
-
###
|
|
245
|
+
### Design Tokens
|
|
166
246
|
|
|
167
247
|
```typescript
|
|
168
|
-
import {
|
|
169
|
-
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// }
|
|
248
|
+
import { fontSize, fontWeight, fontFamily, lineHeight, font, typography } from '@fastwork/xosmoz-theme/tokens';
|
|
249
|
+
|
|
250
|
+
fontSize[400] // '1rem'
|
|
251
|
+
fontSize[700] // '1.5rem'
|
|
252
|
+
fontWeight[700] // 700
|
|
253
|
+
fontFamily.primary // system sans-serif stack
|
|
254
|
+
fontFamily.secondary // "Fastwork" + fallbacks
|
|
255
|
+
lineHeight['150pct'] // '1.5'
|
|
256
|
+
|
|
257
|
+
// Semantic font tokens
|
|
258
|
+
font.heading1 // { fontFamily, fontSize: { desktop, mobile }, fontWeight, lineHeight }
|
|
259
|
+
font.title2
|
|
260
|
+
font.subtitle1Bold
|
|
261
|
+
font.body1
|
|
262
|
+
|
|
263
|
+
// All typography combined
|
|
264
|
+
typography.fontSize
|
|
265
|
+
typography.fontFamily
|
|
266
|
+
typography.font
|
|
188
267
|
```
|
|
189
268
|
|
|
190
|
-
|
|
269
|
+
### Types
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
import type {
|
|
273
|
+
ThemeConfig,
|
|
274
|
+
ThemeName,
|
|
275
|
+
ThemeRegistry,
|
|
276
|
+
ColorToken,
|
|
277
|
+
TypographyToken,
|
|
278
|
+
TypographyScale,
|
|
279
|
+
FontWeights,
|
|
280
|
+
HeadingTokens,
|
|
281
|
+
TitleTokens,
|
|
282
|
+
SubtitleTokens,
|
|
283
|
+
BodyTokens,
|
|
284
|
+
Theme,
|
|
285
|
+
} from '@fastwork/xosmoz-theme';
|
|
286
|
+
```
|
|
191
287
|
|
|
192
|
-
|
|
193
|
-
- **Primary, Secondary, Accent** - Main brand colors
|
|
194
|
-
- **Neutral** - Grayscale palette
|
|
195
|
-
- **Semantic colors** - Success, Warning, Error, Info
|
|
196
|
-
- Each color has **11 shades** (50-950) for maximum flexibility
|
|
288
|
+
## Custom Themes
|
|
197
289
|
|
|
198
|
-
|
|
199
|
-
- **Font sizes**: xs, sm, base, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl
|
|
200
|
-
- **Font weights**: thin, extralight, light, normal, medium, semibold, bold, extrabold, black
|
|
201
|
-
- **Font families**: sans, serif, mono
|
|
202
|
-
- **Line heights**: none, tight, snug, normal, relaxed, loose
|
|
290
|
+
Override any CSS variable for a custom theme:
|
|
203
291
|
|
|
204
|
-
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
292
|
+
```css
|
|
293
|
+
[data-theme="brand"] {
|
|
294
|
+
--xz-color-surface-100: oklch(1.00 0 0);
|
|
295
|
+
--xz-color-surface-200: oklch(0.98 0.005 260);
|
|
296
|
+
--xz-color-text-100: oklch(0.20 0.006 285);
|
|
297
|
+
--xz-color-line-100: oklch(0.95 0 1 / 0.95);
|
|
298
|
+
--xz-color-primary-bg-100: oklch(0.58 0.25 30);
|
|
299
|
+
--xz-color-primary-fg-100: oklch(1 0 0 / 0.95);
|
|
300
|
+
--xz-color-primary-text-100: oklch(0.58 0.25 30);
|
|
301
|
+
/* override other variables as needed */
|
|
302
|
+
}
|
|
303
|
+
```
|
|
208
304
|
|
|
209
|
-
|
|
210
|
-
- From **none** to **full** circle
|
|
211
|
-
- Standard sizes: sm, base, md, lg, xl, 2xl, 3xl
|
|
305
|
+
Then activate it:
|
|
212
306
|
|
|
213
|
-
|
|
214
|
-
-
|
|
215
|
-
|
|
216
|
-
- Optimized for light and dark modes
|
|
307
|
+
```html
|
|
308
|
+
<html data-theme="brand">...</html>
|
|
309
|
+
```
|
|
217
310
|
|
|
218
|
-
##
|
|
311
|
+
## Common Patterns
|
|
219
312
|
|
|
220
|
-
|
|
313
|
+
### Card
|
|
221
314
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
315
|
+
```css
|
|
316
|
+
.card {
|
|
317
|
+
background: var(--xz-color-surface-200);
|
|
318
|
+
color: var(--xz-color-text-100);
|
|
319
|
+
border: 1px solid var(--xz-color-line-100);
|
|
320
|
+
border-radius: 0.75rem;
|
|
321
|
+
box-shadow: var(--xz-box-shadow-200);
|
|
322
|
+
}
|
|
323
|
+
```
|
|
227
324
|
|
|
228
|
-
###
|
|
325
|
+
### Primary button
|
|
229
326
|
|
|
230
327
|
```css
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
328
|
+
.btn-primary {
|
|
329
|
+
background: var(--xz-color-primary-bg-100);
|
|
330
|
+
color: var(--xz-color-primary-fg-100);
|
|
331
|
+
font: var(--xz-font-subtitle1-bold);
|
|
332
|
+
border: none;
|
|
333
|
+
border-radius: 0.5rem;
|
|
334
|
+
}
|
|
335
|
+
.btn-primary:hover {
|
|
336
|
+
background: var(--xz-color-primary-bg-200);
|
|
337
|
+
}
|
|
338
|
+
```
|
|
234
339
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
340
|
+
### Outline button
|
|
341
|
+
|
|
342
|
+
```css
|
|
343
|
+
.btn-outline {
|
|
344
|
+
background: transparent;
|
|
345
|
+
color: var(--xz-color-primary-text-100);
|
|
346
|
+
border: 1px solid var(--xz-color-primary-line-200);
|
|
347
|
+
}
|
|
238
348
|
```
|
|
239
349
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
350
|
+
### Alert
|
|
351
|
+
|
|
352
|
+
```css
|
|
353
|
+
.alert-success {
|
|
354
|
+
background: var(--xz-color-success-soft-100);
|
|
355
|
+
color: var(--xz-color-success-text-100);
|
|
356
|
+
border: 1px solid var(--xz-color-success-line-100);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.alert-danger {
|
|
360
|
+
background: var(--xz-color-danger-bg-100);
|
|
361
|
+
color: var(--xz-color-danger-fg-100);
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Form input
|
|
366
|
+
|
|
367
|
+
```css
|
|
368
|
+
.input {
|
|
369
|
+
background: var(--xz-color-surface-100);
|
|
370
|
+
color: var(--xz-color-text-100);
|
|
371
|
+
border: 1px solid var(--xz-color-line-200);
|
|
372
|
+
font: var(--xz-font-body1);
|
|
373
|
+
}
|
|
374
|
+
.input:focus {
|
|
375
|
+
border-color: var(--xz-color-primary-line-200);
|
|
376
|
+
box-shadow: 0 0 0 3px var(--xz-color-primary-soft-100);
|
|
377
|
+
}
|
|
244
378
|
```
|
|
245
379
|
|
|
380
|
+
### Muted text
|
|
381
|
+
|
|
382
|
+
```css
|
|
383
|
+
.text-muted { color: var(--xz-color-text-200); }
|
|
384
|
+
.text-disabled { color: var(--xz-color-text-300); }
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## CSS Files
|
|
388
|
+
|
|
389
|
+
| Import path | Contents |
|
|
390
|
+
|-------------|----------|
|
|
391
|
+
| `@fastwork/xosmoz-theme/base.css` | Font imports, CSS reset, non-color tokens (typography, spacing, borders, shadows) |
|
|
392
|
+
| `@fastwork/xosmoz-theme/themes.css` | All themes (light + dark) |
|
|
393
|
+
| `@fastwork/xosmoz-theme/themes/light.css` | Light theme colors only |
|
|
394
|
+
| `@fastwork/xosmoz-theme/themes/dark.css` | Dark theme colors only |
|
|
395
|
+
|
|
246
396
|
## Development
|
|
247
397
|
|
|
248
398
|
```bash
|
|
249
|
-
# Build the package
|
|
399
|
+
# Build the package (TypeScript + CSS)
|
|
250
400
|
npm run build
|
|
251
401
|
|
|
252
|
-
# Watch mode
|
|
402
|
+
# Watch mode
|
|
253
403
|
npm run dev
|
|
254
404
|
|
|
255
|
-
# Lint
|
|
405
|
+
# Lint
|
|
256
406
|
npm run lint
|
|
257
407
|
|
|
258
|
-
#
|
|
408
|
+
# Remove dist/
|
|
259
409
|
npm run clean
|
|
260
410
|
```
|
|
261
411
|
|