gavaengine 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,733 @@
1
+ /* ========================================
2
+ GavaEngine CSS
3
+ Import: import "gavaengine/styles"
4
+ ======================================== */
5
+
6
+ /* ========================================
7
+ Article content wrapper - breakout layout
8
+ ======================================== */
9
+ .article-content-wrapper {
10
+ max-width: 1024px;
11
+ margin: 0 auto;
12
+ padding: 0 1rem;
13
+ }
14
+
15
+ /* Article content styles */
16
+ .article-content {
17
+ line-height: 1.8;
18
+ font-size: 1.125rem;
19
+ letter-spacing: -0.003em;
20
+ }
21
+
22
+ /* Drop cap on first paragraph */
23
+ .article-content > p:first-of-type::first-letter {
24
+ font-size: 3.5em;
25
+ float: left;
26
+ line-height: 0.8;
27
+ margin-right: 0.1em;
28
+ margin-top: 0.1em;
29
+ font-weight: 700;
30
+ color: var(--ge-accent, var(--accent, #2563eb));
31
+ }
32
+
33
+ .article-content h2 {
34
+ font-size: 1.75rem;
35
+ font-weight: 700;
36
+ margin-top: 2.5rem;
37
+ margin-bottom: 1rem;
38
+ letter-spacing: -0.02em;
39
+ }
40
+
41
+ .article-content h3 {
42
+ font-size: 1.4rem;
43
+ font-weight: 600;
44
+ margin-top: 2rem;
45
+ margin-bottom: 0.75rem;
46
+ letter-spacing: -0.01em;
47
+ }
48
+
49
+ .article-content p {
50
+ margin-bottom: 1.5rem;
51
+ }
52
+
53
+ .article-content ul,
54
+ .article-content ol {
55
+ margin-bottom: 1.25rem;
56
+ padding-left: 1.5rem;
57
+ }
58
+
59
+ .article-content li {
60
+ margin-bottom: 0.5rem;
61
+ }
62
+
63
+ /* Pull-quote style blockquote */
64
+ .article-content blockquote {
65
+ border-left: 3px solid var(--ge-accent, var(--accent, #2563eb));
66
+ padding: 1.25rem 1.5rem;
67
+ margin: 2.5rem 0;
68
+ font-style: italic;
69
+ background: var(--ge-accent-bg, rgba(37, 99, 235, 0.04));
70
+ border-radius: 0 0.5rem 0.5rem 0;
71
+ font-size: 1.25rem;
72
+ line-height: 1.6;
73
+ position: relative;
74
+ }
75
+
76
+ .article-content blockquote p {
77
+ margin-bottom: 0;
78
+ }
79
+
80
+ .article-content a {
81
+ color: var(--ge-accent, var(--accent, #2563eb));
82
+ text-decoration: underline;
83
+ text-underline-offset: 2px;
84
+ text-decoration-thickness: 1px;
85
+ transition: text-decoration-color 0.2s;
86
+ }
87
+
88
+ .article-content a:hover {
89
+ text-decoration-thickness: 2px;
90
+ }
91
+
92
+ /* Breakout images */
93
+ .article-content img {
94
+ max-width: 100%;
95
+ height: auto;
96
+ border-radius: 0.75rem;
97
+ box-shadow: 0px 24px 36px 0px rgba(0, 0, 0, 0.10);
98
+ }
99
+
100
+ /* Text wrap — public rendering */
101
+ .article-content img[data-text-wrap="left"],
102
+ .article-content img[data-float="left"] {
103
+ float: left;
104
+ margin: 0.25rem 1.5rem 1rem 0;
105
+ }
106
+ .article-content img[data-text-wrap="right"],
107
+ .article-content img[data-float="right"] {
108
+ float: right;
109
+ margin: 0.25rem 0 1rem 1.5rem;
110
+ }
111
+
112
+ .article-content hr {
113
+ border: none;
114
+ text-align: center;
115
+ margin: 3rem 0;
116
+ }
117
+
118
+ .article-content hr::after {
119
+ content: "";
120
+ display: inline-block;
121
+ width: 40px;
122
+ height: 3px;
123
+ background: var(--ge-accent, var(--accent, #2563eb));
124
+ border-radius: 2px;
125
+ }
126
+
127
+ .article-content strong {
128
+ font-weight: 600;
129
+ }
130
+
131
+ /* Figure elements with alignment */
132
+ .article-content .article-figure {
133
+ margin: 1.5rem 0;
134
+ }
135
+
136
+ .article-content .article-figure.align-center {
137
+ clear: both;
138
+ text-align: center;
139
+ }
140
+
141
+ .article-content .article-figure img,
142
+ .article-content .article-figure iframe,
143
+ .article-content .article-figure video {
144
+ display: block;
145
+ margin: 0;
146
+ max-width: 100%;
147
+ border-radius: 0.5rem;
148
+ }
149
+
150
+ .article-content .article-figure.align-center img {
151
+ margin: 0 auto;
152
+ }
153
+
154
+ .article-content .article-figure.align-left {
155
+ float: left;
156
+ margin: 0.5rem 1.5rem 1rem 0;
157
+ max-width: 45%;
158
+ }
159
+
160
+ .article-content .article-figure.align-right {
161
+ float: right;
162
+ margin: 0.5rem 0 1rem 1.5rem;
163
+ max-width: 45%;
164
+ }
165
+
166
+ .article-content .article-figure figcaption {
167
+ font-size: 0.85rem;
168
+ color: var(--ge-muted, var(--muted, #737373));
169
+ font-style: italic;
170
+ margin-top: 0.5rem;
171
+ text-align: center;
172
+ }
173
+
174
+ /* Clear floats */
175
+ .article-content p {
176
+ margin-bottom: 1.25rem;
177
+ }
178
+
179
+ .article-content::after {
180
+ content: "";
181
+ display: table;
182
+ clear: both;
183
+ }
184
+
185
+ /* Video container */
186
+ .article-content .article-video {
187
+ margin: 2rem 0;
188
+ text-align: center;
189
+ }
190
+
191
+ .article-content .article-video iframe,
192
+ .article-content .article-video video {
193
+ max-width: 100%;
194
+ border-radius: 0.5rem;
195
+ box-shadow: 0px 24px 36px 0px rgba(0, 0, 0, 0.10);
196
+ }
197
+
198
+ /* Responsive: stack floated images on mobile */
199
+ @media (max-width: 640px) {
200
+ .article-content .article-figure.align-left,
201
+ .article-content .article-figure.align-right {
202
+ float: none;
203
+ margin: 1.5rem auto;
204
+ max-width: 100%;
205
+ text-align: center;
206
+ }
207
+ }
208
+
209
+ /* ========================================
210
+ TipTap Editor Styles
211
+ ======================================== */
212
+
213
+ /* Placeholder */
214
+ .tiptap p.is-editor-empty:first-child::before {
215
+ content: attr(data-placeholder);
216
+ float: left;
217
+ color: var(--ge-muted-foreground, var(--muted-foreground, #a3a3a3));
218
+ pointer-events: none;
219
+ height: 0;
220
+ font-style: italic;
221
+ }
222
+
223
+ /* YouTube embeds in editor */
224
+ .tiptap div[data-youtube-video] {
225
+ margin: 2rem 0;
226
+ }
227
+
228
+ .tiptap div[data-youtube-video] iframe {
229
+ max-width: 100%;
230
+ border-radius: 0.5rem;
231
+ box-shadow: 0px 24px 36px 0px rgba(0, 0, 0, 0.10);
232
+ }
233
+
234
+ /* ========================================
235
+ Image Node — Word-like (editor)
236
+ ======================================== */
237
+
238
+ .image-node {
239
+ position: relative;
240
+ max-width: 100%;
241
+ line-height: 0;
242
+ cursor: default;
243
+ }
244
+
245
+ .image-node[data-text-wrap="none"] {
246
+ display: block;
247
+ margin: 1.5rem 0;
248
+ }
249
+
250
+ .image-node[data-text-wrap="left"] {
251
+ float: left;
252
+ margin: 0.25rem 1.5rem 1rem 0;
253
+ }
254
+
255
+ .image-node[data-text-wrap="right"] {
256
+ float: right;
257
+ margin: 0.25rem 0 1rem 1.5rem;
258
+ }
259
+
260
+ .image-node__img {
261
+ display: block;
262
+ width: 100%;
263
+ height: auto;
264
+ border-radius: 0.75rem;
265
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.10);
266
+ }
267
+
268
+ .image-node.selected .image-node__img {
269
+ cursor: grab;
270
+ }
271
+
272
+ .image-node.selected .image-node__img:active {
273
+ cursor: grabbing;
274
+ }
275
+
276
+ .image-node.selected {
277
+ outline: 2px solid var(--ge-accent, var(--accent, #2563eb));
278
+ outline-offset: 3px;
279
+ border-radius: 0.75rem;
280
+ z-index: 5;
281
+ }
282
+
283
+ .image-node.resizing {
284
+ user-select: none;
285
+ }
286
+
287
+ /* 4 corner resize handles */
288
+ .image-node__handle {
289
+ position: absolute;
290
+ width: 12px;
291
+ height: 12px;
292
+ background: white;
293
+ border: 2px solid var(--ge-accent, var(--accent, #2563eb));
294
+ border-radius: 50%;
295
+ z-index: 11;
296
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
297
+ }
298
+
299
+ .image-node__handle--nw { top: -6px; left: -6px; cursor: nwse-resize; }
300
+ .image-node__handle--ne { top: -6px; right: -6px; cursor: nesw-resize; }
301
+ .image-node__handle--sw { bottom: -6px; left: -6px; cursor: nesw-resize; }
302
+ .image-node__handle--se { bottom: -6px; right: -6px; cursor: nwse-resize; }
303
+
304
+ .image-node__handle:hover {
305
+ background: var(--ge-accent, var(--accent, #2563eb));
306
+ transform: scale(1.2);
307
+ }
308
+
309
+ /* Floating toolbar below image */
310
+ .image-node__toolbar {
311
+ position: absolute;
312
+ bottom: -48px;
313
+ left: 50%;
314
+ transform: translateX(-50%);
315
+ display: flex;
316
+ align-items: center;
317
+ gap: 2px;
318
+ background: var(--ge-card, var(--card, #ffffff));
319
+ border: 1px solid var(--ge-card-border, var(--card-border, #e5e5e5));
320
+ border-radius: 10px;
321
+ padding: 4px;
322
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
323
+ z-index: 20;
324
+ white-space: nowrap;
325
+ }
326
+
327
+ .image-node__toolbar button {
328
+ display: flex;
329
+ align-items: center;
330
+ justify-content: center;
331
+ width: 32px;
332
+ height: 32px;
333
+ border: none;
334
+ background: transparent;
335
+ border-radius: 6px;
336
+ color: var(--ge-muted, var(--muted, #737373));
337
+ cursor: pointer;
338
+ transition: all 0.15s;
339
+ }
340
+
341
+ .image-node__toolbar button:hover {
342
+ background: var(--ge-card-border, var(--card-border, #e5e5e5));
343
+ color: var(--ge-foreground, var(--foreground, #171717));
344
+ }
345
+
346
+ .image-node__toolbar button.active {
347
+ background: var(--ge-accent, var(--accent, #2563eb));
348
+ color: white;
349
+ }
350
+
351
+ .image-node__toolbar button.delete:hover {
352
+ background: #fef2f2;
353
+ color: #dc2626;
354
+ }
355
+
356
+ .image-node__toolbar-sep {
357
+ width: 1px;
358
+ height: 20px;
359
+ background: var(--ge-card-border, var(--card-border, #e5e5e5));
360
+ margin: 0 2px;
361
+ }
362
+
363
+ /* Drop cursor */
364
+ .ProseMirror .ProseMirror-dropcursor {
365
+ color: var(--ge-accent, var(--accent, #2563eb)) !important;
366
+ border-color: var(--ge-accent, var(--accent, #2563eb)) !important;
367
+ }
368
+
369
+ /* Responsive: stack floated images on mobile */
370
+ @media (max-width: 640px) {
371
+ .image-node[data-text-wrap="left"],
372
+ .image-node[data-text-wrap="right"] {
373
+ float: none !important;
374
+ margin: 1rem 0 !important;
375
+ width: 100% !important;
376
+ }
377
+
378
+ .article-content img[data-text-wrap="left"],
379
+ .article-content img[data-text-wrap="right"],
380
+ .article-content img[data-float="left"],
381
+ .article-content img[data-float="right"] {
382
+ float: none !important;
383
+ margin: 1rem auto !important;
384
+ max-width: 100% !important;
385
+ display: block !important;
386
+ }
387
+ }
388
+
389
+ /* Lists in editor */
390
+ .tiptap ul { list-style: disc; }
391
+ .tiptap ol { list-style: decimal; }
392
+
393
+ /* ========================================
394
+ Tables (editor + public)
395
+ ======================================== */
396
+ .tiptap table,
397
+ .article-content table {
398
+ border-collapse: collapse;
399
+ width: 100%;
400
+ margin: 1.5rem 0;
401
+ overflow: hidden;
402
+ }
403
+
404
+ .tiptap table td,
405
+ .tiptap table th,
406
+ .article-content table td,
407
+ .article-content table th {
408
+ border: 1px solid var(--ge-card-border, var(--card-border, #e5e5e5));
409
+ padding: 0.5rem 0.75rem;
410
+ min-width: 80px;
411
+ vertical-align: top;
412
+ position: relative;
413
+ }
414
+
415
+ .tiptap table th,
416
+ .article-content table th {
417
+ font-weight: 600;
418
+ background: color-mix(in srgb, var(--ge-card-border, var(--card-border, #e5e5e5)) 50%, transparent);
419
+ text-align: left;
420
+ }
421
+
422
+ .tiptap table .selectedCell::after {
423
+ content: "";
424
+ position: absolute;
425
+ inset: 0;
426
+ background: var(--ge-accent, var(--accent, #2563eb));
427
+ opacity: 0.1;
428
+ pointer-events: none;
429
+ }
430
+
431
+ .tiptap .column-resize-handle {
432
+ position: absolute;
433
+ right: -2px;
434
+ top: 0;
435
+ bottom: 0;
436
+ width: 4px;
437
+ background: var(--ge-accent, var(--accent, #2563eb));
438
+ pointer-events: none;
439
+ }
440
+
441
+ .tiptap.resize-cursor {
442
+ cursor: col-resize;
443
+ }
444
+
445
+ /* ========================================
446
+ Code blocks (editor + public)
447
+ ======================================== */
448
+ .tiptap pre,
449
+ .article-content pre {
450
+ background: #1e1e1e;
451
+ color: #d4d4d4;
452
+ padding: 1rem 1.25rem;
453
+ border-radius: 0.5rem;
454
+ overflow-x: auto;
455
+ margin: 1.5rem 0;
456
+ font-family: 'Consolas', 'Fira Code', monospace;
457
+ font-size: 0.9rem;
458
+ line-height: 1.6;
459
+ }
460
+
461
+ .tiptap code,
462
+ .article-content code {
463
+ background: rgba(0, 0, 0, 0.06);
464
+ padding: 0.15em 0.35em;
465
+ border-radius: 0.25rem;
466
+ font-family: 'Consolas', 'Fira Code', monospace;
467
+ font-size: 0.9em;
468
+ }
469
+
470
+ .tiptap pre code,
471
+ .article-content pre code {
472
+ background: none;
473
+ padding: 0;
474
+ font-size: inherit;
475
+ }
476
+
477
+ /* ========================================
478
+ Highlight marks
479
+ ======================================== */
480
+ .tiptap mark,
481
+ .article-content mark {
482
+ border-radius: 0.15em;
483
+ padding: 0.05em 0.15em;
484
+ }
485
+
486
+ /* ========================================
487
+ Strikethrough
488
+ ======================================== */
489
+ .article-content s,
490
+ .article-content del {
491
+ text-decoration: line-through;
492
+ color: var(--ge-muted, var(--muted, #737373));
493
+ }
494
+
495
+ /* ========================================
496
+ YouTube embeds (public)
497
+ ======================================== */
498
+ .article-content .article-video-embed,
499
+ .article-content div[data-youtube-video] {
500
+ margin: 2rem 0;
501
+ }
502
+
503
+ .article-content .article-video-embed iframe,
504
+ .article-content div[data-youtube-video] iframe {
505
+ max-width: 100%;
506
+ border-radius: 0.5rem;
507
+ box-shadow: 0px 24px 36px 0px rgba(0, 0, 0, 0.10);
508
+ }
509
+
510
+ /* ========================================
511
+ Draggable Video NodeView (editor)
512
+ ======================================== */
513
+ .draggable-video-wrapper {
514
+ position: relative;
515
+ margin: 2rem 0;
516
+ }
517
+
518
+ .draggable-video-wrapper iframe {
519
+ max-width: 100%;
520
+ border-radius: 0.5rem;
521
+ box-shadow: 0px 24px 36px 0px rgba(0, 0, 0, 0.10);
522
+ }
523
+
524
+ .draggable-video-wrapper.selected {
525
+ cursor: grab;
526
+ }
527
+
528
+ .draggable-video-wrapper.selected:active {
529
+ cursor: grabbing;
530
+ }
531
+
532
+ .draggable-video-wrapper.selected > iframe,
533
+ .draggable-video-wrapper.selected > video {
534
+ outline: 3px solid var(--ge-accent, var(--accent, #2563eb));
535
+ outline-offset: 2px;
536
+ border-radius: 0.5rem;
537
+ }
538
+
539
+ /* ========================================
540
+ Dashboard animations & micro-interactions
541
+ ======================================== */
542
+
543
+ @keyframes dash-fade-in {
544
+ from { opacity: 0; transform: translateY(8px); }
545
+ to { opacity: 1; transform: translateY(0); }
546
+ }
547
+
548
+ @keyframes dash-scale-in {
549
+ from { opacity: 0; transform: scale(0.96); }
550
+ to { opacity: 1; transform: scale(1); }
551
+ }
552
+
553
+ .dash-animate-in {
554
+ animation: dash-fade-in 0.35s ease-out both;
555
+ }
556
+
557
+ .dash-scale-in {
558
+ animation: dash-scale-in 0.3s ease-out both;
559
+ }
560
+
561
+ .dash-stagger { --i: 0; animation-delay: calc(var(--i) * 60ms); }
562
+
563
+ .dash-card-hover {
564
+ transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
565
+ box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1),
566
+ border-color 0.25s ease;
567
+ }
568
+
569
+ .dash-card-hover:hover {
570
+ transform: translateY(-2px);
571
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
572
+ }
573
+
574
+ .dash-row {
575
+ transition: background-color 0.2s ease, opacity 0.3s ease, transform 0.3s ease;
576
+ }
577
+
578
+ .dash-filter-group {
579
+ position: relative;
580
+ }
581
+
582
+ .dash-filter-indicator {
583
+ position: absolute;
584
+ inset: 4px auto;
585
+ border-radius: 9999px;
586
+ background: var(--ge-accent, var(--accent, #2563eb));
587
+ transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1),
588
+ width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
589
+ z-index: 0;
590
+ }
591
+
592
+ .dash-filter-btn {
593
+ position: relative;
594
+ z-index: 1;
595
+ transition: color 0.2s ease;
596
+ }
597
+
598
+ .dash-search {
599
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
600
+ }
601
+
602
+ .dash-search:focus {
603
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
604
+ }
605
+
606
+ @keyframes dash-pulse {
607
+ 0%, 100% { opacity: 0.4; }
608
+ 50% { opacity: 0.7; }
609
+ }
610
+
611
+ .dash-empty-icon {
612
+ animation: dash-pulse 2s ease-in-out infinite;
613
+ }
614
+
615
+ .dash-media-img {
616
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
617
+ }
618
+
619
+ .group:hover .dash-media-img {
620
+ transform: scale(1.05);
621
+ }
622
+
623
+ .dash-media-overlay {
624
+ transition: opacity 0.25s ease;
625
+ }
626
+
627
+ @keyframes dash-badge-pop {
628
+ 0% { transform: scale(0.8); opacity: 0; }
629
+ 50% { transform: scale(1.05); }
630
+ 100% { transform: scale(1); opacity: 1; }
631
+ }
632
+
633
+ .dash-badge {
634
+ animation: dash-badge-pop 0.3s ease-out both;
635
+ }
636
+
637
+ .dash-stat-value {
638
+ transition: color 0.3s ease;
639
+ }
640
+
641
+ @keyframes dash-bar-grow {
642
+ from { transform: scaleY(0); }
643
+ to { transform: scaleY(1); }
644
+ }
645
+
646
+ .dash-chart-bar {
647
+ transform-origin: bottom;
648
+ animation: dash-bar-grow 0.5s cubic-bezier(0.4, 0, 0.2, 1) both;
649
+ }
650
+
651
+ /* ========================================
652
+ Page exit transition (article -> editor)
653
+ ======================================== */
654
+ html.page-exit-to-editor body {
655
+ overflow: hidden;
656
+ }
657
+
658
+ html.page-exit-to-editor header,
659
+ html.page-exit-to-editor main,
660
+ html.page-exit-to-editor footer {
661
+ transition: opacity 400ms cubic-bezier(0.4, 0, 0.2, 1),
662
+ transform 400ms cubic-bezier(0.4, 0, 0.2, 1),
663
+ filter 400ms cubic-bezier(0.4, 0, 0.2, 1);
664
+ opacity: 0;
665
+ filter: blur(3px);
666
+ }
667
+
668
+ html.page-exit-to-editor header { transform: translateY(-20px); }
669
+ html.page-exit-to-editor main { transform: scale(0.97) translateY(-15px); }
670
+ html.page-exit-to-editor footer { transform: translateY(20px); }
671
+
672
+ /* ========================================
673
+ Splash Screen — Gava Engine
674
+ ======================================== */
675
+ @keyframes splash-appear {
676
+ 0% { opacity: 0; }
677
+ 100% { opacity: 1; }
678
+ }
679
+
680
+ @keyframes splash-word-in {
681
+ 0% { opacity: 0; transform: translateY(8px); }
682
+ 100% { opacity: 1; transform: translateY(0); }
683
+ }
684
+
685
+ @keyframes splash-enter-down {
686
+ from { transform: translateY(-100%); }
687
+ to { transform: translateY(0); }
688
+ }
689
+
690
+ @keyframes splash-enter-up {
691
+ from { transform: translateY(100%); }
692
+ to { transform: translateY(0); }
693
+ }
694
+
695
+ @keyframes splash-exit-up {
696
+ to { transform: translateY(-100%); }
697
+ }
698
+
699
+ @keyframes splash-exit-down {
700
+ to { transform: translateY(100%); }
701
+ }
702
+
703
+ .splash-title {
704
+ font-size: clamp(3.5rem, 12vw, 10rem);
705
+ line-height: 1;
706
+ animation: splash-appear 0.6s ease-out both;
707
+ }
708
+
709
+ .splash-half {
710
+ z-index: 9999;
711
+ }
712
+
713
+ .splash-enter-down {
714
+ animation: splash-enter-down 0.7s cubic-bezier(0.2, 0, 0.3, 1) both;
715
+ }
716
+
717
+ .splash-enter-up {
718
+ animation: splash-enter-up 0.7s cubic-bezier(0.2, 0, 0.3, 1) both;
719
+ }
720
+
721
+ .splash-exit-up {
722
+ animation: splash-exit-up 0.8s cubic-bezier(0.7, 0, 0.3, 1) forwards;
723
+ }
724
+
725
+ .splash-exit-down {
726
+ animation: splash-exit-down 0.8s cubic-bezier(0.7, 0, 0.3, 1) forwards;
727
+ }
728
+
729
+ .splash-word {
730
+ color: var(--ge-muted, var(--muted, #737373));
731
+ opacity: 0;
732
+ animation: splash-word-in 0.5s ease-out forwards;
733
+ }