@pi-unipi/kanboard 0.1.2

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,729 @@
1
+ /* @pi-unipi/kanboard — Styles
2
+ * Premium dark editorial. Warm near-black, serif headings,
3
+ * geometric body, teal accent, amber highlight.
4
+ */
5
+
6
+ /* ===== RESET ===== */
7
+ *, *::before, *::after {
8
+ box-sizing: border-box;
9
+ margin: 0;
10
+ padding: 0;
11
+ }
12
+
13
+ html {
14
+ -webkit-font-smoothing: antialiased;
15
+ -moz-osx-font-smoothing: grayscale;
16
+ }
17
+
18
+ /* ===== VISUALLY HIDDEN ===== */
19
+ .visually-hidden {
20
+ position: absolute;
21
+ width: 1px;
22
+ height: 1px;
23
+ padding: 0;
24
+ margin: -1px;
25
+ overflow: hidden;
26
+ clip: rect(0, 0, 0, 0);
27
+ white-space: nowrap;
28
+ border: 0;
29
+ }
30
+
31
+ /* ===== COLOR TOKENS ===== */
32
+ :root {
33
+ /* Brand */
34
+ --hue-brand: 175;
35
+ --hue-warn: 45;
36
+
37
+ /* Surfaces — warm-tinted neutrals toward brand hue */
38
+ --bg-root: oklch(0.13 0.008 70);
39
+ --bg-elevated: oklch(0.155 0.01 70);
40
+ --bg-hover: oklch(0.185 0.012 70);
41
+ --bg-subtle: oklch(0.21 0.015 70);
42
+
43
+ /* Borders */
44
+ --border-faint: oklch(0.22 0.015 70);
45
+ --border-soft: oklch(0.28 0.018 70);
46
+ --border-medium: oklch(0.35 0.02 70);
47
+
48
+ /* Text — WCAG AA contrast on dark bg */
49
+ --text-primary: oklch(0.90 0.005 80);
50
+ --text-secondary: oklch(0.72 0.01 80);
51
+ --text-tertiary: oklch(0.70 0.012 80);
52
+ --text-dim: oklch(0.60 0.01 80);
53
+
54
+ /* Accents */
55
+ --accent-primary: oklch(0.72 0.12 175);
56
+ --accent-primary-faint: oklch(0.72 0.12 175 / 0.08);
57
+ --accent-secondary: oklch(0.72 0.14 55);
58
+ --accent-secondary-faint: oklch(0.72 0.14 55 / 0.08);
59
+
60
+ /* Semantic */
61
+ --green: oklch(0.70 0.16 150);
62
+ --green-faint: oklch(0.70 0.16 150 / 0.10);
63
+ --yellow: oklch(0.72 0.14 80);
64
+ --yellow-faint: oklch(0.72 0.14 80 / 0.10);
65
+ --red: oklch(0.65 0.18 25);
66
+ --red-faint: oklch(0.65 0.18 25 / 0.10);
67
+ --warning-border: oklch(0.72 0.14 80 / 0.15);
68
+
69
+ /* Radii */
70
+ --radius-sm: 3px;
71
+ --radius-md: 6px;
72
+ --radius-lg: 10px;
73
+
74
+ /* Transitions */
75
+ --transition-fast: 0.12s cubic-bezier(0.4, 0, 0.2, 1);
76
+ --transition-medium: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
77
+ }
78
+
79
+ /* ===== SPACING SCALE (semantic) ===== */
80
+ :root {
81
+ --space-micro: 2px;
82
+ --space-xs: 4px;
83
+ --space-sm: 8px;
84
+ --space-md: 12px;
85
+ --space-lg: 16px;
86
+ --space-xl: 24px;
87
+ --space-2xl: 32px;
88
+ --space-3xl: 48px;
89
+ --space-4xl: 64px;
90
+ --space-5xl: 96px;
91
+ }
92
+
93
+ /* ===== TYPOGRAPHY ===== */
94
+ :root {
95
+ --font-display: "Bodoni Moda", "Times New Roman", Georgia, serif;
96
+ --font-body: "Onest", system-ui, -apple-system, sans-serif;
97
+ --font-mono: "JetBrains Mono", "SF Mono", "Liberation Mono", monospace;
98
+ }
99
+
100
+ body {
101
+ font-family: var(--font-body);
102
+ font-weight: 400;
103
+ font-size: 15px;
104
+ background: var(--bg-root);
105
+ color: var(--text-primary);
106
+ line-height: 1.6;
107
+ min-height: 100vh;
108
+ display: flex;
109
+ flex-direction: column;
110
+ letter-spacing: -0.01em;
111
+ }
112
+
113
+ /* Display type — fluid clamp for page titles */
114
+ .page-title {
115
+ font-family: var(--font-display);
116
+ font-weight: 500;
117
+ font-size: clamp(1.5rem, 3vw, 2.5rem);
118
+ line-height: 1.15;
119
+ letter-spacing: -0.025em;
120
+ color: var(--text-primary);
121
+ font-style: italic;
122
+ }
123
+
124
+ .page-subtitle {
125
+ font-family: var(--font-body);
126
+ font-weight: 400;
127
+ font-size: 0.85rem;
128
+ color: var(--text-tertiary);
129
+ line-height: 1.4;
130
+ margin-top: var(--space-sm);
131
+ letter-spacing: 0.01em;
132
+ }
133
+
134
+ .section-title {
135
+ font-family: var(--font-display);
136
+ font-weight: 500;
137
+ font-size: 1.125rem;
138
+ line-height: 1.3;
139
+ letter-spacing: -0.01em;
140
+ color: var(--text-primary);
141
+ }
142
+
143
+ .card-title {
144
+ font-family: var(--font-body);
145
+ font-weight: 600;
146
+ font-size: 0.95rem;
147
+ line-height: 1.35;
148
+ color: var(--text-primary);
149
+ letter-spacing: -0.005em;
150
+ }
151
+
152
+ /* ===== NAVIGATION ===== */
153
+ .navbar {
154
+ display: flex;
155
+ align-items: center;
156
+ justify-content: space-between;
157
+ padding: var(--space-md) var(--space-xl);
158
+ background: transparent;
159
+ border-bottom: 1px solid var(--border-faint);
160
+ }
161
+
162
+ .nav-brand {
163
+ display: flex;
164
+ align-items: center;
165
+ gap: var(--space-md);
166
+ }
167
+
168
+ .nav-icon {
169
+ font-size: 1.25rem;
170
+ opacity: 0.7;
171
+ }
172
+
173
+ .nav-title {
174
+ font-family: var(--font-display);
175
+ font-weight: 500;
176
+ font-size: 1.1rem;
177
+ font-style: italic;
178
+ letter-spacing: -0.02em;
179
+ color: var(--text-primary);
180
+ }
181
+
182
+ .nav-links {
183
+ display: flex;
184
+ gap: var(--space-xs);
185
+ }
186
+
187
+ .nav-link {
188
+ font-family: var(--font-body);
189
+ font-weight: 500;
190
+ font-size: 0.8rem;
191
+ color: var(--text-tertiary);
192
+ text-decoration: none;
193
+ padding: var(--space-sm) var(--space-lg);
194
+ border-radius: var(--radius-md);
195
+ transition: color var(--transition-fast), background var(--transition-fast);
196
+ text-transform: uppercase;
197
+ letter-spacing: 0.06em;
198
+ }
199
+
200
+ .nav-link:hover {
201
+ color: var(--text-secondary);
202
+ background: var(--bg-hover);
203
+ }
204
+
205
+ .nav-link.active {
206
+ color: var(--accent-primary);
207
+ background: var(--accent-primary-faint);
208
+ }
209
+
210
+ /* ===== CONTAINER ===== */
211
+ .container {
212
+ flex: 1;
213
+ max-width: 1100px;
214
+ margin: 0 auto;
215
+ padding: var(--space-2xl) var(--space-xl);
216
+ width: 100%;
217
+ }
218
+
219
+ /* ===== FOOTER ===== */
220
+ .footer {
221
+ text-align: center;
222
+ padding: var(--space-xl);
223
+ color: var(--text-dim);
224
+ font-size: 0.7rem;
225
+ font-weight: 500;
226
+ letter-spacing: 0.08em;
227
+ text-transform: uppercase;
228
+ border-top: 1px solid var(--border-faint);
229
+ }
230
+
231
+ /* ===== PAGE HEADER ===== */
232
+ .page-header {
233
+ margin-bottom: var(--space-3xl);
234
+ padding-bottom: var(--space-xl);
235
+ border-bottom: 1px solid var(--border-faint);
236
+ }
237
+
238
+ .page-header .progress-bar {
239
+ margin-top: var(--space-lg);
240
+ max-width: 360px;
241
+ }
242
+
243
+ .page-header-stat {
244
+ font-family: var(--font-mono);
245
+ font-size: 0.7rem;
246
+ font-weight: 500;
247
+ color: var(--text-dim);
248
+ letter-spacing: 0.05em;
249
+ margin-top: var(--space-sm);
250
+ }
251
+
252
+ /* ===== CARDS ===== */
253
+ .card {
254
+ background: var(--bg-elevated);
255
+ border: 1px solid var(--border-faint);
256
+ border-radius: var(--radius-lg);
257
+ padding: var(--space-lg) var(--space-xl);
258
+ transition: border-color var(--transition-medium);
259
+ cursor: pointer;
260
+ will-change: border-color;
261
+ }
262
+
263
+ .card:hover {
264
+ border-color: var(--border-soft);
265
+ }
266
+
267
+ .card-header {
268
+ display: flex;
269
+ align-items: center;
270
+ justify-content: space-between;
271
+ margin-bottom: var(--space-md);
272
+ gap: var(--space-md);
273
+ border: none;
274
+ background: transparent;
275
+ color: inherit;
276
+ font: inherit;
277
+ text-align: left;
278
+ width: 100%;
279
+ cursor: pointer;
280
+ padding: 0;
281
+ }
282
+
283
+ .card-header:focus-visible {
284
+ outline: 2px solid var(--accent-primary);
285
+ outline-offset: 2px;
286
+ border-radius: var(--radius-md);
287
+ }
288
+
289
+ .card-header-inner {
290
+ display: flex;
291
+ align-items: center;
292
+ gap: var(--space-sm);
293
+ min-width: 0;
294
+ }
295
+
296
+ .card-meta {
297
+ display: flex;
298
+ align-items: center;
299
+ gap: var(--space-md);
300
+ }
301
+
302
+ .card-footer {
303
+ margin-top: var(--space-md);
304
+ padding-top: var(--space-md);
305
+ border-top: 1px solid var(--border-faint);
306
+ }
307
+
308
+ .card .checklist {
309
+ margin-top: var(--space-md);
310
+ }
311
+
312
+ /* ===== PROGRESS BAR ===== */
313
+ .progress-bar {
314
+ --progress: 0%;
315
+ height: 3px;
316
+ background: var(--border-faint);
317
+ border-radius: 2px;
318
+ overflow: hidden;
319
+ position: relative;
320
+ }
321
+
322
+ .progress-fill {
323
+ height: 100%;
324
+ transform-origin: left;
325
+ transform: scaleX(clamp(0, calc(var(--progress) / 100%), 1));
326
+ background: var(--green);
327
+ border-radius: 2px;
328
+ transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
329
+ will-change: transform;
330
+ position: relative;
331
+ }
332
+
333
+ .progress-fill::after {
334
+ content: "";
335
+ position: absolute;
336
+ right: 0;
337
+ top: 0;
338
+ bottom: 0;
339
+ width: 8px;
340
+ background: linear-gradient(to right, transparent, var(--green));
341
+ opacity: 0;
342
+ transition: opacity 0.3s;
343
+ }
344
+
345
+ .card:hover .progress-fill::after {
346
+ opacity: 0.5;
347
+ }
348
+
349
+ .progress-text {
350
+ font-family: var(--font-mono);
351
+ font-size: 0.7rem;
352
+ font-weight: 500;
353
+ color: var(--text-dim);
354
+ letter-spacing: 0.03em;
355
+ }
356
+
357
+ .section-header .progress-bar {
358
+ width: 80px;
359
+ flex-shrink: 0;
360
+ }
361
+
362
+ /* ===== CHECKLIST ===== */
363
+ .checklist {
364
+ list-style: none;
365
+ display: flex;
366
+ flex-direction: column;
367
+ gap: var(--space-xs);
368
+ }
369
+
370
+ .checklist-item {
371
+ display: flex;
372
+ align-items: flex-start;
373
+ gap: var(--space-md);
374
+ padding: var(--space-md) var(--space-lg);
375
+ border-radius: var(--radius-md);
376
+ transition: background var(--transition-fast);
377
+ }
378
+
379
+ .checklist-item:hover {
380
+ background: var(--bg-hover);
381
+ }
382
+
383
+ .checklist-status {
384
+ flex-shrink: 0;
385
+ width: 1.25rem;
386
+ height: 1.25rem;
387
+ display: flex;
388
+ align-items: center;
389
+ justify-content: center;
390
+ font-size: 0.7rem;
391
+ margin-top: 0.125rem;
392
+ border-radius: var(--radius-sm);
393
+ }
394
+
395
+ .checklist-status.done {
396
+ color: var(--green);
397
+ background: var(--green-faint);
398
+ }
399
+
400
+ .checklist-status.in-progress {
401
+ color: var(--yellow);
402
+ background: var(--yellow-faint);
403
+ }
404
+
405
+ .checklist-status.todo {
406
+ color: var(--text-dim);
407
+ background: var(--bg-subtle);
408
+ }
409
+
410
+ .checklist-status.reviewed {
411
+ color: var(--accent-secondary);
412
+ background: var(--accent-secondary-faint);
413
+ }
414
+
415
+ .checklist-text {
416
+ flex: 1;
417
+ font-size: 0.88rem;
418
+ line-height: 1.5;
419
+ color: var(--text-secondary);
420
+ max-width: 68ch;
421
+ }
422
+
423
+ .checklist-text.done {
424
+ text-decoration: line-through;
425
+ color: var(--text-dim);
426
+ text-decoration-color: var(--text-dim);
427
+ text-decoration-thickness: 1px;
428
+ }
429
+
430
+ /* ===== STATUS BADGE ===== */
431
+ .badge {
432
+ display: inline-flex;
433
+ align-items: center;
434
+ gap: var(--space-xs);
435
+ padding: var(--space-micro) var(--space-sm);
436
+ border-radius: var(--radius-sm);
437
+ font-family: var(--font-mono);
438
+ font-size: 0.68rem;
439
+ font-weight: 500;
440
+ letter-spacing: 0.05em;
441
+ text-transform: uppercase;
442
+ white-space: nowrap;
443
+ }
444
+
445
+ .badge-done {
446
+ background: var(--green-faint);
447
+ color: var(--green);
448
+ }
449
+
450
+ .badge-in-progress {
451
+ background: var(--yellow-faint);
452
+ color: var(--yellow);
453
+ }
454
+
455
+ .badge-todo {
456
+ background: var(--bg-subtle);
457
+ color: var(--text-dim);
458
+ }
459
+
460
+ .badge-reviewed {
461
+ background: var(--accent-secondary-faint);
462
+ color: var(--accent-secondary);
463
+ }
464
+
465
+ /* ===== COPY BUTTON ===== */
466
+ .copy-btn {
467
+ display: inline-flex;
468
+ align-items: center;
469
+ gap: var(--space-xs);
470
+ padding: var(--space-sm) var(--space-md);
471
+ background: transparent;
472
+ border: 1px solid var(--border-soft);
473
+ border-radius: var(--radius-md);
474
+ color: var(--text-tertiary);
475
+ font-family: var(--font-mono);
476
+ font-size: 0.7rem;
477
+ font-weight: 500;
478
+ cursor: pointer;
479
+ transition: all var(--transition-fast);
480
+ letter-spacing: 0.02em;
481
+ min-height: 44px;
482
+ min-width: 44px;
483
+ }
484
+
485
+ .copy-btn:hover {
486
+ color: var(--text-primary);
487
+ border-color: var(--accent-primary);
488
+ background: var(--accent-primary-faint);
489
+ }
490
+
491
+ .copy-btn.copied {
492
+ color: var(--green);
493
+ border-color: var(--green);
494
+ background: var(--green-faint);
495
+ }
496
+
497
+ .copy-btn.copied span {
498
+ font-size: 0.65rem;
499
+ }
500
+
501
+ /* ===== COLLAPSIBLE SECTIONS ===== */
502
+ .section {
503
+ margin-bottom: var(--space-2xl);
504
+ }
505
+
506
+ .section-header {
507
+ display: flex;
508
+ align-items: center;
509
+ gap: var(--space-md);
510
+ padding: var(--space-lg) var(--space-xl);
511
+ background: var(--bg-elevated);
512
+ border: 1px solid var(--border-faint);
513
+ border-radius: var(--radius-lg);
514
+ cursor: pointer;
515
+ user-select: none;
516
+ transition: background var(--transition-fast), border-color var(--transition-fast);
517
+ position: relative;
518
+ font: inherit;
519
+ color: inherit;
520
+ text-align: left;
521
+ width: 100%;
522
+ }
523
+
524
+ .section-header:focus-visible {
525
+ outline: 2px solid var(--accent-primary);
526
+ outline-offset: 2px;
527
+ }
528
+
529
+ .section-header::before {
530
+ content: "";
531
+ position: absolute;
532
+ left: 0;
533
+ top: var(--space-lg);
534
+ bottom: var(--space-lg);
535
+ width: 1px;
536
+ background: var(--border-soft);
537
+ }
538
+
539
+ .section-header:hover {
540
+ background: var(--bg-hover);
541
+ border-color: var(--border-soft);
542
+ }
543
+
544
+ .section-toggle {
545
+ font-size: 0.6rem;
546
+ color: var(--text-dim);
547
+ transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
548
+ margin-left: var(--space-xs);
549
+ flex-shrink: 0;
550
+ }
551
+
552
+ .section-header[aria-expanded="true"] .section-toggle {
553
+ transform: rotate(90deg);
554
+ }
555
+
556
+ .section-title-wrap {
557
+ display: flex;
558
+ align-items: center;
559
+ gap: var(--space-md);
560
+ flex: 1;
561
+ min-width: 0;
562
+ }
563
+
564
+ .section-count {
565
+ font-family: var(--font-mono);
566
+ font-size: 0.7rem;
567
+ color: var(--text-dim);
568
+ letter-spacing: 0.03em;
569
+ flex-shrink: 0;
570
+ }
571
+
572
+ .section-content {
573
+ padding: var(--space-lg) var(--space-xl) var(--space-xl);
574
+ border: 1px solid var(--border-faint);
575
+ border-top: none;
576
+ border-radius: 0 0 var(--radius-lg) var(--radius-lg);
577
+ margin-top: -1px;
578
+ will-change: transform, opacity;
579
+ }
580
+
581
+ /* ===== FILTER CONTROLS ===== */
582
+ .filters {
583
+ display: flex;
584
+ gap: var(--space-md);
585
+ margin-bottom: var(--space-2xl);
586
+ padding-bottom: var(--space-xl);
587
+ border-bottom: 1px solid var(--border-faint);
588
+ flex-wrap: wrap;
589
+ }
590
+
591
+ .filter-btn {
592
+ padding: var(--space-sm) var(--space-lg);
593
+ background: transparent;
594
+ border: none;
595
+ border-bottom: 2px solid transparent;
596
+ color: var(--text-tertiary);
597
+ font-family: var(--font-body);
598
+ font-size: 0.8rem;
599
+ font-weight: 500;
600
+ cursor: pointer;
601
+ transition: all var(--transition-fast);
602
+ letter-spacing: 0.02em;
603
+ }
604
+
605
+ .filter-btn:hover {
606
+ color: var(--text-secondary);
607
+ }
608
+
609
+ .filter-btn.active {
610
+ color: var(--accent-primary);
611
+ border-bottom-color: var(--accent-primary);
612
+ }
613
+
614
+ /* ===== GRID LAYOUTS ===== */
615
+ .card-grid {
616
+ display: grid;
617
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
618
+ gap: var(--space-lg);
619
+ }
620
+
621
+ /* ===== EMPTY STATE ===== */
622
+ .empty-state {
623
+ text-align: center;
624
+ padding: var(--space-4xl) var(--space-xl);
625
+ color: var(--text-dim);
626
+ }
627
+
628
+ .empty-state-icon {
629
+ font-size: 2.5rem;
630
+ margin-bottom: var(--space-lg);
631
+ opacity: 0.4;
632
+ }
633
+
634
+ .empty-state-text {
635
+ font-size: 0.9rem;
636
+ font-weight: 400;
637
+ letter-spacing: 0.01em;
638
+ }
639
+
640
+ /* ===== WARNING LIST ===== */
641
+ .warnings {
642
+ margin-top: var(--space-md);
643
+ padding: var(--space-md) var(--space-lg);
644
+ background: var(--yellow-faint);
645
+ border-radius: var(--radius-md);
646
+ border: 1px solid var(--warning-border);
647
+ }
648
+
649
+ .warning-item {
650
+ font-family: var(--font-mono);
651
+ font-size: 0.72rem;
652
+ color: var(--yellow);
653
+ line-height: 1.6;
654
+ }
655
+
656
+ .warning-item::before {
657
+ content: "⚠ ";
658
+ opacity: 0.8;
659
+ }
660
+
661
+ /* ===== SECTION METRIC ===== */
662
+ .section-stat {
663
+ display: flex;
664
+ align-items: center;
665
+ gap: var(--space-md);
666
+ }
667
+
668
+ /* ===== DOC TYPE ICON ===== */
669
+ .doc-type-icon {
670
+ font-size: 1rem;
671
+ flex-shrink: 0;
672
+ opacity: 0.85;
673
+ }
674
+
675
+ /* ===== RESPONSIVE ===== */
676
+ @media (max-width: 640px) {
677
+ .navbar {
678
+ flex-direction: column;
679
+ gap: var(--space-sm);
680
+ padding: var(--space-md) var(--space-lg);
681
+ }
682
+
683
+ .container {
684
+ padding: var(--space-xl) var(--space-lg);
685
+ }
686
+
687
+ .card-grid {
688
+ grid-template-columns: 1fr;
689
+ gap: var(--space-md);
690
+ }
691
+
692
+ .section-header {
693
+ flex-wrap: wrap;
694
+ gap: var(--space-sm);
695
+ }
696
+
697
+ .section-stat {
698
+ width: 100%;
699
+ }
700
+
701
+ .filters {
702
+ gap: var(--space-xs);
703
+ }
704
+
705
+ .filter-btn {
706
+ padding-left: var(--space-sm);
707
+ padding-right: var(--space-sm);
708
+ font-size: 0.75rem;
709
+ }
710
+
711
+ .page-header {
712
+ margin-bottom: var(--space-2xl);
713
+ }
714
+ }
715
+
716
+ /* ===== REDUCED MOTION ===== */
717
+ @media (prefers-reduced-motion: reduce) {
718
+ *,
719
+ *::before,
720
+ *::after {
721
+ animation-duration: 0.01ms !important;
722
+ animation-iteration-count: 1 !important;
723
+ transition-duration: 0.01ms !important;
724
+ }
725
+
726
+ .progress-fill {
727
+ transition: none;
728
+ }
729
+ }