@galvyn-io/design 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.
@@ -0,0 +1,478 @@
1
+ /*
2
+ * ═══════════════════════════════════════════════════
3
+ * GALVYN DESIGN SYSTEM — CSS Custom Properties
4
+ * @galvyn-io/design v0.1.0
5
+ * ═══════════════════════════════════════════════════
6
+ *
7
+ * USAGE:
8
+ * @import "@galvyn-io/design/css";
9
+ *
10
+ * Then set the accent hue on :root or any container:
11
+ * :root { --galvyn-accent-hue: 220; }
12
+ *
13
+ * Hue presets: 220 (blue), 180 (teal), 270 (purple),
14
+ * 340 (pink), 150 (green), 30 (amber)
15
+ *
16
+ * COMPATIBILITY:
17
+ * Works alongside shadcn/ui — all variables are
18
+ * prefixed with --galvyn-* to avoid collisions.
19
+ * ═══════════════════════════════════════════════════
20
+ */
21
+
22
+ /* ─── SHARED TOKENS (theme-independent) ──────────── */
23
+ :root {
24
+ /* Accent control — change these to rotate the palette */
25
+ --galvyn-accent-hue: 220;
26
+ --galvyn-accent-sat: 70%;
27
+
28
+ /* Typography */
29
+ --galvyn-font-sans: 'Geist', ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
30
+ --galvyn-font-mono: 'Geist Mono', 'SF Mono', 'Fira Code', ui-monospace, monospace;
31
+ --galvyn-font-display: 'Geist', ui-sans-serif, -apple-system, sans-serif;
32
+
33
+ /* Spacing (4px base grid) */
34
+ --galvyn-space-0: 0;
35
+ --galvyn-space-px: 1px;
36
+ --galvyn-space-0-5: 2px;
37
+ --galvyn-space-1: 4px;
38
+ --galvyn-space-1-5: 6px;
39
+ --galvyn-space-2: 8px;
40
+ --galvyn-space-2-5: 10px;
41
+ --galvyn-space-3: 12px;
42
+ --galvyn-space-4: 16px;
43
+ --galvyn-space-5: 20px;
44
+ --galvyn-space-6: 24px;
45
+ --galvyn-space-8: 32px;
46
+ --galvyn-space-10: 40px;
47
+ --galvyn-space-12: 48px;
48
+ --galvyn-space-16: 64px;
49
+
50
+ /* Radii */
51
+ --galvyn-radius-none: 0;
52
+ --galvyn-radius-sm: 4px;
53
+ --galvyn-radius-md: 6px;
54
+ --galvyn-radius-lg: 8px;
55
+ --galvyn-radius-xl: 12px;
56
+ --galvyn-radius-2xl: 16px;
57
+ --galvyn-radius-full: 9999px;
58
+
59
+ /* Motion */
60
+ --galvyn-duration-instant: 50ms;
61
+ --galvyn-duration-fast: 100ms;
62
+ --galvyn-duration-normal: 200ms;
63
+ --galvyn-duration-slow: 300ms;
64
+ --galvyn-duration-slower: 500ms;
65
+ --galvyn-ease-default: cubic-bezier(0.16, 1, 0.3, 1);
66
+ --galvyn-ease-in: cubic-bezier(0.55, 0, 1, 0.45);
67
+ --galvyn-ease-out: cubic-bezier(0, 0.55, 0.45, 1);
68
+ --galvyn-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
69
+ --galvyn-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
70
+
71
+ /* Z-index scale */
72
+ --galvyn-z-base: 0;
73
+ --galvyn-z-dropdown: 50;
74
+ --galvyn-z-sticky: 100;
75
+ --galvyn-z-overlay: 200;
76
+ --galvyn-z-modal: 300;
77
+ --galvyn-z-popover: 400;
78
+ --galvyn-z-toast: 500;
79
+ --galvyn-z-tooltip: 600;
80
+ --galvyn-z-command: 700;
81
+ }
82
+
83
+
84
+ /* ─── DARK THEME (default) ───────────────────────── */
85
+ :root,
86
+ .dark,
87
+ [data-theme="dark"] {
88
+ color-scheme: dark;
89
+
90
+ /* Backgrounds */
91
+ --galvyn-bg-000: #09090b;
92
+ --galvyn-bg-100: #0c0c0e;
93
+ --galvyn-bg-200: #111113;
94
+ --galvyn-bg-300: #18181b;
95
+
96
+ /* Surfaces */
97
+ --galvyn-surface-100: #141416;
98
+ --galvyn-surface-200: #1c1c1f;
99
+ --galvyn-surface-300: #232326;
100
+ --galvyn-surface-hover: #2a2a2d;
101
+ --galvyn-surface-active: #35353a;
102
+
103
+ /* Borders */
104
+ --galvyn-border-100: rgba(255, 255, 255, 0.03);
105
+ --galvyn-border-200: rgba(255, 255, 255, 0.06);
106
+ --galvyn-border-300: rgba(255, 255, 255, 0.09);
107
+ --galvyn-border-400: rgba(255, 255, 255, 0.14);
108
+ --galvyn-border-focus: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55% / 0.5);
109
+
110
+ /* Text */
111
+ --galvyn-text-000: #ffffff;
112
+ --galvyn-text-100: #fafafa;
113
+ --galvyn-text-200: #a1a1aa;
114
+ --galvyn-text-300: #71717a;
115
+ --galvyn-text-400: #52525b;
116
+ --galvyn-text-500: #3f3f46;
117
+
118
+ /* Accent (hue-driven) */
119
+ --galvyn-accent-50: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 95% / 0.05);
120
+ --galvyn-accent-100: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 95% / 0.08);
121
+ --galvyn-accent-200: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 90% / 0.12);
122
+ --galvyn-accent-300: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 60%);
123
+ --galvyn-accent-400: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55%);
124
+ --galvyn-accent-500: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50%);
125
+ --galvyn-accent-text: hsl(var(--galvyn-accent-hue) 80% 70%);
126
+
127
+ /* Semantic */
128
+ --galvyn-success: #22c55e;
129
+ --galvyn-success-muted: rgba(34, 197, 94, 0.10);
130
+ --galvyn-warning: #eab308;
131
+ --galvyn-warning-muted: rgba(234, 179, 8, 0.10);
132
+ --galvyn-error: #ef4444;
133
+ --galvyn-error-muted: rgba(239, 68, 68, 0.10);
134
+ --galvyn-info: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55%);
135
+ --galvyn-info-muted: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55% / 0.10);
136
+
137
+ /* Shadows */
138
+ --galvyn-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.4);
139
+ --galvyn-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.5), 0 1px 2px -1px rgb(0 0 0 / 0.5);
140
+ --galvyn-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.5), 0 2px 4px -2px rgb(0 0 0 / 0.5);
141
+ --galvyn-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.5);
142
+ --galvyn-shadow-glow: 0 0 20px -5px hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.15);
143
+ --galvyn-shadow-glow-lg: 0 0 40px -10px hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.2);
144
+
145
+ /* Gradient borders */
146
+ --galvyn-gradient-border-subtle: linear-gradient(180deg, rgba(255,255,255,0.09), rgba(255,255,255,0.03));
147
+ --galvyn-gradient-border-medium: linear-gradient(180deg, rgba(255,255,255,0.14), rgba(255,255,255,0.04));
148
+ --galvyn-gradient-border-strong: linear-gradient(135deg, hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55% / 0.6), rgba(255,255,255,0.06), hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55% / 0.2));
149
+ --galvyn-gradient-border-accent: linear-gradient(135deg, hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 60%), hsl(calc(var(--galvyn-accent-hue) + 40) var(--galvyn-accent-sat) 50%));
150
+ }
151
+
152
+
153
+ /* ─── LIGHT THEME ────────────────────────────────── */
154
+ .light,
155
+ [data-theme="light"] {
156
+ color-scheme: light;
157
+
158
+ --galvyn-bg-000: #ffffff;
159
+ --galvyn-bg-100: #fafafa;
160
+ --galvyn-bg-200: #f4f4f5;
161
+ --galvyn-bg-300: #e4e4e7;
162
+
163
+ --galvyn-surface-100: #ffffff;
164
+ --galvyn-surface-200: #f8f8f9;
165
+ --galvyn-surface-300: #f0f0f2;
166
+ --galvyn-surface-hover: #ededf0;
167
+ --galvyn-surface-active: #e4e4e7;
168
+
169
+ --galvyn-border-100: rgba(0, 0, 0, 0.03);
170
+ --galvyn-border-200: rgba(0, 0, 0, 0.06);
171
+ --galvyn-border-300: rgba(0, 0, 0, 0.09);
172
+ --galvyn-border-400: rgba(0, 0, 0, 0.14);
173
+ --galvyn-border-focus: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.4);
174
+
175
+ --galvyn-text-000: #09090b;
176
+ --galvyn-text-100: #18181b;
177
+ --galvyn-text-200: #52525b;
178
+ --galvyn-text-300: #71717a;
179
+ --galvyn-text-400: #a1a1aa;
180
+ --galvyn-text-500: #d4d4d8;
181
+
182
+ --galvyn-accent-50: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.04);
183
+ --galvyn-accent-100: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.06);
184
+ --galvyn-accent-200: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.10);
185
+ --galvyn-accent-300: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50%);
186
+ --galvyn-accent-400: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 45%);
187
+ --galvyn-accent-500: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 40%);
188
+ --galvyn-accent-text: hsl(var(--galvyn-accent-hue) 80% 40%);
189
+
190
+ --galvyn-success: #16a34a;
191
+ --galvyn-success-muted: rgba(22, 163, 74, 0.08);
192
+ --galvyn-warning: #ca8a04;
193
+ --galvyn-warning-muted: rgba(202, 138, 4, 0.08);
194
+ --galvyn-error: #dc2626;
195
+ --galvyn-error-muted: rgba(220, 38, 38, 0.08);
196
+ --galvyn-info: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50%);
197
+ --galvyn-info-muted: hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.08);
198
+
199
+ --galvyn-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
200
+ --galvyn-shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
201
+ --galvyn-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
202
+ --galvyn-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
203
+ --galvyn-shadow-glow: 0 0 20px -5px hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.1);
204
+ --galvyn-shadow-glow-lg: 0 0 40px -10px hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.15);
205
+
206
+ --galvyn-gradient-border-subtle: linear-gradient(180deg, rgba(0,0,0,0.06), rgba(0,0,0,0.02));
207
+ --galvyn-gradient-border-medium: linear-gradient(180deg, rgba(0,0,0,0.10), rgba(0,0,0,0.03));
208
+ --galvyn-gradient-border-strong: linear-gradient(135deg, hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.4), rgba(0,0,0,0.04), hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 50% / 0.15));
209
+ --galvyn-gradient-border-accent: linear-gradient(135deg, hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55%), hsl(calc(var(--galvyn-accent-hue) + 40) var(--galvyn-accent-sat) 45%));
210
+ }
211
+
212
+
213
+ /* ═══════════════════════════════════════════════════
214
+ UTILITY CLASSES
215
+ ═══════════════════════════════════════════════════ */
216
+
217
+ /* ─── Gradient Border ────────────────────────────── */
218
+ .galvyn-border-gradient {
219
+ position: relative;
220
+ border-radius: var(--galvyn-radius-lg);
221
+ isolation: isolate;
222
+ }
223
+ .galvyn-border-gradient::before {
224
+ content: '';
225
+ position: absolute;
226
+ inset: 0;
227
+ border-radius: inherit;
228
+ padding: 1px;
229
+ background: var(--galvyn-gradient-border-subtle);
230
+ -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
231
+ -webkit-mask-composite: xor;
232
+ mask-composite: exclude;
233
+ pointer-events: none;
234
+ }
235
+ .galvyn-border-gradient-medium::before {
236
+ background: var(--galvyn-gradient-border-medium);
237
+ }
238
+ .galvyn-border-gradient-strong::before {
239
+ background: var(--galvyn-gradient-border-strong);
240
+ }
241
+ .galvyn-border-gradient-accent::before {
242
+ background: var(--galvyn-gradient-border-accent);
243
+ padding: 1.5px;
244
+ }
245
+
246
+ /* ─── Shimmer Border (animated) ──────────────────── */
247
+ @property --galvyn-shimmer-angle {
248
+ syntax: '<angle>';
249
+ initial-value: 0deg;
250
+ inherits: false;
251
+ }
252
+ .galvyn-border-shimmer::before {
253
+ background: conic-gradient(
254
+ from var(--galvyn-shimmer-angle),
255
+ transparent 0%,
256
+ hsl(var(--galvyn-accent-hue) var(--galvyn-accent-sat) 55% / 0.4) 10%,
257
+ transparent 20%
258
+ );
259
+ animation: galvyn-shimmer-spin 3s linear infinite;
260
+ }
261
+ @keyframes galvyn-shimmer-spin {
262
+ to { --galvyn-shimmer-angle: 360deg; }
263
+ }
264
+
265
+ /* ─── Focus Ring ─────────────────────────────────── */
266
+ .galvyn-focus-ring:focus-visible {
267
+ outline: none;
268
+ box-shadow: 0 0 0 2px var(--galvyn-bg-000), 0 0 0 4px var(--galvyn-border-focus);
269
+ }
270
+
271
+ /* ─── Transition Shorthand ───────────────────────── */
272
+ .galvyn-transition {
273
+ transition-property: color, background-color, border-color, box-shadow, opacity, transform;
274
+ transition-duration: var(--galvyn-duration-normal);
275
+ transition-timing-function: var(--galvyn-ease-default);
276
+ }
277
+ .galvyn-transition-fast {
278
+ transition-property: color, background-color, border-color, box-shadow, opacity, transform;
279
+ transition-duration: var(--galvyn-duration-fast);
280
+ transition-timing-function: var(--galvyn-ease-default);
281
+ }
282
+
283
+ /* ─── Animations ─────────────────────────────────── */
284
+ @keyframes galvyn-fade-in {
285
+ from { opacity: 0; transform: translateY(4px); }
286
+ to { opacity: 1; transform: translateY(0); }
287
+ }
288
+ @keyframes galvyn-fade-out {
289
+ from { opacity: 1; transform: translateY(0); }
290
+ to { opacity: 0; transform: translateY(4px); }
291
+ }
292
+ @keyframes galvyn-scale-in {
293
+ from { opacity: 0; transform: scale(0.95); }
294
+ to { opacity: 1; transform: scale(1); }
295
+ }
296
+ @keyframes galvyn-slide-up {
297
+ from { opacity: 0; transform: translateY(8px); }
298
+ to { opacity: 1; transform: translateY(0); }
299
+ }
300
+
301
+ /* ─── Component styles (imported automatically) ── */
302
+ /*
303
+ * GALVYN COMPONENT STYLES
304
+ * Import: @import "@galvyn-io/design/css";
305
+ * These are included in galvyn.css — this file exists
306
+ * for reference if you want to cherry-pick.
307
+ */
308
+
309
+ /* ─── Button ─────────────────────────────────────── */
310
+ .galvyn-btn {
311
+ display: inline-flex;
312
+ align-items: center;
313
+ justify-content: center;
314
+ gap: 6px;
315
+ font-family: var(--galvyn-font-sans);
316
+ font-weight: 500;
317
+ border-radius: var(--galvyn-radius-md);
318
+ cursor: pointer;
319
+ white-space: nowrap;
320
+ user-select: none;
321
+ border: 1px solid transparent;
322
+ }
323
+ .galvyn-btn:active:not(:disabled) { transform: scale(0.97); }
324
+ .galvyn-btn:disabled { opacity: 0.5; cursor: not-allowed; }
325
+
326
+ .galvyn-btn-sm { height: 28px; padding: 0 10px; font-size: 0.75rem; }
327
+ .galvyn-btn-md { height: 34px; padding: 0 14px; font-size: 0.8125rem; }
328
+ .galvyn-btn-lg { height: 40px; padding: 0 18px; font-size: 0.875rem; }
329
+
330
+ .galvyn-btn-default {
331
+ background: var(--galvyn-surface-200);
332
+ border-color: var(--galvyn-border-300);
333
+ color: var(--galvyn-text-100);
334
+ }
335
+ .galvyn-btn-default:hover:not(:disabled) { background: var(--galvyn-surface-hover); }
336
+
337
+ .galvyn-btn-secondary {
338
+ background: transparent;
339
+ border-color: var(--galvyn-border-200);
340
+ color: var(--galvyn-text-200);
341
+ }
342
+ .galvyn-btn-secondary:hover:not(:disabled) { background: var(--galvyn-surface-200); color: var(--galvyn-text-100); }
343
+
344
+ .galvyn-btn-ghost {
345
+ background: transparent;
346
+ color: var(--galvyn-text-200);
347
+ }
348
+ .galvyn-btn-ghost:hover:not(:disabled) { background: var(--galvyn-surface-200); color: var(--galvyn-text-100); }
349
+
350
+ .galvyn-btn-accent {
351
+ background: var(--galvyn-accent-400);
352
+ border-color: var(--galvyn-accent-300);
353
+ color: #fff;
354
+ }
355
+ .galvyn-btn-accent:hover:not(:disabled) { filter: brightness(1.1); }
356
+
357
+ .galvyn-btn-danger {
358
+ background: var(--galvyn-error-muted);
359
+ color: var(--galvyn-error);
360
+ }
361
+ .galvyn-btn-danger:hover:not(:disabled) { filter: brightness(1.15); }
362
+
363
+ .galvyn-btn-icon { display: flex; }
364
+ .galvyn-spinner { animation: galvyn-spin 0.6s linear infinite; }
365
+ @keyframes galvyn-spin { to { transform: rotate(360deg); } }
366
+
367
+
368
+ /* ─── Input ──────────────────────────────────────── */
369
+ .galvyn-input-wrapper {
370
+ display: flex;
371
+ flex-direction: column;
372
+ gap: 5px;
373
+ }
374
+ .galvyn-input-label {
375
+ font-size: 0.75rem;
376
+ font-weight: 500;
377
+ color: var(--galvyn-text-200);
378
+ letter-spacing: 0.02em;
379
+ }
380
+ .galvyn-input-container {
381
+ display: flex;
382
+ align-items: center;
383
+ background: var(--galvyn-surface-100);
384
+ border: 1px solid var(--galvyn-border-300);
385
+ border-radius: var(--galvyn-radius-md);
386
+ overflow: hidden;
387
+ }
388
+ .galvyn-input-error { border-color: var(--galvyn-error); }
389
+ .galvyn-input-icon {
390
+ padding-left: var(--galvyn-space-3);
391
+ color: var(--galvyn-text-400);
392
+ display: flex;
393
+ }
394
+ .galvyn-input {
395
+ flex: 1;
396
+ height: 34px;
397
+ padding: 0 var(--galvyn-space-3);
398
+ background: transparent;
399
+ border: none;
400
+ color: var(--galvyn-text-100);
401
+ font-family: var(--galvyn-font-sans);
402
+ font-size: 0.8125rem;
403
+ outline: none;
404
+ }
405
+ .galvyn-input::placeholder { color: var(--galvyn-text-400); }
406
+ .galvyn-input:focus { border-color: var(--galvyn-accent-400); }
407
+ .galvyn-input-mono { font-family: var(--galvyn-font-mono); font-size: 0.75rem; }
408
+ .galvyn-input-hint { font-size: 0.6875rem; color: var(--galvyn-text-400); }
409
+ .galvyn-input-hint-error { color: var(--galvyn-error); }
410
+
411
+
412
+ /* ─── Badge ──────────────────────────────────────── */
413
+ .galvyn-badge {
414
+ display: inline-flex;
415
+ align-items: center;
416
+ gap: 5px;
417
+ font-family: var(--galvyn-font-sans);
418
+ font-weight: 500;
419
+ border-radius: var(--galvyn-radius-full);
420
+ white-space: nowrap;
421
+ }
422
+ .galvyn-badge-sm { height: 20px; padding: 0 8px; font-size: 0.625rem; }
423
+ .galvyn-badge-md { height: 24px; padding: 0 10px; font-size: 0.75rem; }
424
+
425
+ .galvyn-badge-default { background: var(--galvyn-surface-200); color: var(--galvyn-text-200); border: 1px solid var(--galvyn-border-200); }
426
+ .galvyn-badge-accent { background: var(--galvyn-accent-100); color: var(--galvyn-accent-text); }
427
+ .galvyn-badge-success { background: var(--galvyn-success-muted); color: var(--galvyn-success); }
428
+ .galvyn-badge-warning { background: var(--galvyn-warning-muted); color: var(--galvyn-warning); }
429
+ .galvyn-badge-error { background: var(--galvyn-error-muted); color: var(--galvyn-error); }
430
+ .galvyn-badge-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
431
+
432
+
433
+ /* ─── Card ───────────────────────────────────────── */
434
+ .galvyn-card {
435
+ background: var(--galvyn-surface-100);
436
+ border-radius: var(--galvyn-radius-lg);
437
+ }
438
+ .galvyn-card-pad-sm { padding: var(--galvyn-space-3); }
439
+ .galvyn-card-pad-md { padding: var(--galvyn-space-4); }
440
+ .galvyn-card-pad-lg { padding: var(--galvyn-space-6); }
441
+ .galvyn-card-hover { cursor: pointer; transition: background var(--galvyn-duration-fast) var(--galvyn-ease-default); }
442
+ .galvyn-card-hover:hover { background: var(--galvyn-surface-hover); }
443
+
444
+
445
+ /* ─── Kbd ────────────────────────────────────────── */
446
+ .galvyn-kbd {
447
+ display: inline-flex;
448
+ align-items: center;
449
+ justify-content: center;
450
+ min-width: 20px;
451
+ height: 20px;
452
+ padding: 0 5px;
453
+ background: var(--galvyn-surface-200);
454
+ border: 1px solid var(--galvyn-border-300);
455
+ border-radius: var(--galvyn-radius-sm);
456
+ font-family: var(--galvyn-font-mono);
457
+ font-size: 0.625rem;
458
+ color: var(--galvyn-text-300);
459
+ box-shadow: 0 1px 0 var(--galvyn-border-200);
460
+ }
461
+
462
+
463
+ /* ─── Status Dot ─────────────────────────────────── */
464
+ .galvyn-status {
465
+ display: inline-flex;
466
+ align-items: center;
467
+ gap: 6px;
468
+ }
469
+ .galvyn-status-dot {
470
+ width: 8px;
471
+ height: 8px;
472
+ border-radius: 50%;
473
+ }
474
+ .galvyn-status-dot-online { background: var(--galvyn-success); }
475
+ .galvyn-status-dot-offline { background: var(--galvyn-text-400); }
476
+ .galvyn-status-dot-warning { background: var(--galvyn-warning); }
477
+ .galvyn-status-dot-error { background: var(--galvyn-error); }
478
+ .galvyn-status-label { font-size: 0.75rem; color: var(--galvyn-text-200); }
package/dist/index.cjs ADDED
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ // src/tokens/index.ts
4
+ var GALVYN_HUES = {
5
+ blue: 220,
6
+ teal: 180,
7
+ purple: 270,
8
+ pink: 340,
9
+ green: 150,
10
+ amber: 30
11
+ };
12
+ function galvynAccent(hue) {
13
+ const value = typeof hue === "number" ? hue : GALVYN_HUES[hue];
14
+ return { "--galvyn-accent-hue": value };
15
+ }
16
+ function galvynBorderClass(variant = "subtle") {
17
+ if (variant === "none") return "";
18
+ const base = "galvyn-border-gradient";
19
+ if (variant === "subtle") return base;
20
+ if (variant === "shimmer") return `${base} galvyn-border-shimmer`;
21
+ return `${base} galvyn-border-gradient-${variant}`;
22
+ }
23
+
24
+ exports.GALVYN_HUES = GALVYN_HUES;
25
+ exports.galvynAccent = galvynAccent;
26
+ exports.galvynBorderClass = galvynBorderClass;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Galvyn accent hue presets.
3
+ * Set via: style={{ '--galvyn-accent-hue': GALVYN_HUES.teal }}
4
+ * Or in CSS: :root { --galvyn-accent-hue: 180; }
5
+ */
6
+ declare const GALVYN_HUES: {
7
+ readonly blue: 220;
8
+ readonly teal: 180;
9
+ readonly purple: 270;
10
+ readonly pink: 340;
11
+ readonly green: 150;
12
+ readonly amber: 30;
13
+ };
14
+ type GalvynHue = keyof typeof GALVYN_HUES;
15
+ type GalvynVariant = 'default' | 'secondary' | 'ghost' | 'accent' | 'danger';
16
+ type GalvynSize = 'sm' | 'md' | 'lg';
17
+ type GalvynBorderGradient = 'none' | 'subtle' | 'medium' | 'strong' | 'accent' | 'shimmer';
18
+ type GalvynStatus = 'success' | 'warning' | 'error' | 'info';
19
+ /**
20
+ * Helper to set the accent hue as inline style.
21
+ * Usage: <div style={galvynAccent('teal')}>
22
+ */
23
+ declare function galvynAccent(hue: GalvynHue | number): React.CSSProperties;
24
+ /**
25
+ * Gradient border class helper.
26
+ * Returns the appropriate CSS class string for gradient borders.
27
+ */
28
+ declare function galvynBorderClass(variant?: GalvynBorderGradient): string;
29
+
30
+ export { GALVYN_HUES, type GalvynBorderGradient, type GalvynHue, type GalvynSize, type GalvynStatus, type GalvynVariant, galvynAccent, galvynBorderClass };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Galvyn accent hue presets.
3
+ * Set via: style={{ '--galvyn-accent-hue': GALVYN_HUES.teal }}
4
+ * Or in CSS: :root { --galvyn-accent-hue: 180; }
5
+ */
6
+ declare const GALVYN_HUES: {
7
+ readonly blue: 220;
8
+ readonly teal: 180;
9
+ readonly purple: 270;
10
+ readonly pink: 340;
11
+ readonly green: 150;
12
+ readonly amber: 30;
13
+ };
14
+ type GalvynHue = keyof typeof GALVYN_HUES;
15
+ type GalvynVariant = 'default' | 'secondary' | 'ghost' | 'accent' | 'danger';
16
+ type GalvynSize = 'sm' | 'md' | 'lg';
17
+ type GalvynBorderGradient = 'none' | 'subtle' | 'medium' | 'strong' | 'accent' | 'shimmer';
18
+ type GalvynStatus = 'success' | 'warning' | 'error' | 'info';
19
+ /**
20
+ * Helper to set the accent hue as inline style.
21
+ * Usage: <div style={galvynAccent('teal')}>
22
+ */
23
+ declare function galvynAccent(hue: GalvynHue | number): React.CSSProperties;
24
+ /**
25
+ * Gradient border class helper.
26
+ * Returns the appropriate CSS class string for gradient borders.
27
+ */
28
+ declare function galvynBorderClass(variant?: GalvynBorderGradient): string;
29
+
30
+ export { GALVYN_HUES, type GalvynBorderGradient, type GalvynHue, type GalvynSize, type GalvynStatus, type GalvynVariant, galvynAccent, galvynBorderClass };
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ // src/tokens/index.ts
2
+ var GALVYN_HUES = {
3
+ blue: 220,
4
+ teal: 180,
5
+ purple: 270,
6
+ pink: 340,
7
+ green: 150,
8
+ amber: 30
9
+ };
10
+ function galvynAccent(hue) {
11
+ const value = typeof hue === "number" ? hue : GALVYN_HUES[hue];
12
+ return { "--galvyn-accent-hue": value };
13
+ }
14
+ function galvynBorderClass(variant = "subtle") {
15
+ if (variant === "none") return "";
16
+ const base = "galvyn-border-gradient";
17
+ if (variant === "subtle") return base;
18
+ if (variant === "shimmer") return `${base} galvyn-border-shimmer`;
19
+ return `${base} galvyn-border-gradient-${variant}`;
20
+ }
21
+
22
+ export { GALVYN_HUES, galvynAccent, galvynBorderClass };