@goplusvn/core 0.1.4 → 0.1.6

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,585 @@
1
+ /*
2
+ * @goplusvn/core — canonical design tokens (Radix -> shadcn -> Plane semantic).
3
+ *
4
+ * Shared design-system foundation. Apps import it from their Tailwind v4 entry
5
+ * stylesheet AFTER pulling in Tailwind itself, then override brand tokens:
6
+ *
7
+ * @import "tailwindcss";
8
+ * @import "tw-animate-css";
9
+ * @import "@goerp/core/styles/base.css";
10
+ * @source "../node_modules/@goerp/core/src/(asterisk)(asterisk)/(asterisk).tsx";
11
+ * :root { --primary: var(--violet-9); } // re-skin here
12
+ *
13
+ * Brand default is indigo; neutral is slate. Re-skin by overriding
14
+ * --primary / --accent-primary / --ring / --sidebar-* in your app :root.
15
+ */
16
+ @import "./radix-themes.css";
17
+
18
+ @custom-variant dark (&:is(.dark *));
19
+
20
+ @theme inline {
21
+ --color-border: hsl(var(--border));
22
+ --color-input: hsl(var(--input));
23
+ --color-ring: hsl(var(--ring));
24
+ --color-background: hsl(var(--background));
25
+ --color-foreground: hsl(var(--foreground));
26
+
27
+ --color-primary: hsl(var(--primary));
28
+ --color-primary-foreground: hsl(var(--primary-foreground));
29
+
30
+ --color-secondary: hsl(var(--secondary));
31
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
32
+
33
+ --color-destructive: hsl(var(--destructive));
34
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
35
+
36
+ --color-success: hsl(var(--success));
37
+ --color-success-foreground: hsl(var(--success-foreground));
38
+
39
+ --color-muted: hsl(var(--muted));
40
+ --color-muted-foreground: hsl(var(--muted-foreground));
41
+
42
+ --color-accent: hsl(var(--accent));
43
+ --color-accent-foreground: hsl(var(--accent-foreground));
44
+
45
+ --color-popover: hsl(var(--popover));
46
+ --color-popover-foreground: hsl(var(--popover-foreground));
47
+
48
+ --color-card: hsl(var(--card));
49
+ --color-card-foreground: hsl(var(--card-foreground));
50
+
51
+ --color-chart-1: hsl(var(--chart-1));
52
+ --color-chart-2: hsl(var(--chart-2));
53
+ --color-chart-3: hsl(var(--chart-3));
54
+ --color-chart-4: hsl(var(--chart-4));
55
+ --color-chart-5: hsl(var(--chart-5));
56
+
57
+ --color-sidebar: hsl(var(--sidebar-background));
58
+ --color-sidebar-foreground: hsl(var(--sidebar-foreground));
59
+ --color-sidebar-primary: hsl(var(--sidebar-primary));
60
+ --color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
61
+ --color-sidebar-accent: hsl(var(--sidebar-accent));
62
+ --color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
63
+ --color-sidebar-border: hsl(var(--sidebar-border));
64
+ --color-sidebar-ring: hsl(var(--sidebar-ring));
65
+
66
+ /* ── Semantic Tokens (Plane-inspired, usable as Tailwind utilities) ─── */
67
+ /* Usage: bg-layer-2, text-text-secondary, border-border-subtle, etc. */
68
+ --color-accent-primary: hsl(var(--accent-primary));
69
+ --color-accent-primary-hover: hsl(var(--accent-primary-hover));
70
+ --color-accent-primary-active: hsl(var(--accent-primary-active));
71
+ --color-accent-primary-subtle: hsl(var(--accent-primary-subtle));
72
+
73
+ --color-layer-1: hsl(var(--layer-1));
74
+ --color-layer-2: hsl(var(--layer-2));
75
+ --color-layer-2-hover: hsl(var(--layer-2-hover));
76
+ --color-layer-3: hsl(var(--layer-3));
77
+ --color-layer-3-hover: hsl(var(--layer-3-hover));
78
+ --color-layer-disabled: hsl(var(--layer-disabled));
79
+
80
+ --color-text-primary: hsl(var(--text-primary));
81
+ --color-text-secondary: hsl(var(--text-secondary));
82
+ --color-text-tertiary: hsl(var(--text-tertiary));
83
+ --color-text-disabled: hsl(var(--text-disabled));
84
+ --color-text-on-color: hsl(var(--text-on-color));
85
+
86
+ --color-border-subtle: hsl(var(--border-subtle));
87
+ --color-border-default: hsl(var(--border-default));
88
+ --color-border-strong: hsl(var(--border-strong));
89
+
90
+ --color-danger: hsl(var(--danger-primary));
91
+ --color-danger-hover: hsl(var(--danger-primary-hover));
92
+ --color-danger-subtle: hsl(var(--danger-subtle));
93
+ --color-danger-text: hsl(var(--danger-text));
94
+
95
+ --color-warning: hsl(var(--warning-primary));
96
+ --color-warning-subtle: hsl(var(--warning-subtle));
97
+ --color-warning-text: hsl(var(--warning-text));
98
+
99
+ --color-info: hsl(var(--info-primary));
100
+ --color-info-subtle: hsl(var(--info-subtle));
101
+ --color-info-text: hsl(var(--info-text));
102
+
103
+ --color-success-semantic: hsl(var(--success-primary));
104
+ --color-success-subtle: hsl(var(--success-subtle));
105
+ --color-success-text: hsl(var(--success-text));
106
+
107
+ --radius-lg: var(--radius);
108
+ --radius-md: calc(var(--radius) - 2px);
109
+ --radius-sm: calc(var(--radius) - 4px);
110
+
111
+ --animate-accordion-down: accordion-down 0.2s ease-out;
112
+ --animate-accordion-up: accordion-up 0.2s ease-out;
113
+ --animate-collapsible-down: collapsible-down 0.2s ease-out;
114
+ --animate-collapsible-up: collapsible-up 0.2s ease-out;
115
+ --animate-collapsible-right: collapsible-right 0.2s ease-out;
116
+ --animate-collapsible-left: collapsible-left 0.2s ease-out;
117
+
118
+ @keyframes accordion-down {
119
+ from {
120
+ height: 0;
121
+ }
122
+
123
+ to {
124
+ height: var(--radix-accordion-content-height);
125
+ }
126
+ }
127
+
128
+ @keyframes accordion-up {
129
+ from {
130
+ height: var(--radix-accordion-content-height);
131
+ }
132
+
133
+ to {
134
+ height: 0;
135
+ }
136
+ }
137
+
138
+ @keyframes collapsible-down {
139
+ from {
140
+ height: 0;
141
+ }
142
+
143
+ to {
144
+ height: var(--radix-collapsible-content-height);
145
+ }
146
+ }
147
+
148
+ @keyframes collapsible-up {
149
+ from {
150
+ height: var(--radix-collapsible-content-height);
151
+ }
152
+
153
+ to {
154
+ height: 0;
155
+ }
156
+ }
157
+
158
+ @keyframes collapsible-right {
159
+ from {
160
+ width: 0;
161
+ }
162
+
163
+ to {
164
+ width: var(--radix-collapsible-content-width);
165
+ }
166
+ }
167
+
168
+ @keyframes collapsible-left {
169
+ from {
170
+ width: var(--radix-collapsible-content-width);
171
+ }
172
+
173
+ to {
174
+ width: 0;
175
+ }
176
+ }
177
+ }
178
+
179
+ @utility container {
180
+ margin-inline: auto;
181
+ padding-inline: 1rem;
182
+
183
+ @media (width >=--theme(--breakpoint-sm)) {
184
+ max-width: none;
185
+ }
186
+
187
+ @media (width >=1400px) {
188
+ max-width: 1400px;
189
+ }
190
+ }
191
+
192
+ /*
193
+ The default border color has changed to `currentColor` in Tailwind CSS v4,
194
+ so we've added these compatibility styles to make sure everything still
195
+ looks the same as it did with Tailwind CSS v3.
196
+
197
+ If we ever want to remove these styles, we need to add an explicit border
198
+ color utility to any element that depends on these defaults.
199
+ */
200
+ @layer base {
201
+
202
+ *,
203
+ ::after,
204
+ ::before,
205
+ ::backdrop,
206
+ ::file-selector-button {
207
+ border-color: var(--color-border, currentColor);
208
+ }
209
+
210
+ button:not(:disabled),
211
+ [role="button"]:not(:disabled) {
212
+ cursor: pointer;
213
+ }
214
+ }
215
+
216
+ @layer base {
217
+ * {
218
+ @apply border-border outline-ring/50;
219
+ }
220
+
221
+ body {
222
+ @apply bg-background text-foreground;
223
+ }
224
+ }
225
+
226
+ :root {
227
+ /* Neutral: Slate */
228
+ --background: var(--slate-1);
229
+ --foreground: var(--slate-12);
230
+ --card: var(--slate-1);
231
+ --card-foreground: var(--slate-12);
232
+ --popover: var(--slate-1);
233
+ --popover-foreground: var(--slate-12);
234
+
235
+ /* Brand: Indigo */
236
+ --primary: var(--indigo-9);
237
+ --primary-foreground: 0 0% 100%;
238
+ /* White text on indigo-9 is safe */
239
+
240
+ /* Secondary: Slate (lighter) */
241
+ --secondary: var(--slate-3);
242
+ --secondary-foreground: var(--slate-12);
243
+
244
+ /* Muted: Slate (subtle) */
245
+ --muted: var(--slate-2);
246
+ --muted-foreground: var(--slate-11);
247
+
248
+ /* Accent: Slate (hover states) */
249
+ --accent: var(--slate-3);
250
+ --accent-foreground: var(--slate-12);
251
+
252
+ /* Functional Colors */
253
+ --destructive: var(--red-9);
254
+ --destructive-foreground: 0 0% 100%;
255
+
256
+ --success: var(--green-9);
257
+ --success-foreground: 0 0% 100%;
258
+
259
+ /* Borders & Inputs */
260
+ --border: var(--slate-6);
261
+ --input: var(--slate-6);
262
+ --ring: var(--indigo-8);
263
+
264
+ --radius: 0.5rem;
265
+
266
+ /* ══════════════════════════════════════════════════════════════
267
+ * Semantic Design Tokens (Plane-inspired)
268
+ * Usage: bg-[hsl(var(--accent-primary))] or via Tailwind theme
269
+ *
270
+ * These tokens add a SEMANTIC layer on top of Radix Colors,
271
+ * making the intent of each color self-documenting.
272
+ * ══════════════════════════════════════════════════════════════ */
273
+
274
+ /* ── Accent (Brand Actions) ─── */
275
+ --accent-primary: var(--indigo-9);
276
+ --accent-primary-hover: var(--indigo-10);
277
+ --accent-primary-active: var(--indigo-11);
278
+ --accent-primary-subtle: var(--indigo-3);
279
+
280
+ /* ── Layer System (Surface Hierarchy) ─── */
281
+ --layer-1: var(--slate-1);
282
+ /* Page background */
283
+ --layer-2: var(--slate-2);
284
+ /* Card, raised surfaces */
285
+ --layer-2-hover: var(--slate-3);
286
+ --layer-3: var(--slate-3);
287
+ /* Nested surfaces */
288
+ --layer-3-hover: var(--slate-4);
289
+ --layer-disabled: var(--slate-3);
290
+
291
+ /* ── Text Hierarchy ─── */
292
+ --text-primary: var(--slate-12);
293
+ --text-secondary: var(--slate-11);
294
+ --text-tertiary: var(--slate-9);
295
+ --text-disabled: var(--slate-8);
296
+ --text-on-color: 0 0% 100%;
297
+ /* White text on colored backgrounds */
298
+
299
+ /* ── Border Hierarchy ─── */
300
+ --border-subtle: var(--slate-4);
301
+ --border-default: var(--slate-6);
302
+ --border-strong: var(--slate-7);
303
+
304
+ /* ── Status Colors (Functional) ─── */
305
+ --danger-primary: var(--red-9);
306
+ --danger-primary-hover: var(--red-10);
307
+ --danger-subtle: var(--red-3);
308
+ --danger-text: var(--red-11);
309
+
310
+ --warning-primary: var(--orange-9);
311
+ --warning-subtle: var(--orange-3);
312
+ --warning-text: var(--orange-11);
313
+
314
+ --info-primary: var(--blue-9);
315
+ --info-subtle: var(--blue-3);
316
+ --info-text: var(--blue-11);
317
+
318
+ --success-primary: var(--green-9);
319
+ --success-subtle: var(--green-3);
320
+ --success-text: var(--green-11);
321
+
322
+ /* Elevation system */
323
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
324
+ --shadow-md: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
325
+ --shadow-lg: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
326
+ --shadow-xl:
327
+ 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
328
+
329
+ /* Charts */
330
+ --chart-1: var(--indigo-9);
331
+ --chart-2: var(--green-9);
332
+ --chart-3: var(--orange-9);
333
+ --chart-4: var(--blue-9);
334
+ --chart-5: var(--red-9);
335
+
336
+ /* Sidebar - Deep Blue Theme */
337
+ --sidebar-background: 233.9 88.8% 17.5%;
338
+ --sidebar-foreground: 0 0% 100%;
339
+ --sidebar-primary: 234.1 83% 68%;
340
+ --sidebar-primary-foreground: 0 0% 100%;
341
+ --sidebar-accent: 234.1 60% 45%;
342
+ --sidebar-accent-foreground: 0 0% 100%;
343
+ --sidebar-border: 234.1 60% 30%;
344
+ --sidebar-ring: 233.9 88.8% 17.5%;
345
+
346
+ /* Calendar vars */
347
+ --fc-small-font-size: 0.875em;
348
+ --fc-page-bg-color: hsl(var(--border));
349
+ --fc-neutral-bg-color: hsl(var(--border));
350
+ --fc-neutral-text-color: hsl(var(--accent-foreground));
351
+ --fc-border-color: hsl(var(--border));
352
+ --fc-button-text-color: hsl(var(--background));
353
+ --fc-button-bg-color: hsl(var(--primary));
354
+ --fc-button-border-color: hsl(var(--primary));
355
+ --fc-button-hover-bg-color: hsl(var(--primary) / 0.8);
356
+ --fc-button-hover-border-color: hsl(var(--primary));
357
+ --fc-button-active-bg-color: hsl(var(--primary) / 0.8);
358
+ --fc-button-active-border-color: hsl(var(--primary) / 0);
359
+ --fc-event-bg-color: hsl(var(--primary));
360
+ --fc-event-border-color: hsl(var(--primary));
361
+ --fc-event-text-color: hsl(var(--background));
362
+ --fc-event-selected-overlay-color: hsl(var(--muted));
363
+ --fc-more-link-bg-color: hsl(var(--muted));
364
+ --fc-more-link-text-color: inherit;
365
+ --fc-event-resizer-thickness: 8px;
366
+ --fc-event-resizer-dot-total-width: 8px;
367
+ --fc-event-resizer-dot-border-width: var(--radius);
368
+ --fc-non-business-color: rgba(215, 215, 215, 0.3);
369
+ --fc-bg-event-color: hsl(var(--success));
370
+ --fc-bg-event-opacity: 0.3;
371
+ --fc-highlight-color: rgba(188, 232, 241, 0.3);
372
+ --fc-today-bg-color: hsl(var(--primary) / 0.15);
373
+ --fc-now-indicator-color: hsl(var(--destructive));
374
+ }
375
+
376
+ .dark {
377
+ /* Neutral: Slate Dark */
378
+ --background: var(--slate-1);
379
+ --foreground: var(--slate-12);
380
+ --card: var(--slate-2);
381
+ --card-foreground: var(--slate-12);
382
+ --popover: var(--slate-2);
383
+ --popover-foreground: var(--slate-12);
384
+
385
+ /* Brand: Indigo Dark */
386
+ --primary: var(--indigo-9);
387
+ --primary-foreground: 0 0% 100%;
388
+
389
+ /* Secondary */
390
+ --secondary: var(--slate-3);
391
+ --secondary-foreground: var(--slate-12);
392
+
393
+ /* Muted */
394
+ --muted: var(--slate-2);
395
+ --muted-foreground: var(--slate-11);
396
+
397
+ /* Accent */
398
+ --accent: var(--slate-3);
399
+ --accent-foreground: var(--slate-12);
400
+
401
+ /* Functional */
402
+ --destructive: var(--red-9);
403
+ --destructive-foreground: 0 0% 100%;
404
+
405
+ --success: var(--green-9);
406
+ --success-foreground: 0 0% 100%;
407
+
408
+ /* Borders & Inputs */
409
+ --border: var(--slate-6);
410
+ --input: var(--slate-6);
411
+ --ring: var(--indigo-8);
412
+
413
+ /* Charts */
414
+ --chart-1: var(--indigo-9);
415
+ --chart-2: var(--green-9);
416
+ --chart-3: var(--orange-9);
417
+ --chart-4: var(--blue-9);
418
+ --chart-5: var(--red-9);
419
+
420
+ /* Sidebar - Dark Mode Deep Blue */
421
+ --sidebar-background: 234.1 50% 10%;
422
+ /* Very dark blue */
423
+ --sidebar-foreground: 210 40% 98%;
424
+ --sidebar-primary: 234.1 70% 55%;
425
+ --sidebar-primary-foreground: 0 0% 100%;
426
+ --sidebar-accent: 234.1 35% 17%;
427
+ --sidebar-accent-foreground: 210 40% 98%;
428
+ --sidebar-border: 234.1 30% 18%;
429
+ --sidebar-ring: 234.1 70% 50%;
430
+
431
+ /* ── Dark Mode Semantic Tokens ─── */
432
+ --accent-primary: var(--indigo-9);
433
+ --accent-primary-hover: var(--indigo-10);
434
+ --accent-primary-active: var(--indigo-11);
435
+ --accent-primary-subtle: var(--indigo-4);
436
+
437
+ --layer-1: var(--slate-1);
438
+ --layer-2: var(--slate-2);
439
+ --layer-2-hover: var(--slate-3);
440
+ --layer-3: var(--slate-3);
441
+ --layer-3-hover: var(--slate-4);
442
+ --layer-disabled: var(--slate-4);
443
+
444
+ --text-primary: var(--slate-12);
445
+ --text-secondary: var(--slate-11);
446
+ --text-tertiary: var(--slate-9);
447
+ --text-disabled: var(--slate-7);
448
+ --text-on-color: 0 0% 100%;
449
+
450
+ --border-subtle: var(--slate-4);
451
+ --border-default: var(--slate-6);
452
+ --border-strong: var(--slate-8);
453
+
454
+ --danger-primary: var(--red-9);
455
+ --danger-primary-hover: var(--red-10);
456
+ --danger-subtle: var(--red-4);
457
+ --danger-text: var(--red-11);
458
+
459
+ --warning-primary: var(--orange-9);
460
+ --warning-subtle: var(--orange-4);
461
+ --warning-text: var(--orange-11);
462
+
463
+ --info-primary: var(--blue-9);
464
+ --info-subtle: var(--blue-4);
465
+ --info-text: var(--blue-11);
466
+
467
+ --success-primary: var(--green-9);
468
+ --success-subtle: var(--green-4);
469
+ --success-text: var(--green-11);
470
+ }
471
+
472
+ aside.EmojiPickerReact {
473
+ /* Emoji Picker vars */
474
+ --epr-emoji-size: 2rem;
475
+ --epr-emoji-padding: 0.25rem;
476
+ --epr-emoji-gap: 0.5rem;
477
+ --epr-hover-bg-color: hsl(var(--accent));
478
+ --epr-focus-bg-color: hsl(var(--accent));
479
+ --epr-bg-color: hsl(var(--background));
480
+ --epr-reactions-bg-color: hsl(var(--background));
481
+ --epr-highlight-color: hsl(var(--primary));
482
+ --epr-category-icon-active-color: hsl(var(--primary));
483
+ --epr-category-label-bg-color: hsl(var(--background));
484
+ --epr-text-color: hsl(var(--foreground));
485
+ --epr-horizontal-padding: 0.75rem;
486
+ --epr-search-input-bg-color: hsl(var(--muted));
487
+ --epr-search-input-border-radius: var(--radius);
488
+ --epr-search-input-padding: 0 40px;
489
+ --epr-preview-text-size: 0.875rem;
490
+ --epr-header-padding: var(--epr-horizontal-padding) var(--epr-horizontal-padding);
491
+ --epr-picker-border-radius: var(--radius);
492
+ --epr-picker-border-color: hsl(var(--border));
493
+ --epr-skin-tone-outer-border-color: hsl(var(--border));
494
+ }
495
+
496
+ .EmojiPickerReact .epr-btn {
497
+ border-radius: var(--radius);
498
+ }
499
+
500
+ .EmojiPickerReact .epr-btn:focus::before {
501
+ border-radius: var(--radius);
502
+ border-width: 1px;
503
+ }
504
+
505
+ /* Toast notification positioning - responsive */
506
+ /* Desktop: top-right, Mobile: top-center */
507
+ [data-sonner-toaster] {
508
+ top: 1rem !important;
509
+ bottom: auto !important;
510
+ }
511
+
512
+ @media (max-width: 768px) {
513
+ [data-sonner-toaster] {
514
+ left: 50% !important;
515
+ right: auto !important;
516
+ transform: translateX(-50%) !important;
517
+ top: 1rem !important;
518
+ bottom: auto !important;
519
+ }
520
+
521
+ [data-sonner-toast] {
522
+ left: 50% !important;
523
+ right: auto !important;
524
+ transform: translateX(-50%) !important;
525
+ }
526
+ }
527
+
528
+ /* Ensure toasts are always at top */
529
+ [data-sonner-toast] {
530
+ top: 1rem !important;
531
+ bottom: auto !important;
532
+ }
533
+
534
+ /* Custom Scrollbar Utility - Always visible on macOS & Windows */
535
+ @utility custom-scrollbar {
536
+ /* Firefox: always show thin scrollbar */
537
+ scrollbar-width: thin;
538
+ scrollbar-color: #cbd5e1 transparent;
539
+
540
+ /* Webkit (Chrome, Safari, Edge): force scrollbar always visible */
541
+ &::-webkit-scrollbar {
542
+ width: 8px;
543
+ height: 8px;
544
+ -webkit-appearance: none;
545
+ }
546
+
547
+ &::-webkit-scrollbar-track {
548
+ background: hsl(var(--muted) / 0.3);
549
+ border-radius: 4px;
550
+ }
551
+
552
+ &::-webkit-scrollbar-thumb {
553
+ background: #cbd5e1;
554
+ /* slate-300 */
555
+ border-radius: 4px;
556
+ min-height: 40px;
557
+ }
558
+
559
+ &::-webkit-scrollbar-thumb:hover {
560
+ background: #94a3b8;
561
+ /* slate-400 */
562
+ }
563
+
564
+ &::-webkit-scrollbar-corner {
565
+ background: transparent;
566
+ }
567
+ }
568
+
569
+ .dark .custom-scrollbar {
570
+ scrollbar-color: #475569 transparent;
571
+ }
572
+
573
+ .dark .custom-scrollbar::-webkit-scrollbar-track {
574
+ background: hsl(var(--muted) / 0.2);
575
+ }
576
+
577
+ .dark .custom-scrollbar::-webkit-scrollbar-thumb {
578
+ background: #475569;
579
+ /* slate-600 */
580
+ }
581
+
582
+ .dark .custom-scrollbar::-webkit-scrollbar-thumb:hover {
583
+ background: #64748b;
584
+ /* slate-500 */
585
+ }