@weichenlin/swell-ui 0.1.0 → 0.3.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 +187 -17
- package/dist/index.d.ts +106 -6
- package/dist/index.js +486 -170
- package/dist/theme.css +215 -237
- package/dist/typography.css +12 -0
- package/package.json +2 -1
package/dist/theme.css
CHANGED
|
@@ -1,267 +1,253 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* swell-ui design tokens
|
|
2
|
+
* swell-ui design tokens and base styles.
|
|
3
3
|
* Import right after tailwindcss. Contains no utilities and no @source:
|
|
4
4
|
* use styles.css to also have Tailwind scan the components.
|
|
5
|
+
*
|
|
6
|
+
* Colors come in two layers:
|
|
7
|
+
* - Base colors (the palette): page, surfaces, text, brand, status. The only literal colors here;
|
|
8
|
+
* these are what an app overrides.
|
|
9
|
+
* - Everything else is computed from them at runtime with var() and color-mix(), so overriding a
|
|
10
|
+
* base color carries through. The mix percentages reproduce the tuned values for the default
|
|
11
|
+
* palette and a warm parchment one, contrast-checked (text >=4.5:1, field borders >=3:1). A palette far from
|
|
12
|
+
* these can still fall short: check contrast after changing bg, surface or fg.
|
|
13
|
+
*
|
|
14
|
+
* Light/dark pairs are written once as light-dark(<light>, <dark>), following `color-scheme` on
|
|
15
|
+
* the root: the system by default, forced by data-theme="light" / "dark". Tailwind's build
|
|
16
|
+
* polyfills light-dark() for browsers that lack it.
|
|
5
17
|
*/
|
|
6
18
|
|
|
7
|
-
/* Tokens. Light values live on bare :root (and @theme). */
|
|
8
19
|
@theme {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
--color-
|
|
12
|
-
--color-surface
|
|
13
|
-
--color-
|
|
14
|
-
--color-fg
|
|
15
|
-
|
|
16
|
-
--color-
|
|
17
|
-
--color-
|
|
18
|
-
--color-
|
|
19
|
-
|
|
20
|
-
--color-
|
|
21
|
-
--color-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
--color-
|
|
26
|
-
--color-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
/* ---- Base colors ---- */
|
|
21
|
+
|
|
22
|
+
--color-bg: light-dark(#f4f4f4, #141414); /* page */
|
|
23
|
+
--color-surface: light-dark(#f9f9f9, #303030); /* cards, panels, text fields */
|
|
24
|
+
--color-surface-raised: light-dark(#ffffff, #303030); /* popovers, dialogs */
|
|
25
|
+
--color-fg: light-dark(#141414, #f9f9f9); /* text */
|
|
26
|
+
/* Brand: defaults to the text color (neutral). A rebrand sets these two. */
|
|
27
|
+
--color-primary: var(--color-fg);
|
|
28
|
+
--color-primary-fg: light-dark(var(--color-surface), var(--color-bg));
|
|
29
|
+
--color-focus: #3898ec; /* keyboard focus outline */
|
|
30
|
+
/* Status. Light red on dark: one danger can't pass 4.5:1 both as a fill and as text. */
|
|
31
|
+
--color-danger: light-dark(#b53333, #ee8a80);
|
|
32
|
+
--color-success: light-dark(
|
|
33
|
+
#394d00,
|
|
34
|
+
#758e48
|
|
35
|
+
); /* olive; deepest, so it parts from danger by lightness (CVD) */
|
|
36
|
+
--color-warning: light-dark(#a5761d, #e6b463); /* amber */
|
|
37
|
+
--color-info: light-dark(#3e7087, #74a6bf); /* muted teal-blue */
|
|
38
|
+
|
|
39
|
+
/* ---- Computed: fg mixed into bg (in oklab) unless noted ---- */
|
|
40
|
+
|
|
41
|
+
/* Secondary brand color; no component uses it */
|
|
42
|
+
--color-accent: var(--color-primary);
|
|
43
|
+
|
|
44
|
+
--color-surface-muted: light-dark(
|
|
45
|
+
color-mix(in oklab, var(--color-fg) 5%, var(--color-bg)),
|
|
46
|
+
color-mix(in oklab, var(--color-fg) 10%, var(--color-bg))
|
|
47
|
+
); /* hover fills, secondary button; sunk below surface on dark */
|
|
48
|
+
--color-fg-strong: color-mix(in oklab, var(--color-fg) 71%, var(--color-bg));
|
|
49
|
+
--color-fg-muted: light-dark(
|
|
50
|
+
color-mix(in oklab, var(--color-fg) 63%, var(--color-bg)),
|
|
51
|
+
color-mix(in oklab, var(--color-fg) 71%, var(--color-bg))
|
|
52
|
+
);
|
|
53
|
+
/* >=4.5:1 on every surface, including surface-muted and the popover highlight */
|
|
54
|
+
--color-fg-subtle: light-dark(
|
|
55
|
+
color-mix(in oklab, var(--color-fg) 58%, var(--color-bg)),
|
|
56
|
+
color-mix(in oklab, var(--color-fg) 69%, var(--color-bg))
|
|
57
|
+
);
|
|
58
|
+
--color-border: light-dark(
|
|
59
|
+
color-mix(in oklab, var(--color-fg) 2%, var(--color-bg)),
|
|
60
|
+
color-mix(in oklab, var(--color-fg) 19%, var(--color-bg))
|
|
61
|
+
); /* row dividers */
|
|
62
|
+
--color-border-strong: light-dark(
|
|
63
|
+
color-mix(in oklab, var(--color-fg) 5%, var(--color-bg)),
|
|
64
|
+
color-mix(in oklab, var(--color-fg) 22%, var(--color-bg))
|
|
65
|
+
);
|
|
66
|
+
--color-ring: light-dark(
|
|
67
|
+
color-mix(in oklab, var(--color-fg) 14%, var(--color-bg)),
|
|
68
|
+
color-mix(in oklab, var(--color-fg) 22%, var(--color-bg))
|
|
69
|
+
);
|
|
70
|
+
--color-ring-deep: light-dark(
|
|
71
|
+
color-mix(in oklab, var(--color-fg) 20%, var(--color-bg)),
|
|
72
|
+
color-mix(in oklab, var(--color-fg) 29%, var(--color-bg))
|
|
73
|
+
);
|
|
74
|
+
/* Tooltips and the `dark` button: near-fg on light, the page itself on dark */
|
|
75
|
+
--color-inverse: light-dark(
|
|
76
|
+
color-mix(in oklab, var(--color-fg) 85%, var(--color-bg)),
|
|
77
|
+
var(--color-bg)
|
|
78
|
+
);
|
|
79
|
+
--color-inverse-fg: light-dark(var(--color-surface), var(--color-fg-muted));
|
|
80
|
+
--color-danger-fg: light-dark(var(--color-surface), var(--color-bg));
|
|
81
|
+
|
|
29
82
|
/*
|
|
30
|
-
* Text fields
|
|
31
|
-
*
|
|
32
|
-
*
|
|
83
|
+
* Text fields sit on the container color (as Ant Design, Primer and Fluent do): lighter than the
|
|
84
|
+
* page, the same as a card. Read-only drops to the page color, so it reads flatter than editable.
|
|
85
|
+
* Borders are kept >=3:1 against the page, the card and the fill (WCAG 1.4.11).
|
|
86
|
+
* Hover changes the border and adds a faint drop shadow; the fill stays.
|
|
33
87
|
*/
|
|
34
|
-
|
|
35
|
-
--color-input-bg:
|
|
36
|
-
--color-input-border:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
--color-input-
|
|
41
|
-
|
|
42
|
-
|
|
88
|
+
--color-input-bg: var(--color-surface);
|
|
89
|
+
--color-input-bg-hover: var(--color-input-bg);
|
|
90
|
+
--color-input-border: light-dark(
|
|
91
|
+
color-mix(in oklab, var(--color-fg) 48%, var(--color-bg)),
|
|
92
|
+
color-mix(in oklab, var(--color-fg) 52%, var(--color-bg))
|
|
93
|
+
);
|
|
94
|
+
--color-input-placeholder: light-dark(
|
|
95
|
+
color-mix(in oklab, var(--color-fg) 57%, var(--color-bg)),
|
|
96
|
+
color-mix(in oklab, var(--color-fg) 62%, var(--color-bg))
|
|
97
|
+
);
|
|
98
|
+
--color-input-border-hover: var(--color-fg-strong);
|
|
99
|
+
--color-input-focus: var(--color-primary);
|
|
100
|
+
--color-input-highlight: light-dark(rgb(0 0 0 / 0.03), rgb(255 255 255 / 0.04));
|
|
43
101
|
--shadow-input: inset 0 1px 0 var(--color-input-highlight);
|
|
44
|
-
|
|
102
|
+
/* A drop shadow doesn't read on near-black, so it fades out on dark */
|
|
103
|
+
--shadow-input-lift: 0 1px 2px light-dark(rgb(0 0 0 / 0.06), transparent);
|
|
45
104
|
/* Focus/error halos: decorative 3px rings outside the border */
|
|
46
105
|
--color-input-halo: color-mix(in oklab, var(--color-input-focus) 14%, transparent);
|
|
47
106
|
--color-input-halo-invalid: color-mix(in oklab, var(--color-danger) 12%, transparent);
|
|
48
107
|
--color-input-halo-invalid-focus: color-mix(in oklab, var(--color-danger) 22%, transparent);
|
|
108
|
+
|
|
49
109
|
/*
|
|
50
|
-
* Selection controls (Switch, Checkbox): the checked fill and the
|
|
110
|
+
* Selection controls (Switch, Checkbox): the checked fill, and the check/dash drawn on it.
|
|
51
111
|
* The off track/box reuses the input border, which is already >=3:1 on the page and the fill.
|
|
52
112
|
*/
|
|
53
|
-
--color-control-checked:
|
|
54
|
-
--color-control-checked-fg:
|
|
55
|
-
/*
|
|
56
|
-
*
|
|
113
|
+
--color-control-checked: var(--color-primary);
|
|
114
|
+
--color-control-checked-fg: var(--color-primary-fg);
|
|
115
|
+
/*
|
|
116
|
+
* Switch handle (the thumb). Off: the raised surface (white) on light, the text color on dark.
|
|
117
|
+
* On: white, unless the checked track is very light (oklch L > 0.9, e.g. the default brand on
|
|
118
|
+
* dark), then black. That is what CSS contrast-color() does, written with relative color syntax
|
|
119
|
+
* for wider support.
|
|
120
|
+
*/
|
|
121
|
+
--color-switch-handle: light-dark(var(--color-surface-raised), var(--color-fg));
|
|
122
|
+
--color-switch-handle-checked: oklch(
|
|
123
|
+
from var(--color-control-checked) clamp(0, (0.9 - l) * 1000, 1) 0 0
|
|
124
|
+
);
|
|
125
|
+
/* Thumb: a hairline plus a soft drop straight down (a sideways offset makes the small thumb look shifted) */
|
|
57
126
|
--shadow-switch-thumb: 0 0 0 0.5px rgb(0 0 0 / 0.08), 0 1px 2px rgb(0 0 0 / 0.2);
|
|
127
|
+
|
|
58
128
|
/*
|
|
59
|
-
* Popovers (the Select picker): raised
|
|
60
|
-
* Highlight is the hovered/keyboard-active row
|
|
129
|
+
* Popovers (the Select picker): the raised surface with a hairline and a soft shadow; fg is mixed
|
|
130
|
+
* into the raised surface here. Highlight is the hovered/keyboard-active row.
|
|
131
|
+
* Dark shadows are darker and denser: the surface itself already separates from near-black.
|
|
61
132
|
*/
|
|
62
|
-
--color-popover-bg:
|
|
63
|
-
--color-popover-border:
|
|
64
|
-
|
|
65
|
-
|
|
133
|
+
--color-popover-bg: var(--color-surface-raised);
|
|
134
|
+
--color-popover-border: light-dark(
|
|
135
|
+
color-mix(in oklab, var(--color-fg) 12%, var(--color-surface-raised)),
|
|
136
|
+
color-mix(in oklab, var(--color-fg) 8%, var(--color-surface-raised))
|
|
137
|
+
);
|
|
138
|
+
--color-popover-highlight: light-dark(
|
|
139
|
+
color-mix(in oklab, var(--color-fg) 7%, var(--color-surface-raised)),
|
|
140
|
+
color-mix(in oklab, var(--color-fg) 8%, var(--color-surface-raised))
|
|
141
|
+
);
|
|
142
|
+
--shadow-popover:
|
|
143
|
+
0 8px 24px light-dark(rgb(0 0 0 / 0.08), rgb(0 0 0 / 0.4)),
|
|
144
|
+
0 1px 3px light-dark(rgb(0 0 0 / 0.06), rgb(0 0 0 / 0.3));
|
|
66
145
|
/*
|
|
67
|
-
* Dialogs: same surface and hairline as popovers, one elevation step higher
|
|
68
|
-
*
|
|
146
|
+
* Dialogs: same surface and hairline as popovers, one elevation step higher. The backdrop is
|
|
147
|
+
* never blurred; it is darker on dark because a 40% dim barely reads over a near-black page.
|
|
69
148
|
*/
|
|
70
|
-
--shadow-dialog:
|
|
71
|
-
|
|
149
|
+
--shadow-dialog:
|
|
150
|
+
0 16px 48px light-dark(rgb(0 0 0 / 0.12), rgb(0 0 0 / 0.5)),
|
|
151
|
+
0 2px 6px light-dark(rgb(0 0 0 / 0.06), rgb(0 0 0 / 0.3));
|
|
152
|
+
--color-dialog-backdrop: light-dark(
|
|
153
|
+
color-mix(in oklab, var(--color-fg) 40%, transparent),
|
|
154
|
+
rgb(0 0 0 / 0.6)
|
|
155
|
+
);
|
|
156
|
+
|
|
72
157
|
/*
|
|
73
|
-
* Status tones (Badge,
|
|
158
|
+
* Status tones (Badge, Toast, ...). Per tone: main = solid fill / standalone icon,
|
|
74
159
|
* -fg = text on a solid fill, -subtle-bg/-subtle-fg = tinted badge, -border = its hairline.
|
|
75
|
-
* subtle-bg is main mixed
|
|
76
|
-
* pushed
|
|
77
|
-
* Meaning is carried by text + icon
|
|
78
|
-
* danger main/-fg already exist above; only its subtle-* are new.
|
|
160
|
+
* subtle-bg is main mixed into bg (14% light / 16% dark), border likewise (35% / 40%);
|
|
161
|
+
* subtle-fg is main pushed toward fg until >=5:1 on subtle-bg (the % differs per tone).
|
|
162
|
+
* Meaning is carried by text + icon, not color alone.
|
|
79
163
|
*/
|
|
80
|
-
|
|
81
|
-
--color-success:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
--color-success-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
--color-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
--color-
|
|
95
|
-
--color-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
--color-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
--color-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
--color-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
--
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
--
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
--
|
|
120
|
-
--
|
|
164
|
+
--color-success-fg: light-dark(var(--color-surface), var(--color-bg));
|
|
165
|
+
--color-success-subtle-bg: light-dark(
|
|
166
|
+
color-mix(in oklab, var(--color-success) 14%, var(--color-bg)),
|
|
167
|
+
color-mix(in oklab, var(--color-success) 16%, var(--color-bg))
|
|
168
|
+
);
|
|
169
|
+
--color-success-subtle-fg: light-dark(
|
|
170
|
+
color-mix(in oklab, var(--color-fg) 2%, var(--color-success)),
|
|
171
|
+
color-mix(in oklab, var(--color-fg) 14%, var(--color-success))
|
|
172
|
+
);
|
|
173
|
+
--color-success-border: light-dark(
|
|
174
|
+
color-mix(in oklab, var(--color-success) 35%, var(--color-bg)),
|
|
175
|
+
color-mix(in oklab, var(--color-success) 40%, var(--color-bg))
|
|
176
|
+
);
|
|
177
|
+
/* Dark text on amber in both schemes: light text on it fails 4.5:1 */
|
|
178
|
+
--color-warning-fg: light-dark(var(--color-fg), var(--color-bg));
|
|
179
|
+
--color-warning-subtle-bg: light-dark(
|
|
180
|
+
color-mix(in oklab, var(--color-warning) 14%, var(--color-bg)),
|
|
181
|
+
color-mix(in oklab, var(--color-warning) 16%, var(--color-bg))
|
|
182
|
+
);
|
|
183
|
+
--color-warning-subtle-fg: light-dark(
|
|
184
|
+
color-mix(in oklab, var(--color-fg) 30%, var(--color-warning)),
|
|
185
|
+
color-mix(in oklab, var(--color-fg) 2%, var(--color-warning))
|
|
186
|
+
);
|
|
187
|
+
--color-warning-border: light-dark(
|
|
188
|
+
color-mix(in oklab, var(--color-warning) 35%, var(--color-bg)),
|
|
189
|
+
color-mix(in oklab, var(--color-warning) 40%, var(--color-bg))
|
|
190
|
+
);
|
|
191
|
+
--color-danger-subtle-bg: light-dark(
|
|
192
|
+
color-mix(in oklab, var(--color-danger) 14%, var(--color-bg)),
|
|
193
|
+
color-mix(in oklab, var(--color-danger) 16%, var(--color-bg))
|
|
194
|
+
);
|
|
195
|
+
--color-danger-subtle-fg: light-dark(
|
|
196
|
+
color-mix(in oklab, var(--color-fg) 11%, var(--color-danger)),
|
|
197
|
+
color-mix(in oklab, var(--color-fg) 2%, var(--color-danger))
|
|
198
|
+
);
|
|
199
|
+
--color-danger-border: light-dark(
|
|
200
|
+
color-mix(in oklab, var(--color-danger) 35%, var(--color-bg)),
|
|
201
|
+
color-mix(in oklab, var(--color-danger) 40%, var(--color-bg))
|
|
202
|
+
);
|
|
203
|
+
--color-info-fg: light-dark(var(--color-surface), var(--color-bg));
|
|
204
|
+
--color-info-subtle-bg: light-dark(
|
|
205
|
+
color-mix(in oklab, var(--color-info) 14%, var(--color-bg)),
|
|
206
|
+
color-mix(in oklab, var(--color-info) 16%, var(--color-bg))
|
|
207
|
+
);
|
|
208
|
+
--color-info-subtle-fg: light-dark(
|
|
209
|
+
color-mix(in oklab, var(--color-fg) 17%, var(--color-info)),
|
|
210
|
+
color-mix(in oklab, var(--color-fg) 2%, var(--color-info))
|
|
211
|
+
);
|
|
212
|
+
--color-info-border: light-dark(
|
|
213
|
+
color-mix(in oklab, var(--color-info) 35%, var(--color-bg)),
|
|
214
|
+
color-mix(in oklab, var(--color-info) 40%, var(--color-bg))
|
|
215
|
+
);
|
|
216
|
+
/* neutral: a gray between fg and bg */
|
|
217
|
+
--color-neutral: light-dark(
|
|
218
|
+
color-mix(in oklab, var(--color-fg) 60%, var(--color-bg)),
|
|
219
|
+
color-mix(in oklab, var(--color-fg) 71%, var(--color-bg))
|
|
220
|
+
);
|
|
221
|
+
--color-neutral-fg: light-dark(var(--color-surface), var(--color-bg));
|
|
222
|
+
--color-neutral-subtle-bg: light-dark(
|
|
223
|
+
color-mix(in oklab, var(--color-neutral) 14%, var(--color-bg)),
|
|
224
|
+
color-mix(in oklab, var(--color-neutral) 16%, var(--color-bg))
|
|
225
|
+
);
|
|
226
|
+
--color-neutral-subtle-fg: light-dark(
|
|
227
|
+
color-mix(in oklab, var(--color-fg) 11%, var(--color-neutral)),
|
|
228
|
+
color-mix(in oklab, var(--color-fg) 2%, var(--color-neutral))
|
|
229
|
+
);
|
|
230
|
+
--color-neutral-border: light-dark(
|
|
231
|
+
color-mix(in oklab, var(--color-neutral) 35%, var(--color-bg)),
|
|
232
|
+
color-mix(in oklab, var(--color-neutral) 40%, var(--color-bg))
|
|
233
|
+
);
|
|
121
234
|
|
|
235
|
+
/* Fonts and radii are Tailwind's defaults; see the README to change them */
|
|
122
236
|
--shadow-whisper: rgba(0, 0, 0, 0.05) 0 4px 24px;
|
|
123
237
|
--container-page: 1200px;
|
|
124
238
|
}
|
|
125
239
|
|
|
240
|
+
/* Follow the system unless data-theme forces one; light-dark() above reads this */
|
|
126
241
|
:root {
|
|
127
|
-
color-scheme: light;
|
|
242
|
+
color-scheme: light dark;
|
|
128
243
|
}
|
|
129
244
|
|
|
130
|
-
|
|
131
|
-
:
|
|
132
|
-
@media (prefers-color-scheme: dark) {
|
|
133
|
-
color-scheme: dark;
|
|
134
|
-
--color-bg: #141413;
|
|
135
|
-
--color-surface: #30302e;
|
|
136
|
-
--color-surface-raised: #30302e;
|
|
137
|
-
--color-surface-muted: #262625; /* sunk below Dark Surface: header rows, hover fills */
|
|
138
|
-
--color-fg: #faf9f5;
|
|
139
|
-
--color-fg-strong: #b0aea5;
|
|
140
|
-
--color-fg-muted: #b0aea5;
|
|
141
|
-
--color-fg-subtle: #a8a79e; /* >=4.5:1 on raised and highlighted surfaces */
|
|
142
|
-
--color-border: #383836; /* between Dark Surface and Dark Warm: row dividers */
|
|
143
|
-
--color-border-strong: #3d3d3a; /* Dark Warm */
|
|
144
|
-
--color-ring: #3d3d3a; /* Dark Warm */
|
|
145
|
-
--color-ring-deep: #4d4c48; /* Charcoal Warm */
|
|
146
|
-
--color-inverse: #141413;
|
|
147
|
-
--color-inverse-fg: #b0aea5;
|
|
148
|
-
--color-danger: #ee8a80;
|
|
149
|
-
--color-danger-fg: #141413;
|
|
150
|
-
--color-input-bg: #1f1f1e; /* white 6% over bg in oklab */
|
|
151
|
-
--color-input-border: #81817e;
|
|
152
|
-
--color-input-placeholder: #9a998f;
|
|
153
|
-
--color-input-border-hover: #b0aea5;
|
|
154
|
-
--color-input-bg-hover: #262625;
|
|
155
|
-
--color-input-focus: #c49a6c; /* Warm Tan: primary is too dark on dark surfaces */
|
|
156
|
-
--color-control-checked: #c49a6c; /* Warm Tan, as the focus color */
|
|
157
|
-
--color-control-checked-fg: #141413; /* white on tan is only ~2.6:1; near-black is 7.2:1 */
|
|
158
|
-
--color-input-highlight: rgb(255 255 255 / 0.04);
|
|
159
|
-
--shadow-input-lift: 0 0 #0000; /* a drop shadow doesn't read on near-black */
|
|
160
|
-
--color-popover-bg: #30302e; /* Dark Surface */
|
|
161
|
-
--color-popover-border: #3d3d3a; /* Dark Warm */
|
|
162
|
-
--color-popover-highlight: #3d3d3a;
|
|
163
|
-
/* Darker and denser than light: the surface itself already separates from near-black */
|
|
164
|
-
--shadow-popover: 0 8px 24px rgb(0 0 0 / 0.4), 0 1px 3px rgb(0 0 0 / 0.3);
|
|
165
|
-
--shadow-dialog: 0 16px 48px rgb(0 0 0 / 0.5), 0 2px 6px rgb(0 0 0 / 0.3);
|
|
166
|
-
/* Darker than light: a 40% dim barely reads over a near-black page */
|
|
167
|
-
--color-dialog-backdrop: rgb(0 0 0 / 0.6);
|
|
168
|
-
/* Status tones: lightened for dark surfaces, solid-fg flips to near-black */
|
|
169
|
-
/* success: olive, lightened for dark; kept darker than danger for CVD */
|
|
170
|
-
--color-success: #758e48;
|
|
171
|
-
--color-success-fg: #141413;
|
|
172
|
-
--color-success-subtle-bg: #22251c;
|
|
173
|
-
--color-success-subtle-fg: #98b070;
|
|
174
|
-
--color-success-border: #384128;
|
|
175
|
-
/* warning: amber */
|
|
176
|
-
--color-warning: #e6b463;
|
|
177
|
-
--color-warning-fg: #141413;
|
|
178
|
-
--color-warning-subtle-bg: #302a20;
|
|
179
|
-
--color-warning-subtle-fg: #e2b56e;
|
|
180
|
-
--color-warning-border: #5f4e33;
|
|
181
|
-
/* danger: existing (unchanged) */
|
|
182
|
-
--color-danger-subtle-bg: #322522;
|
|
183
|
-
--color-danger-subtle-fg: #f0958c;
|
|
184
|
-
--color-danger-border: #63403b;
|
|
185
|
-
/* info: dusty teal-blue */
|
|
186
|
-
--color-info: #74a6bf;
|
|
187
|
-
--color-info-fg: #141413;
|
|
188
|
-
--color-info-subtle-bg: #22282a;
|
|
189
|
-
--color-info-subtle-fg: #87b4cb;
|
|
190
|
-
--color-info-border: #384951;
|
|
191
|
-
/* neutral: Warm Silver */
|
|
192
|
-
--color-neutral: #b0aea5;
|
|
193
|
-
--color-neutral-fg: #141413;
|
|
194
|
-
--color-neutral-subtle-bg: #292927;
|
|
195
|
-
--color-neutral-subtle-fg: #b4b2aa;
|
|
196
|
-
--color-neutral-border: #4c4c48;
|
|
197
|
-
}
|
|
245
|
+
:root[data-theme="light"] {
|
|
246
|
+
color-scheme: light;
|
|
198
247
|
}
|
|
199
248
|
|
|
200
249
|
:root[data-theme="dark"] {
|
|
201
250
|
color-scheme: dark;
|
|
202
|
-
--color-bg: #141413;
|
|
203
|
-
--color-surface: #30302e;
|
|
204
|
-
--color-surface-raised: #30302e;
|
|
205
|
-
--color-surface-muted: #262625; /* sunk below Dark Surface: header rows, hover fills */
|
|
206
|
-
--color-fg: #faf9f5;
|
|
207
|
-
--color-fg-strong: #b0aea5;
|
|
208
|
-
--color-fg-muted: #b0aea5;
|
|
209
|
-
--color-fg-subtle: #a8a79e; /* >=4.5:1 on raised and highlighted surfaces */
|
|
210
|
-
--color-border: #383836; /* between Dark Surface and Dark Warm: row dividers */
|
|
211
|
-
--color-border-strong: #3d3d3a; /* Dark Warm */
|
|
212
|
-
--color-ring: #3d3d3a; /* Dark Warm */
|
|
213
|
-
--color-ring-deep: #4d4c48; /* Charcoal Warm */
|
|
214
|
-
--color-inverse: #141413;
|
|
215
|
-
--color-inverse-fg: #b0aea5;
|
|
216
|
-
/* Light red + dark text: a single danger token can't pass 4.5:1 both as fill and as text on dark */
|
|
217
|
-
--color-danger: #ee8a80;
|
|
218
|
-
--color-danger-fg: #141413;
|
|
219
|
-
--color-input-bg: #1f1f1e; /* white 6% over bg in oklab */
|
|
220
|
-
--color-input-border: #81817e;
|
|
221
|
-
--color-input-placeholder: #9a998f;
|
|
222
|
-
--color-input-border-hover: #b0aea5;
|
|
223
|
-
--color-input-bg-hover: #262625;
|
|
224
|
-
--color-input-focus: #c49a6c; /* Warm Tan: primary is too dark on dark surfaces */
|
|
225
|
-
--color-control-checked: #c49a6c; /* Warm Tan, as the focus color */
|
|
226
|
-
--color-control-checked-fg: #141413; /* white on tan is only ~2.6:1; near-black is 7.2:1 */
|
|
227
|
-
--color-input-highlight: rgb(255 255 255 / 0.04);
|
|
228
|
-
--shadow-input-lift: 0 0 #0000; /* a drop shadow doesn't read on near-black */
|
|
229
|
-
--color-popover-bg: #30302e; /* Dark Surface */
|
|
230
|
-
--color-popover-border: #3d3d3a; /* Dark Warm */
|
|
231
|
-
--color-popover-highlight: #3d3d3a;
|
|
232
|
-
/* Darker and denser than light: the surface itself already separates from near-black */
|
|
233
|
-
--shadow-popover: 0 8px 24px rgb(0 0 0 / 0.4), 0 1px 3px rgb(0 0 0 / 0.3);
|
|
234
|
-
--shadow-dialog: 0 16px 48px rgb(0 0 0 / 0.5), 0 2px 6px rgb(0 0 0 / 0.3);
|
|
235
|
-
--color-dialog-backdrop: rgb(0 0 0 / 0.6);
|
|
236
|
-
/* Status tones: lightened for dark surfaces, solid-fg flips to near-black */
|
|
237
|
-
/* success: olive, lightened for dark; kept darker than danger for CVD */
|
|
238
|
-
--color-success: #758e48;
|
|
239
|
-
--color-success-fg: #141413;
|
|
240
|
-
--color-success-subtle-bg: #22251c;
|
|
241
|
-
--color-success-subtle-fg: #98b070;
|
|
242
|
-
--color-success-border: #384128;
|
|
243
|
-
/* warning: amber */
|
|
244
|
-
--color-warning: #e6b463;
|
|
245
|
-
--color-warning-fg: #141413;
|
|
246
|
-
--color-warning-subtle-bg: #302a20;
|
|
247
|
-
--color-warning-subtle-fg: #e2b56e;
|
|
248
|
-
--color-warning-border: #5f4e33;
|
|
249
|
-
/* danger: existing (unchanged) */
|
|
250
|
-
--color-danger-subtle-bg: #322522;
|
|
251
|
-
--color-danger-subtle-fg: #f0958c;
|
|
252
|
-
--color-danger-border: #63403b;
|
|
253
|
-
/* info: dusty teal-blue */
|
|
254
|
-
--color-info: #74a6bf;
|
|
255
|
-
--color-info-fg: #141413;
|
|
256
|
-
--color-info-subtle-bg: #22282a;
|
|
257
|
-
--color-info-subtle-fg: #87b4cb;
|
|
258
|
-
--color-info-border: #384951;
|
|
259
|
-
/* neutral: Warm Silver */
|
|
260
|
-
--color-neutral: #b0aea5;
|
|
261
|
-
--color-neutral-fg: #141413;
|
|
262
|
-
--color-neutral-subtle-bg: #292927;
|
|
263
|
-
--color-neutral-subtle-fg: #b4b2aa;
|
|
264
|
-
--color-neutral-border: #4c4c48;
|
|
265
251
|
}
|
|
266
252
|
|
|
267
253
|
/* `dark:` follows the tokens: data-theme="dark" on the root, or the system when not forced light */
|
|
@@ -305,7 +291,7 @@
|
|
|
305
291
|
}
|
|
306
292
|
}
|
|
307
293
|
|
|
308
|
-
/* Layered so the app's own utilities (e.g. a body background
|
|
294
|
+
/* Layered so the app's own utilities (e.g. a body background) win */
|
|
309
295
|
@layer base {
|
|
310
296
|
body {
|
|
311
297
|
margin: 0;
|
|
@@ -314,14 +300,6 @@
|
|
|
314
300
|
font-family: var(--font-sans);
|
|
315
301
|
line-height: 1.6;
|
|
316
302
|
}
|
|
317
|
-
|
|
318
|
-
/* Dialog and Drawer titles rely on this */
|
|
319
|
-
h1,
|
|
320
|
-
h2,
|
|
321
|
-
h3 {
|
|
322
|
-
font-family: var(--font-serif);
|
|
323
|
-
font-weight: 500;
|
|
324
|
-
}
|
|
325
303
|
}
|
|
326
304
|
|
|
327
305
|
/* Unlayered: beats Tailwind's layered utilities (e.g. `transition-*`) on cascade order alone */
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Opt-in editorial headings: h1-h3 in the serif stack at weight 500.
|
|
3
|
+
* Import after swell-ui's styles.css (or theme.css). Layered, so utilities on a heading still win.
|
|
4
|
+
*/
|
|
5
|
+
@layer base {
|
|
6
|
+
h1,
|
|
7
|
+
h2,
|
|
8
|
+
h3 {
|
|
9
|
+
font-family: var(--font-serif);
|
|
10
|
+
font-weight: 500;
|
|
11
|
+
}
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weichenlin/swell-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Hand-built React components styled with Tailwind CSS v4.",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"./theme.css": "./dist/theme.css",
|
|
18
18
|
"./styles.css": "./dist/styles.css",
|
|
19
|
+
"./typography.css": "./dist/typography.css",
|
|
19
20
|
"./package.json": "./package.json"
|
|
20
21
|
},
|
|
21
22
|
"publishConfig": {
|