@aquiferre/theme-kit 0.1.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/base.css +33 -0
- package/components.css +360 -0
- package/index.ts +1 -0
- package/package.json +18 -0
- package/tailwind.preset.js +56 -0
- package/theme.ts +54 -0
- package/variables.css +146 -0
package/base.css
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@import './variables.css';
|
|
2
|
+
@import './components.css';
|
|
3
|
+
|
|
4
|
+
@tailwind base;
|
|
5
|
+
@tailwind components;
|
|
6
|
+
@tailwind utilities;
|
|
7
|
+
|
|
8
|
+
@layer base {
|
|
9
|
+
body {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
13
|
+
min-height: 100vh;
|
|
14
|
+
@apply bg-bg-primary text-text-primary antialiased;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
::-webkit-scrollbar {
|
|
18
|
+
width: 6px;
|
|
19
|
+
height: 6px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
::-webkit-scrollbar-track {
|
|
23
|
+
@apply bg-bg-secondary;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
::-webkit-scrollbar-thumb {
|
|
27
|
+
@apply bg-bg-tertiary rounded-full;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
::-webkit-scrollbar-thumb:hover {
|
|
31
|
+
@apply bg-text-tertiary;
|
|
32
|
+
}
|
|
33
|
+
}
|
package/components.css
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/* Reusable Component Styles */
|
|
2
|
+
|
|
3
|
+
@layer components {
|
|
4
|
+
/* ========== Navbar ========== */
|
|
5
|
+
.navbar {
|
|
6
|
+
@apply bg-bg-elevated border-b border-border-primary
|
|
7
|
+
flex items-center justify-between px-6 shadow-xs;
|
|
8
|
+
height: 48px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.navbar-brand {
|
|
12
|
+
@apply text-lg font-bold text-accent-primary;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.navbar-user {
|
|
16
|
+
@apply flex items-center space-x-3;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.navbar-avatar {
|
|
20
|
+
@apply w-7 h-7 rounded-full bg-accent-primary
|
|
21
|
+
flex items-center justify-center text-text-inverse text-xs font-medium;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* ========== Card Components ========== */
|
|
25
|
+
.card {
|
|
26
|
+
@apply bg-bg-elevated border border-border-primary rounded-xl shadow-sm overflow-hidden;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.card-glass {
|
|
30
|
+
@apply bg-bg-glass backdrop-blur-xl border border-border-primary rounded-xl;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.card-hover {
|
|
34
|
+
@apply bg-bg-elevated border border-border-primary rounded-xl shadow-sm transition-all duration-300 overflow-hidden;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.card-hover:hover {
|
|
38
|
+
@apply shadow-lg;
|
|
39
|
+
transform: translateY(-2px);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ========== Input Components ========== */
|
|
43
|
+
.input {
|
|
44
|
+
background-color: var(--color-input-bg);
|
|
45
|
+
color: var(--color-input-text);
|
|
46
|
+
@apply border border-border-primary rounded-md px-3 py-1.5
|
|
47
|
+
text-sm
|
|
48
|
+
transition-all duration-200
|
|
49
|
+
focus:outline-none focus:border-border-focus focus:ring-2;
|
|
50
|
+
--tw-ring-color: color-mix(in srgb, var(--color-accent-primary) 20%, transparent);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.input::placeholder {
|
|
54
|
+
color: var(--color-input-placeholder);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.input-sm {
|
|
58
|
+
@apply px-2.5 py-1 text-xs;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.input-lg {
|
|
62
|
+
@apply px-4 py-2.5 text-base;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.input-error {
|
|
66
|
+
@apply border-border-danger focus:border-border-danger focus:ring-2;
|
|
67
|
+
--tw-ring-color: color-mix(in srgb, var(--color-accent-danger) 20%, transparent);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.select {
|
|
71
|
+
@apply input appearance-none cursor-pointer;
|
|
72
|
+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
|
|
73
|
+
background-position: right 0.5rem center;
|
|
74
|
+
background-repeat: no-repeat;
|
|
75
|
+
background-size: 1.5em 1.5em;
|
|
76
|
+
padding-right: 2.5rem;
|
|
77
|
+
color: var(--color-text-tertiary);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* ========== Button Components ========== */
|
|
81
|
+
.btn {
|
|
82
|
+
@apply inline-flex items-center justify-center
|
|
83
|
+
font-semibold rounded-md px-3 py-1.5 text-sm
|
|
84
|
+
transition-all duration-200
|
|
85
|
+
focus:outline-none focus:ring-2 focus:ring-offset-2
|
|
86
|
+
disabled:opacity-50 disabled:cursor-not-allowed;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.btn-primary {
|
|
90
|
+
@apply btn text-text-inverse
|
|
91
|
+
hover:shadow-lg
|
|
92
|
+
focus:ring-accent-primary;
|
|
93
|
+
background: linear-gradient(to right, var(--color-accent-primary), var(--color-accent-secondary));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.btn-secondary {
|
|
97
|
+
@apply btn bg-bg-secondary text-text-primary border border-border-primary
|
|
98
|
+
hover:bg-bg-hover
|
|
99
|
+
focus:ring-accent-primary;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.btn-danger {
|
|
103
|
+
@apply btn bg-accent-danger text-text-inverse
|
|
104
|
+
hover:shadow-lg
|
|
105
|
+
focus:ring-accent-danger;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.btn-ghost {
|
|
109
|
+
@apply btn bg-transparent text-text-secondary
|
|
110
|
+
hover:bg-bg-hover hover:text-text-primary
|
|
111
|
+
focus:ring-accent-primary;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.btn-sm {
|
|
115
|
+
@apply px-2.5 py-1 text-xs;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.btn-lg {
|
|
119
|
+
@apply px-5 py-2.5 text-base;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.btn-icon {
|
|
123
|
+
@apply btn p-1.5;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* ========== Table Components ========== */
|
|
127
|
+
.table-container {
|
|
128
|
+
@apply overflow-x-auto overflow-y-hidden;
|
|
129
|
+
border-radius: 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.table {
|
|
133
|
+
@apply min-w-full divide-y divide-border-primary;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.table-header {
|
|
137
|
+
@apply bg-bg-tertiary;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.table-header-cell {
|
|
141
|
+
@apply px-6 py-3 text-left text-xs font-medium text-text-secondary uppercase tracking-wider;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.table-body {
|
|
145
|
+
@apply bg-bg-elevated divide-y divide-border-secondary;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.table-row {
|
|
149
|
+
@apply hover:bg-bg-hover transition-colors duration-150;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.table-cell {
|
|
153
|
+
@apply px-6 py-4 whitespace-nowrap text-sm text-text-primary;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.table-empty {
|
|
157
|
+
@apply px-6 py-12 text-center text-text-tertiary;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* ========== Sidebar Components ========== */
|
|
161
|
+
.sidebar {
|
|
162
|
+
@apply bg-sidebar-bg min-h-screen border-r border-sidebar-border;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.sidebar-item {
|
|
166
|
+
@apply flex items-center px-4 py-2.5 text-sidebar-text
|
|
167
|
+
hover:bg-sidebar-hover hover:text-text-primary
|
|
168
|
+
transition-colors duration-150;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.sidebar-item-active {
|
|
172
|
+
@apply bg-sidebar-active text-text-primary font-medium;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.sidebar-section-title {
|
|
176
|
+
@apply px-4 pt-3 pb-1.5 text-text-tertiary uppercase tracking-wider;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* ========== Badge Components ========== */
|
|
180
|
+
.badge {
|
|
181
|
+
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.badge-primary {
|
|
185
|
+
@apply badge;
|
|
186
|
+
background-color: color-mix(in srgb, var(--color-accent-primary) 15%, transparent);
|
|
187
|
+
color: var(--color-accent-primary);
|
|
188
|
+
border: 1px solid color-mix(in srgb, var(--color-accent-primary) 30%, transparent);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.badge-success {
|
|
192
|
+
@apply badge;
|
|
193
|
+
background-color: color-mix(in srgb, var(--color-accent-success) 15%, transparent);
|
|
194
|
+
color: var(--color-accent-success);
|
|
195
|
+
border: 1px solid color-mix(in srgb, var(--color-accent-success) 30%, transparent);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.badge-warning {
|
|
199
|
+
@apply badge;
|
|
200
|
+
background-color: color-mix(in srgb, var(--color-accent-warning) 15%, transparent);
|
|
201
|
+
color: var(--color-accent-warning);
|
|
202
|
+
border: 1px solid color-mix(in srgb, var(--color-accent-warning) 30%, transparent);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.badge-danger {
|
|
206
|
+
@apply badge;
|
|
207
|
+
background-color: color-mix(in srgb, var(--color-accent-danger) 15%, transparent);
|
|
208
|
+
color: var(--color-accent-danger);
|
|
209
|
+
border: 1px solid color-mix(in srgb, var(--color-accent-danger) 30%, transparent);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.badge-info {
|
|
213
|
+
@apply badge;
|
|
214
|
+
background-color: color-mix(in srgb, var(--color-accent-info) 15%, transparent);
|
|
215
|
+
color: var(--color-accent-info);
|
|
216
|
+
border: 1px solid color-mix(in srgb, var(--color-accent-info) 30%, transparent);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* ========== Status Components ========== */
|
|
220
|
+
.status-dot {
|
|
221
|
+
@apply w-2 h-2 rounded-full animate-pulse;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.status-dot-success {
|
|
225
|
+
@apply status-dot bg-accent-success;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.status-dot-warning {
|
|
229
|
+
@apply status-dot bg-accent-warning;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.status-dot-danger {
|
|
233
|
+
@apply status-dot bg-accent-danger;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.status-dot-info {
|
|
237
|
+
@apply status-dot bg-accent-info;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* ========== Dialog Components ========== */
|
|
241
|
+
.dialog-overlay {
|
|
242
|
+
@apply fixed inset-0 bg-bg-overlay z-50 flex items-center justify-center p-4;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.dialog {
|
|
246
|
+
@apply card-glass w-full max-w-md p-6 rounded-2xl shadow-xl;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.dialog-title {
|
|
250
|
+
@apply text-lg font-semibold text-text-primary mb-4;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.dialog-actions {
|
|
254
|
+
@apply flex justify-end space-x-3 mt-6;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/* ========== Toast Components ========== */
|
|
258
|
+
.toast {
|
|
259
|
+
@apply fixed top-4 right-4 z-50 card p-4 shadow-lg min-w-[300px];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.toast-success {
|
|
263
|
+
@apply toast border-l-4 border-accent-success;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.toast-warning {
|
|
267
|
+
@apply toast border-l-4 border-accent-warning;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.toast-danger {
|
|
271
|
+
@apply toast border-l-4 border-accent-danger;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.toast-info {
|
|
275
|
+
@apply toast border-l-4 border-accent-info;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* ========== Pagination Components ========== */
|
|
279
|
+
.pagination {
|
|
280
|
+
@apply flex items-center justify-center space-x-1;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.pagination-btn {
|
|
284
|
+
@apply btn-ghost px-3 py-1.5 text-sm;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.pagination-btn-active {
|
|
288
|
+
@apply pagination-btn bg-accent-primary text-text-inverse;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.pagination-btn-disabled {
|
|
292
|
+
@apply pagination-btn opacity-50 cursor-not-allowed;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* ========== Search Input ========== */
|
|
296
|
+
.search-input {
|
|
297
|
+
@apply input pl-10;
|
|
298
|
+
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor'%3e%3cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z'/%3e%3c/svg%3e");
|
|
299
|
+
background-position: left 0.75rem center;
|
|
300
|
+
background-repeat: no-repeat;
|
|
301
|
+
background-size: 1.25em 1.25em;
|
|
302
|
+
color: var(--color-text-tertiary);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* ========== Filter Dropdown ========== */
|
|
306
|
+
.filter-dropdown {
|
|
307
|
+
@apply relative;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.filter-dropdown-menu {
|
|
311
|
+
@apply absolute top-full left-0 mt-1 w-48 card shadow-lg z-10 py-1;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.filter-dropdown-item {
|
|
315
|
+
@apply px-4 py-2 text-sm text-text-primary hover:bg-bg-hover cursor-pointer;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* ========== Loading States ========== */
|
|
319
|
+
.skeleton {
|
|
320
|
+
@apply bg-bg-tertiary rounded animate-pulse;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.spinner {
|
|
324
|
+
@apply w-5 h-5 border-2 border-text-tertiary border-t-accent-primary rounded-full animate-spin;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* ========== Page Layout ========== */
|
|
328
|
+
.page-container {
|
|
329
|
+
@apply max-w-7xl mx-auto px-8 py-12;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.page-header {
|
|
333
|
+
@apply mb-8;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.page-title {
|
|
337
|
+
@apply text-2xl font-bold text-text-primary mb-2;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.page-subtitle {
|
|
341
|
+
@apply text-text-secondary;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* ========== Form Layout ========== */
|
|
345
|
+
.form-group {
|
|
346
|
+
@apply mb-4;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.form-label {
|
|
350
|
+
@apply block text-xs font-semibold text-text-secondary mb-2 uppercase tracking-wider;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.form-error {
|
|
354
|
+
@apply text-accent-danger text-xs mt-1;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.form-hint {
|
|
358
|
+
@apply text-text-tertiary text-xs mt-1;
|
|
359
|
+
}
|
|
360
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useThemeStore, type ThemeMode } from './theme'
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aquiferre/theme-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.ts",
|
|
9
|
+
"./base.css": "./base.css",
|
|
10
|
+
"./variables.css": "./variables.css",
|
|
11
|
+
"./components.css": "./components.css",
|
|
12
|
+
"./tailwind.preset": "./tailwind.preset.js"
|
|
13
|
+
},
|
|
14
|
+
"files": ["*.css", "*.ts", "*.js"],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
darkMode: ['selector', '[data-theme="dark"]'],
|
|
4
|
+
theme: {
|
|
5
|
+
extend: {
|
|
6
|
+
colors: {
|
|
7
|
+
'bg-primary': 'var(--color-bg-primary)',
|
|
8
|
+
'bg-secondary': 'var(--color-bg-secondary)',
|
|
9
|
+
'bg-tertiary': 'var(--color-bg-tertiary)',
|
|
10
|
+
'bg-elevated': 'var(--color-bg-elevated)',
|
|
11
|
+
'bg-glass': 'var(--color-bg-glass)',
|
|
12
|
+
'bg-overlay': 'var(--color-bg-overlay)',
|
|
13
|
+
'bg-hover': 'var(--color-bg-hover)',
|
|
14
|
+
'text-primary': 'var(--color-text-primary)',
|
|
15
|
+
'text-secondary': 'var(--color-text-secondary)',
|
|
16
|
+
'text-tertiary': 'var(--color-text-tertiary)',
|
|
17
|
+
'text-inverse': 'var(--color-text-inverse)',
|
|
18
|
+
'text-link': 'var(--color-text-link)',
|
|
19
|
+
'border-primary': 'var(--color-border-primary)',
|
|
20
|
+
'border-secondary': 'var(--color-border-secondary)',
|
|
21
|
+
'border-focus': 'var(--color-border-focus)',
|
|
22
|
+
'border-danger': 'var(--color-border-danger)',
|
|
23
|
+
'accent-primary': 'var(--color-accent-primary)',
|
|
24
|
+
'accent-primary-hover': 'var(--color-accent-primary-hover)',
|
|
25
|
+
'accent-secondary': 'var(--color-accent-secondary)',
|
|
26
|
+
'accent-success': 'var(--color-accent-success)',
|
|
27
|
+
'accent-warning': 'var(--color-accent-warning)',
|
|
28
|
+
'accent-danger': 'var(--color-accent-danger)',
|
|
29
|
+
'accent-info': 'var(--color-accent-info)',
|
|
30
|
+
'sidebar-bg': 'var(--color-sidebar-bg)',
|
|
31
|
+
'sidebar-text': 'var(--color-sidebar-text)',
|
|
32
|
+
'sidebar-hover': 'var(--color-sidebar-hover)',
|
|
33
|
+
'sidebar-active': 'var(--color-sidebar-active)',
|
|
34
|
+
'sidebar-border': 'var(--color-sidebar-border)',
|
|
35
|
+
'input-bg': 'var(--color-input-bg)',
|
|
36
|
+
'input-text': 'var(--color-input-text)',
|
|
37
|
+
'input-placeholder': 'var(--color-input-placeholder)',
|
|
38
|
+
},
|
|
39
|
+
boxShadow: {
|
|
40
|
+
xs: 'var(--shadow-xs)',
|
|
41
|
+
sm: 'var(--shadow-sm)',
|
|
42
|
+
md: 'var(--shadow-md)',
|
|
43
|
+
lg: 'var(--shadow-lg)',
|
|
44
|
+
xl: 'var(--shadow-xl)',
|
|
45
|
+
},
|
|
46
|
+
borderRadius: {
|
|
47
|
+
sm: 'var(--radius-sm)',
|
|
48
|
+
md: 'var(--radius-md)',
|
|
49
|
+
lg: 'var(--radius-lg)',
|
|
50
|
+
xl: 'var(--radius-xl)',
|
|
51
|
+
'2xl': 'var(--radius-2xl)',
|
|
52
|
+
full: 'var(--radius-full)',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
}
|
package/theme.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { defineStore } from 'pinia'
|
|
2
|
+
import { ref, watch } from 'vue'
|
|
3
|
+
|
|
4
|
+
export type ThemeMode = 'light' | 'dark' | 'neutral'
|
|
5
|
+
|
|
6
|
+
export const useThemeStore = defineStore('theme', () => {
|
|
7
|
+
const theme = ref<ThemeMode>(
|
|
8
|
+
(localStorage.getItem('theme') as ThemeMode) || 'dark'
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
function toggle() {
|
|
12
|
+
const cycle: ThemeMode[] = ['light', 'dark', 'neutral']
|
|
13
|
+
const idx = cycle.indexOf(theme.value)
|
|
14
|
+
theme.value = cycle[(idx + 1) % cycle.length]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function setTheme(t: ThemeMode) {
|
|
18
|
+
theme.value = t
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function applyTheme(val: ThemeMode) {
|
|
22
|
+
document.documentElement.setAttribute('data-theme', val)
|
|
23
|
+
localStorage.setItem('theme', val)
|
|
24
|
+
|
|
25
|
+
const metaThemeColor = document.querySelector('meta[name="theme-color"]')
|
|
26
|
+
if (metaThemeColor) {
|
|
27
|
+
metaThemeColor.setAttribute('content', val === 'dark' ? '#0f172a' : '#ffffff')
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
watch(theme, (val) => {
|
|
32
|
+
applyTheme(val)
|
|
33
|
+
}, { immediate: true })
|
|
34
|
+
|
|
35
|
+
function getSystemTheme(): ThemeMode {
|
|
36
|
+
if (typeof window === 'undefined') return 'dark'
|
|
37
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (typeof window !== 'undefined') {
|
|
41
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
|
42
|
+
if (!localStorage.getItem('theme')) {
|
|
43
|
+
theme.value = e.matches ? 'dark' : 'light'
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
theme,
|
|
50
|
+
toggle,
|
|
51
|
+
setTheme,
|
|
52
|
+
getSystemTheme,
|
|
53
|
+
}
|
|
54
|
+
})
|
package/variables.css
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/* Theme CSS Variables */
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
/* ========== Light Theme ========== */
|
|
5
|
+
--color-bg-primary: #ffffff;
|
|
6
|
+
--color-bg-secondary: #f8fafc;
|
|
7
|
+
--color-bg-tertiary: #f1f5f9;
|
|
8
|
+
--color-bg-elevated: #ffffff;
|
|
9
|
+
--color-bg-glass: rgba(255, 255, 255, 0.9);
|
|
10
|
+
--color-bg-overlay: rgba(0, 0, 0, 0.5);
|
|
11
|
+
--color-bg-hover: #f1f5f9;
|
|
12
|
+
|
|
13
|
+
--color-text-primary: #0f172a;
|
|
14
|
+
--color-text-secondary: #475569;
|
|
15
|
+
--color-text-tertiary: #94a3b8;
|
|
16
|
+
--color-text-inverse: #ffffff;
|
|
17
|
+
--color-text-link: #2563eb;
|
|
18
|
+
|
|
19
|
+
--color-border-primary: #e2e8f0;
|
|
20
|
+
--color-border-secondary: #f1f5f9;
|
|
21
|
+
--color-border-focus: #2563eb;
|
|
22
|
+
--color-border-danger: #dc2626;
|
|
23
|
+
|
|
24
|
+
--color-accent-primary: #2563eb;
|
|
25
|
+
--color-accent-primary-hover: #1d4ed8;
|
|
26
|
+
--color-accent-secondary: #4f46e5;
|
|
27
|
+
--color-accent-success: #059669;
|
|
28
|
+
--color-accent-warning: #d97706;
|
|
29
|
+
--color-accent-danger: #dc2626;
|
|
30
|
+
--color-accent-info: #0891b2;
|
|
31
|
+
|
|
32
|
+
--color-sidebar-bg: #f8fafc;
|
|
33
|
+
--color-sidebar-text: #475569;
|
|
34
|
+
--color-sidebar-hover: #f1f5f9;
|
|
35
|
+
--color-sidebar-active: #e2e8f0;
|
|
36
|
+
--color-sidebar-border: #e2e8f0;
|
|
37
|
+
|
|
38
|
+
--color-input-bg: #f8fafc;
|
|
39
|
+
--color-input-text: #1e293b;
|
|
40
|
+
--color-input-placeholder: #94a3b8;
|
|
41
|
+
|
|
42
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
43
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
44
|
+
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
45
|
+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
46
|
+
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
47
|
+
|
|
48
|
+
--radius-sm: 0.375rem;
|
|
49
|
+
--radius-md: 0.5rem;
|
|
50
|
+
--radius-lg: 0.75rem;
|
|
51
|
+
--radius-xl: 1rem;
|
|
52
|
+
--radius-2xl: 1.5rem;
|
|
53
|
+
--radius-full: 9999px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* ========== Dark Theme ========== */
|
|
57
|
+
[data-theme="dark"] {
|
|
58
|
+
--color-bg-primary: #0C0C10;
|
|
59
|
+
--color-bg-elevated: #1B1B22;
|
|
60
|
+
--color-sidebar-bg: #161616;
|
|
61
|
+
--color-bg-secondary: #1e1e28;
|
|
62
|
+
--color-bg-tertiary: #282838;
|
|
63
|
+
--color-bg-glass: rgba(27, 27, 34, 0.9);
|
|
64
|
+
--color-bg-overlay: rgba(0, 0, 0, 0.7);
|
|
65
|
+
--color-bg-hover: #1e1e28;
|
|
66
|
+
|
|
67
|
+
--color-text-primary: #f0f0f5;
|
|
68
|
+
--color-text-secondary: #a0a0b0;
|
|
69
|
+
--color-text-tertiary: #7a7a8a;
|
|
70
|
+
--color-text-inverse: #0C0C10;
|
|
71
|
+
--color-text-link: #818cf8;
|
|
72
|
+
|
|
73
|
+
--color-border-primary: #32323e;
|
|
74
|
+
--color-border-secondary: #1e1e28;
|
|
75
|
+
--color-border-focus: #818cf8;
|
|
76
|
+
--color-border-danger: #f87171;
|
|
77
|
+
|
|
78
|
+
--color-accent-primary: #818cf8;
|
|
79
|
+
--color-accent-primary-hover: #6366f1;
|
|
80
|
+
--color-accent-secondary: #a78bfa;
|
|
81
|
+
--color-accent-success: #4ade80;
|
|
82
|
+
--color-accent-warning: #facc15;
|
|
83
|
+
--color-accent-danger: #f87171;
|
|
84
|
+
--color-accent-info: #22d3ee;
|
|
85
|
+
|
|
86
|
+
--color-sidebar-text: #9e9eaa;
|
|
87
|
+
--color-sidebar-hover: #1e1e28;
|
|
88
|
+
--color-sidebar-active: #22222e;
|
|
89
|
+
--color-sidebar-border: #2a2a36;
|
|
90
|
+
|
|
91
|
+
--color-input-bg: #f0f0f5;
|
|
92
|
+
--color-input-text: #1a1a2e;
|
|
93
|
+
--color-input-placeholder: #6a6a7a;
|
|
94
|
+
|
|
95
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
96
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
97
|
+
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -1px rgba(0, 0, 0, 0.4);
|
|
98
|
+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.4);
|
|
99
|
+
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.4);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ========== Neutral Theme ========== */
|
|
103
|
+
[data-theme="neutral"] {
|
|
104
|
+
--color-bg-primary: #f5f5f5;
|
|
105
|
+
--color-bg-secondary: #e8e8e8;
|
|
106
|
+
--color-bg-tertiary: #d9d9d9;
|
|
107
|
+
--color-bg-elevated: #efefef;
|
|
108
|
+
--color-bg-glass: rgba(239, 239, 239, 0.9);
|
|
109
|
+
--color-bg-overlay: rgba(0, 0, 0, 0.4);
|
|
110
|
+
--color-bg-hover: #d9d9d9;
|
|
111
|
+
|
|
112
|
+
--color-text-primary: #2d2d2d;
|
|
113
|
+
--color-text-secondary: #5c5c5c;
|
|
114
|
+
--color-text-tertiary: #8a8a8a;
|
|
115
|
+
--color-text-inverse: #f5f5f5;
|
|
116
|
+
--color-text-link: #5a6a8a;
|
|
117
|
+
|
|
118
|
+
--color-border-primary: #d0d0d0;
|
|
119
|
+
--color-border-secondary: #e0e0e0;
|
|
120
|
+
--color-border-focus: #5a6a8a;
|
|
121
|
+
--color-border-danger: #cc4444;
|
|
122
|
+
|
|
123
|
+
--color-accent-primary: #5a6a8a;
|
|
124
|
+
--color-accent-primary-hover: #4a5a7a;
|
|
125
|
+
--color-accent-secondary: #6a7a9a;
|
|
126
|
+
--color-accent-success: #5a8a5a;
|
|
127
|
+
--color-accent-warning: #8a7a4a;
|
|
128
|
+
--color-accent-danger: #a05050;
|
|
129
|
+
--color-accent-info: #4a7a8a;
|
|
130
|
+
|
|
131
|
+
--color-sidebar-bg: #eaeaea;
|
|
132
|
+
--color-sidebar-text: #5c5c5c;
|
|
133
|
+
--color-sidebar-hover: #d9d9d9;
|
|
134
|
+
--color-sidebar-active: #d0d0d0;
|
|
135
|
+
--color-sidebar-border: #d0d0d0;
|
|
136
|
+
|
|
137
|
+
--color-input-bg: #f0f0f0;
|
|
138
|
+
--color-input-text: #2d2d2d;
|
|
139
|
+
--color-input-placeholder: #8a8a8a;
|
|
140
|
+
|
|
141
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
142
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
143
|
+
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
144
|
+
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
145
|
+
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
146
|
+
}
|