@cratis/components 4.10.4 → 4.11.1

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,1624 @@
1
+ @layer cratis-components {
2
+ /* @cratis/components/PivotViewer/styles — requires @cratis/components/styles/base. Areas: Filter, PivotViewer. */
3
+ /* ── ./Filter/FilterPanel.css ─────────────────────────────────────── */
4
+ /* -----------------------------------------------------------------------
5
+ * Standalone FilterPanel styles.
6
+ *
7
+ * These styles are shared by the standalone FilterPanel component and the
8
+ * PivotViewer which embeds it. All class names use the .pv-filter-* prefix
9
+ * so they can coexist with PivotViewer's other .pv-* rules.
10
+ * ----------------------------------------------------------------------- */
11
+
12
+ .pv-filter-panel {
13
+ position: fixed;
14
+ width: min(280px, calc(100% - 2rem));
15
+ max-height: calc(100vh - 6.5rem);
16
+ background: linear-gradient(
17
+ 180deg,
18
+ var(--cratis-surface-card),
19
+ var(--cratis-surface-ground)
20
+ );
21
+ border: 1px solid var(--cratis-surface-border);
22
+ border-radius: 1rem;
23
+ box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
24
+ backdrop-filter: blur(14px);
25
+ overflow: hidden;
26
+ z-index: 12;
27
+ display: flex;
28
+ flex-direction: column;
29
+ }
30
+
31
+ .pv-filter-panel.dragging {
32
+ cursor: grabbing;
33
+ user-select: none;
34
+ }
35
+
36
+ .pv-filter-panel.minimized {
37
+ max-height: none;
38
+ }
39
+
40
+ .pv-filter-panel-header {
41
+ display: flex;
42
+ align-items: center;
43
+ gap: 0.5rem;
44
+ padding: 0.75rem 1rem;
45
+ cursor: grab;
46
+ background: var(--cratis-surface-section);
47
+ border-bottom: 1px solid var(--cratis-surface-border);
48
+ flex-shrink: 0;
49
+ }
50
+
51
+ .pv-filter-panel.dragging .pv-filter-panel-header {
52
+ cursor: grabbing;
53
+ }
54
+
55
+ .pv-filter-panel-header h2 {
56
+ margin: 0;
57
+ font-size: 0.85rem;
58
+ letter-spacing: 0.04em;
59
+ text-transform: uppercase;
60
+ color: var(--cratis-text-color);
61
+ flex: 1;
62
+ pointer-events: none;
63
+ }
64
+
65
+ .pv-minimize-btn,
66
+ .pv-close-btn {
67
+ appearance: none;
68
+ border: none;
69
+ border-radius: 0.4rem;
70
+ width: 1.5rem;
71
+ height: 1.5rem;
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ background: var(--cratis-highlight-bg);
76
+ color: var(--cratis-text-color);
77
+ font-size: 1rem;
78
+ font-weight: 500;
79
+ cursor: pointer;
80
+ transition: background 120ms ease;
81
+ }
82
+
83
+ .pv-minimize-btn:hover,
84
+ .pv-close-btn:hover {
85
+ background: var(--cratis-surface-hover);
86
+ }
87
+
88
+ .pv-close-btn {
89
+ font-size: 1.2rem;
90
+ }
91
+
92
+ .pv-filter-panel-content {
93
+ overflow: hidden;
94
+ max-height: 0;
95
+ opacity: 0;
96
+ padding: 0 1.25rem;
97
+ transition:
98
+ max-height 150ms ease-out,
99
+ opacity 100ms ease-out,
100
+ padding 150ms ease-out;
101
+ }
102
+
103
+ .pv-filter-panel-content.expanded {
104
+ overflow-y: auto;
105
+ flex: 1;
106
+ max-height: 600px;
107
+ opacity: 1;
108
+ padding: 1rem 1.25rem 1.25rem;
109
+ }
110
+
111
+ .pv-search {
112
+ padding-bottom: 1rem;
113
+ }
114
+
115
+ .pv-search input {
116
+ width: 100%;
117
+ padding: 0.65rem 0.85rem;
118
+ border-radius: 0.75rem;
119
+ border: 1px solid var(--cratis-surface-border);
120
+ background: var(--cratis-surface-ground);
121
+ color: inherit;
122
+ font-size: 0.95rem;
123
+ box-shadow: inset 0 1px 0 var(--cratis-surface-border);
124
+ }
125
+
126
+ .pv-search input:focus {
127
+ outline: none;
128
+ border-color: var(--cratis-primary-color);
129
+ box-shadow: var(--cratis-focus-ring);
130
+ }
131
+
132
+ .pv-filter-group-search {
133
+ padding: 0 0 0.5rem 0;
134
+ }
135
+
136
+ .pv-filter-group-search input {
137
+ width: 100%;
138
+ padding: 0.4rem 0.6rem;
139
+ border-radius: 0.5rem;
140
+ border: 1px solid var(--cratis-surface-border);
141
+ background: var(--cratis-surface-ground);
142
+ color: inherit;
143
+ font-size: 0.85rem;
144
+ }
145
+
146
+ .pv-filter-group-search input:focus {
147
+ outline: none;
148
+ border-color: var(--cratis-primary-color);
149
+ box-shadow: var(--cratis-focus-ring);
150
+ }
151
+
152
+ /* Reusable checkbox/radio option list (CheckboxListFilter) */
153
+ .pv-option-list {
154
+ position: relative;
155
+ display: flex;
156
+ flex-direction: column;
157
+ max-height: var(--cratis-filter-option-list-max-height, 14rem);
158
+ overflow-y: auto;
159
+ }
160
+
161
+ /* Off-screen clone of every option, used only to measure whether the real (possibly
162
+ search-filtered) list would overflow the box - see useOptionListOverflow. */
163
+ .pv-option-list-mirror {
164
+ position: absolute;
165
+ inset: 0;
166
+ margin: 0;
167
+ padding: 0;
168
+ list-style: none;
169
+ visibility: hidden;
170
+ pointer-events: none;
171
+ max-height: none;
172
+ overflow: visible;
173
+ }
174
+
175
+ /* Rendered via `content: attr(...)` rather than a DOM text node - see CheckboxListFilter.tsx -
176
+ so a mirror row's label/count can never be found by a text-content query. */
177
+ .pv-option-mirror-label::before {
178
+ content: attr(data-label);
179
+ }
180
+
181
+ .pv-option-list-search {
182
+ position: sticky;
183
+ top: 0;
184
+ z-index: 1;
185
+ background: var(--cratis-surface-overlay);
186
+ }
187
+
188
+ .pv-option-list-empty {
189
+ margin: 0;
190
+ padding: 0.45rem 0.5rem;
191
+ font-size: 0.85rem;
192
+ color: var(--cratis-text-color-secondary);
193
+ }
194
+
195
+ .pv-filter-groups {
196
+ display: flex;
197
+ flex-direction: column;
198
+ gap: 0.85rem;
199
+ }
200
+
201
+ .pv-filter {
202
+ background: var(--cratis-surface-overlay);
203
+ border: 1px solid var(--cratis-surface-border);
204
+ border-radius: 0.85rem;
205
+ padding: 0.75rem 0.85rem;
206
+ transition:
207
+ border-color 180ms ease,
208
+ box-shadow 180ms ease;
209
+ }
210
+
211
+ .pv-filter.expanded {
212
+ border-color: var(--cratis-primary-color);
213
+ box-shadow: 0 15px 38px rgba(0, 0, 0, 0.3);
214
+ }
215
+
216
+ .pv-filter-trigger {
217
+ display: flex;
218
+ width: 100%;
219
+ align-items: center;
220
+ gap: 0.5rem;
221
+ }
222
+
223
+ .pv-filter-toggle {
224
+ appearance: none;
225
+ display: flex;
226
+ flex: 1;
227
+ align-items: center;
228
+ justify-content: space-between;
229
+ min-width: 0;
230
+ background: none;
231
+ border: none;
232
+ color: inherit;
233
+ padding: 0;
234
+ cursor: pointer;
235
+ font-size: 0.82rem;
236
+ font-weight: 600;
237
+ text-transform: uppercase;
238
+ letter-spacing: 0.05em;
239
+ }
240
+
241
+ .pv-filter-label {
242
+ display: flex;
243
+ align-items: center;
244
+ gap: 0.4rem;
245
+ }
246
+
247
+ .pv-filter-trigger-meta {
248
+ display: inline-flex;
249
+ align-items: center;
250
+ gap: 0.5rem;
251
+ }
252
+
253
+ .pv-filter-count {
254
+ display: inline-flex;
255
+ align-items: center;
256
+ justify-content: center;
257
+ min-width: 1.5rem;
258
+ padding: 0.15rem 0.45rem;
259
+ border-radius: 999px;
260
+ background: var(--cratis-highlight-bg);
261
+ color: var(--cratis-text-color);
262
+ font-size: 0.7rem;
263
+ }
264
+
265
+ .pv-filter-clear-header {
266
+ appearance: none;
267
+ flex: 0 0 auto;
268
+ border: none;
269
+ width: 1.5rem;
270
+ height: 1.5rem;
271
+ border-radius: 50%;
272
+ background: var(--cratis-highlight-bg);
273
+ color: var(--cratis-text-color);
274
+ font-size: 1.2rem;
275
+ line-height: 1;
276
+ display: flex;
277
+ align-items: center;
278
+ justify-content: center;
279
+ cursor: pointer;
280
+ transition:
281
+ background 160ms ease,
282
+ transform 120ms ease;
283
+ padding: 0;
284
+ }
285
+
286
+ .pv-filter-clear-header:hover {
287
+ background: var(--cratis-surface-hover);
288
+ transform: scale(1.1);
289
+ }
290
+
291
+ .pv-filter-clear-header:active {
292
+ transform: scale(0.95);
293
+ }
294
+
295
+ .pv-filter-chevron {
296
+ width: 0.65rem;
297
+ height: 0.65rem;
298
+ border-right: 2px solid var(--cratis-text-color);
299
+ border-bottom: 2px solid var(--cratis-text-color);
300
+ transform: rotate(45deg);
301
+ transition: transform 180ms ease;
302
+ }
303
+
304
+ .pv-filter.expanded .pv-filter-chevron {
305
+ transform: rotate(225deg);
306
+ }
307
+
308
+ .pv-filter-content {
309
+ overflow: hidden;
310
+ max-height: 0;
311
+ opacity: 0;
312
+ margin-top: 0;
313
+ padding-top: 0;
314
+ border-top: 1px solid transparent;
315
+ transition:
316
+ max-height 120ms ease-out,
317
+ opacity 80ms ease-out,
318
+ margin-top 120ms ease-out,
319
+ padding-top 120ms ease-out,
320
+ border-color 120ms ease-out;
321
+ }
322
+
323
+ .pv-filter-content.expanded {
324
+ max-height: 350px;
325
+ opacity: 1;
326
+ margin-top: 0.75rem;
327
+ padding-top: 0.75rem;
328
+ border-top-color: var(--cratis-surface-border);
329
+ overflow-y: auto;
330
+ }
331
+
332
+ .pv-filter-content ul {
333
+ list-style: none;
334
+ margin: 0;
335
+ padding: 0;
336
+ display: grid;
337
+ gap: 0.45rem;
338
+ }
339
+
340
+ .pv-filter-content li label {
341
+ display: grid;
342
+ grid-template-columns: auto 1fr auto;
343
+ gap: 0.6rem;
344
+ align-items: center;
345
+ padding: 0.45rem 0.5rem;
346
+ border-radius: 0.55rem;
347
+ border: 1px solid transparent;
348
+ cursor: pointer;
349
+ transition:
350
+ background 160ms ease,
351
+ border-color 160ms ease;
352
+ }
353
+
354
+ .pv-filter-content li label:hover {
355
+ background: var(--cratis-surface-hover);
356
+ }
357
+
358
+ .pv-filter-content input[type='checkbox'],
359
+ .pv-filter-content input[type='radio'] {
360
+ accent-color: var(--cratis-primary-color);
361
+ }
362
+
363
+ .pv-filter-content li label span {
364
+ font-size: 0.85rem;
365
+ }
366
+
367
+ .pv-filter-clear {
368
+ margin-top: 0.75rem;
369
+ appearance: none;
370
+ border: none;
371
+ border-radius: 0.55rem;
372
+ padding: 0.4rem 0.75rem;
373
+ background: var(--cratis-highlight-bg);
374
+ color: var(--cratis-text-color);
375
+ font-size: 0.72rem;
376
+ text-transform: uppercase;
377
+ letter-spacing: 0.08em;
378
+ cursor: pointer;
379
+ }
380
+
381
+ .pv-option-count {
382
+ font-feature-settings: 'tnum';
383
+ font-variant-numeric: tabular-nums;
384
+ color: var(--cratis-text-color-secondary);
385
+ font-size: 0.75rem;
386
+ }
387
+
388
+ /* Filter Dropdown (anchor-positioned panel) */
389
+ .pv-filter-dropdown {
390
+ position: fixed;
391
+ width: min(320px, calc(100vw - 2rem));
392
+ max-height: calc(100vh - 8rem);
393
+ background: linear-gradient(
394
+ 180deg,
395
+ var(--cratis-surface-card),
396
+ var(--cratis-surface-ground)
397
+ );
398
+ border: 1px solid var(--cratis-surface-border);
399
+ border-radius: 0.85rem;
400
+ box-shadow: var(--cratis-shadow-overlay);
401
+ backdrop-filter: blur(16px);
402
+ overflow: hidden;
403
+ z-index: var(--cratis-z-index-filter);
404
+ display: flex;
405
+ flex-direction: column;
406
+ will-change: opacity, transform;
407
+ contain: layout;
408
+ color: var(--cratis-text-color);
409
+ }
410
+
411
+ .pv-filter-dropdown-content {
412
+ padding: 1rem;
413
+ overflow-y: auto;
414
+ flex: 1;
415
+ }
416
+
417
+ /* Range Histogram Filter */
418
+ .pv-range-histogram {
419
+ padding: 0.5rem 0;
420
+ }
421
+
422
+ .pv-histogram-bars {
423
+ display: flex;
424
+ align-items: flex-end;
425
+ gap: 2px;
426
+ height: 80px;
427
+ padding: 0 2px;
428
+ margin-bottom: 0.5rem;
429
+ }
430
+
431
+ .pv-histogram-bar {
432
+ flex: 1;
433
+ min-width: 8px;
434
+ background: var(--cratis-highlight-bg);
435
+ border: none;
436
+ border-radius: 2px 2px 0 0;
437
+ cursor: pointer;
438
+ transition:
439
+ background 160ms ease,
440
+ transform 120ms ease;
441
+ padding: 0;
442
+ }
443
+
444
+ .pv-histogram-bar:hover {
445
+ background: var(--cratis-surface-hover);
446
+ transform: scaleY(1.02);
447
+ }
448
+
449
+ .pv-histogram-bar.in-range {
450
+ background: var(--cratis-primary-color);
451
+ }
452
+
453
+ .pv-histogram-bar.partial {
454
+ background: var(--cratis-highlight-bg);
455
+ }
456
+
457
+ .pv-range-slider {
458
+ position: relative;
459
+ height: 24px;
460
+ margin: 0.5rem 0;
461
+ }
462
+
463
+ .pv-range-track {
464
+ position: absolute;
465
+ top: 50%;
466
+ left: 0;
467
+ right: 0;
468
+ height: 4px;
469
+ background: var(--cratis-surface-border);
470
+ border-radius: 2px;
471
+ transform: translateY(-50%);
472
+ }
473
+
474
+ .pv-range-selection {
475
+ position: absolute;
476
+ top: 50%;
477
+ height: 4px;
478
+ background: var(--cratis-primary-color);
479
+ border-radius: 2px;
480
+ transform: translateY(-50%);
481
+ cursor: grab;
482
+ }
483
+
484
+ .pv-range-selection:active {
485
+ cursor: grabbing;
486
+ }
487
+
488
+ .pv-range-handle {
489
+ position: absolute;
490
+ top: 50%;
491
+ width: 16px;
492
+ height: 16px;
493
+ background: var(--cratis-primary-color);
494
+ border: 2px solid var(--cratis-text-color);
495
+ border-radius: 50%;
496
+ transform: translate(-50%, -50%);
497
+ cursor: ew-resize;
498
+ transition:
499
+ transform 120ms ease,
500
+ box-shadow 120ms ease;
501
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
502
+ }
503
+
504
+ .pv-range-handle:hover {
505
+ transform: translate(-50%, -50%) scale(1.15);
506
+ box-shadow: 0 4px 12px var(--cratis-primary-color);
507
+ }
508
+
509
+ .pv-range-handle:focus-visible {
510
+ outline: 2px solid var(--cratis-primary-color);
511
+ outline-offset: 3px;
512
+ }
513
+
514
+ .pv-range-labels {
515
+ display: flex;
516
+ justify-content: space-between;
517
+ font-size: 0.75rem;
518
+ color: var(--cratis-text-color-secondary);
519
+ font-variant-numeric: tabular-nums;
520
+ }
521
+
522
+ .pv-range-clear {
523
+ margin-top: 0.75rem;
524
+ appearance: none;
525
+ border: none;
526
+ border-radius: 0.55rem;
527
+ padding: 0.4rem 0.75rem;
528
+ background: var(--cratis-highlight-bg);
529
+ color: var(--cratis-text-color);
530
+ font-size: 0.72rem;
531
+ text-transform: uppercase;
532
+ letter-spacing: 0.08em;
533
+ cursor: pointer;
534
+ width: 100%;
535
+ }
536
+
537
+ .pv-range-clear:hover {
538
+ background: var(--cratis-surface-hover);
539
+ }
540
+
541
+ @media (max-width: 900px) {
542
+ .pv-filter-panel {
543
+ width: calc(100% - 2.5rem);
544
+ left: 1.25rem;
545
+ right: 1.25rem;
546
+ top: 1.25rem;
547
+ max-height: calc(100vh - 2.5rem);
548
+ }
549
+ }
550
+
551
+ @media (prefers-reduced-motion: reduce) {
552
+ :where(.pv-filter-panel, .pv-filter-dropdown),
553
+ :where(.pv-filter-panel, .pv-filter-dropdown) * {
554
+ transition: none !important;
555
+ animation: none !important;
556
+ }
557
+ }
558
+
559
+ /* ── ./PivotViewer/PivotViewer.css ─────────────────────────────────────── */
560
+ .pivot-viewer {
561
+ /* The height every toolbar control on the left of the bar shares, so the filter button and
562
+ the item count line up as one group. */
563
+ --pv-toolbar-control-size: 2.25rem;
564
+ position: relative;
565
+ /* CRITICAL: Don't set explicit height - let parent control it via container constraints */
566
+ display: flex;
567
+ flex-direction: column;
568
+ min-height: 0; /* allow children to size without forcing overflow */
569
+ max-height: 100%; /* respect parent height if set */
570
+ width: 100%;
571
+ /* Keep root neutral; move visual background to the viewport so it never exceeds the container */
572
+ background: var(--cratis-surface-ground);
573
+ color: var(--cratis-text-color);
574
+ overflow: hidden;
575
+ font-family:
576
+ 'Inter',
577
+ -apple-system,
578
+ BlinkMacSystemFont,
579
+ 'Segoe UI',
580
+ sans-serif;
581
+ /* Ensure we shrink within flex parent */
582
+ flex: 1 1 0%;
583
+ }
584
+
585
+ .pv-main {
586
+ position: relative;
587
+ display: flex;
588
+ flex-direction: column;
589
+ min-height: 0;
590
+ flex: 1 1 auto; /* grow within pivot-viewer */
591
+ height: auto;
592
+ padding-left: 0;
593
+ overflow: hidden;
594
+ }
595
+
596
+ .pv-toolbar {
597
+ display: flex;
598
+ justify-content: space-between;
599
+ align-items: center;
600
+ padding: 0.75rem 1.75rem;
601
+ border-bottom: 1px solid var(--cratis-surface-border);
602
+ background: var(--cratis-surface-section);
603
+ backdrop-filter: blur(12px);
604
+ position: sticky;
605
+ top: 0;
606
+ z-index: 15;
607
+ flex-shrink: 0;
608
+ min-height: 3.5rem;
609
+ height: 3.5rem;
610
+ overflow: visible;
611
+ }
612
+
613
+ .pv-toolbar-left,
614
+ .pv-toolbar-right {
615
+ display: inline-flex;
616
+ align-items: center;
617
+ gap: 0.75rem;
618
+ flex-shrink: 0;
619
+ }
620
+
621
+ .pv-toolbar-right {
622
+ gap: 1rem;
623
+ }
624
+
625
+ /* A span rather than a heading: the host owns its page's heading levels, and a bare `h1`
626
+ inherited whatever heading size the consuming application had set. */
627
+ .pv-title {
628
+ margin: 0;
629
+ font-size: 1.1rem;
630
+ font-weight: 600;
631
+ line-height: 1.2;
632
+ letter-spacing: -0.01em;
633
+ white-space: nowrap;
634
+ }
635
+
636
+ /* Sized to the filter button beside it, so the two read as one group whether or not a title
637
+ separates them. */
638
+ .pv-count {
639
+ display: inline-flex;
640
+ align-items: center;
641
+ justify-content: center;
642
+ gap: 0.35rem;
643
+ height: var(--pv-toolbar-control-size);
644
+ padding: 0 0.65rem;
645
+ border-radius: 999px;
646
+ background: var(--cratis-highlight-bg);
647
+ font-size: 0.8rem;
648
+ line-height: 1;
649
+ color: var(--cratis-text-color);
650
+ }
651
+
652
+ .pv-filter-button {
653
+ appearance: none;
654
+ border: none;
655
+ border-radius: 999px;
656
+ padding: 0.45rem 1rem;
657
+ background: var(--cratis-highlight-bg);
658
+ color: var(--cratis-text-color);
659
+ font-size: 0.8rem;
660
+ letter-spacing: 0.08em;
661
+ text-transform: uppercase;
662
+ cursor: pointer;
663
+ transition:
664
+ background 180ms ease,
665
+ box-shadow 180ms ease;
666
+ }
667
+
668
+ .pv-filter-button.active,
669
+ .pv-filter-button:hover {
670
+ background: var(--cratis-surface-hover);
671
+ box-shadow: var(--cratis-focus-ring);
672
+ }
673
+
674
+ /* Filter Icon Button */
675
+ .pv-filter-icon-button {
676
+ position: relative;
677
+ appearance: none;
678
+ border: none;
679
+ border-radius: 0.5rem;
680
+ width: var(--pv-toolbar-control-size);
681
+ height: var(--pv-toolbar-control-size);
682
+ display: flex;
683
+ align-items: center;
684
+ justify-content: center;
685
+ background: var(--cratis-highlight-bg);
686
+ color: var(--cratis-text-color);
687
+ cursor: pointer;
688
+ transition:
689
+ background 180ms ease,
690
+ box-shadow 180ms ease;
691
+ }
692
+
693
+ .pv-filter-icon-button:hover {
694
+ background: var(--cratis-surface-hover);
695
+ }
696
+
697
+ .pv-filter-icon-button.active {
698
+ background: var(--cratis-surface-hover);
699
+ box-shadow: var(--cratis-focus-ring);
700
+ }
701
+
702
+ .pv-filter-badge {
703
+ position: absolute;
704
+ top: -4px;
705
+ right: -4px;
706
+ min-width: 1.1rem;
707
+ height: 1.1rem;
708
+ display: flex;
709
+ align-items: center;
710
+ justify-content: center;
711
+ border-radius: 999px;
712
+ background: var(--cratis-action-background);
713
+ color: var(--cratis-action-text);
714
+ font-size: 0.65rem;
715
+ font-weight: 600;
716
+ padding: 0 0.25rem;
717
+ }
718
+
719
+ /* Filter Dropdown */
720
+
721
+ .pv-view-toggle {
722
+ display: inline-flex;
723
+ align-items: center;
724
+ border-radius: 999px;
725
+ background: var(--cratis-surface-section);
726
+ border: 1px solid var(--cratis-surface-border);
727
+ padding: 0.2rem;
728
+ gap: 0.2rem;
729
+ }
730
+
731
+ .pv-view-toggle button {
732
+ appearance: none;
733
+ border: none;
734
+ border-radius: 999px;
735
+ padding: 0.35rem 0.9rem;
736
+ color: var(--cratis-text-color-secondary);
737
+ background: transparent;
738
+ font-size: 0.75rem;
739
+ letter-spacing: 0.06em;
740
+ text-transform: uppercase;
741
+ cursor: pointer;
742
+ transition:
743
+ color 160ms ease,
744
+ background 160ms ease,
745
+ box-shadow 160ms ease;
746
+ }
747
+
748
+ .pv-view-toggle button.active {
749
+ background: var(--cratis-action-background);
750
+ color: var(--cratis-action-text);
751
+ }
752
+
753
+ .pv-zoom-controls {
754
+ display: inline-flex;
755
+ align-items: center;
756
+ gap: 0.5rem;
757
+ background: var(--cratis-surface-section);
758
+ border: 1px solid var(--cratis-surface-border);
759
+ border-radius: 0.6rem;
760
+ padding: 0.25rem 0.5rem;
761
+ }
762
+
763
+ .pv-zoom-controls button {
764
+ appearance: none;
765
+ border: none;
766
+ background: transparent;
767
+ color: var(--cratis-text-color);
768
+ font-size: 1.1rem;
769
+ width: 1.75rem;
770
+ height: 1.75rem;
771
+ border-radius: 0.4rem;
772
+ cursor: pointer;
773
+ display: flex;
774
+ align-items: center;
775
+ justify-content: center;
776
+ transition:
777
+ background 120ms ease,
778
+ color 120ms ease;
779
+ }
780
+
781
+ .pv-zoom-controls button:hover {
782
+ background: var(--cratis-surface-hover);
783
+ color: var(--cratis-text-color);
784
+ }
785
+
786
+ .pv-zoom-controls button:disabled {
787
+ opacity: 0.4;
788
+ cursor: not-allowed;
789
+ }
790
+
791
+ .pv-zoom-slider {
792
+ width: 80px;
793
+ height: 4px;
794
+ appearance: none;
795
+ background: var(--cratis-surface-border);
796
+ border-radius: 2px;
797
+ cursor: pointer;
798
+ }
799
+
800
+ .pv-zoom-slider::-webkit-slider-thumb {
801
+ appearance: none;
802
+ width: 14px;
803
+ height: 14px;
804
+ background: var(--cratis-primary-color);
805
+ border: 2px solid var(--cratis-text-color);
806
+ border-radius: 50%;
807
+ cursor: pointer;
808
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
809
+ transition: transform 120ms ease;
810
+ }
811
+
812
+ .pv-zoom-slider::-webkit-slider-thumb:hover {
813
+ transform: scale(1.15);
814
+ }
815
+
816
+ .pv-zoom-slider::-moz-range-thumb {
817
+ width: 14px;
818
+ height: 14px;
819
+ background: var(--cratis-primary-color);
820
+ border: 2px solid var(--cratis-text-color);
821
+ border-radius: 50%;
822
+ cursor: pointer;
823
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
824
+ }
825
+
826
+ .pv-zoom-controls span {
827
+ font-size: 0.75rem;
828
+ color: var(--cratis-text-color-secondary);
829
+ min-width: 3rem;
830
+ text-align: center;
831
+ font-variant-numeric: tabular-nums;
832
+ cursor: pointer;
833
+ padding: 0.25rem 0.5rem;
834
+ border-radius: 0.4rem;
835
+ transition: background 120ms ease;
836
+ }
837
+
838
+ .pv-zoom-controls span:hover {
839
+ background: var(--cratis-surface-hover);
840
+ }
841
+
842
+ .pv-zoom-level-input {
843
+ width: 3rem;
844
+ font-size: 0.75rem;
845
+ text-align: center;
846
+ background: var(--cratis-surface-ground);
847
+ border: 1px solid var(--cratis-primary-color);
848
+ border-radius: 0.4rem;
849
+ color: var(--cratis-text-color);
850
+ padding: 0.25rem 0.5rem;
851
+ font-variant-numeric: tabular-nums;
852
+ outline: none;
853
+ }
854
+
855
+ .pv-zoom-reset {
856
+ display: flex;
857
+ align-items: center;
858
+ justify-content: center;
859
+ }
860
+
861
+ .pv-dimension-select {
862
+ display: inline-flex;
863
+ align-items: center;
864
+ gap: 0.6rem;
865
+ font-size: 0.9rem;
866
+ color: var(--cratis-text-color-secondary);
867
+ }
868
+
869
+ .pv-dimension-select select {
870
+ background: var(--cratis-surface-ground);
871
+ border: 1px solid var(--cratis-surface-border);
872
+ border-radius: 0.6rem;
873
+ color: inherit;
874
+ font-size: 0.9rem;
875
+ padding: 0.4rem 0.6rem;
876
+ }
877
+
878
+ .pv-groups {
879
+ position: relative;
880
+ flex: 1;
881
+ padding: 1.5rem 1.5rem 0;
882
+ display: flex;
883
+ align-items: flex-end;
884
+ gap: 0.25rem;
885
+ overflow: auto;
886
+ scroll-behavior: smooth;
887
+ cursor: grab;
888
+ user-select: none;
889
+ touch-action: pan-x pan-y;
890
+ /* Hide scrollbars */
891
+ scrollbar-width: none; /* Firefox */
892
+ -ms-overflow-style: none; /* IE and Edge */
893
+ }
894
+
895
+ .pv-groups::-webkit-scrollbar {
896
+ display: none; /* Chrome, Safari, Opera */
897
+ }
898
+
899
+ .pv-groups.pv-panning {
900
+ cursor: grabbing;
901
+ scroll-behavior: auto;
902
+ }
903
+
904
+ .pv-groups:active {
905
+ cursor: grabbing;
906
+ }
907
+
908
+ /* Groups wrapper for grouped mode with axis labels */
909
+ .pv-groups-wrapper {
910
+ display: flex;
911
+ flex-direction: column;
912
+ flex: 1;
913
+ min-height: 0;
914
+ overflow: hidden;
915
+ background: transparent;
916
+ }
917
+
918
+ /* Visual background belongs to the scrollable viewport area so it respects container bounds */
919
+ .pv-viewport {
920
+ background: radial-gradient(
921
+ circle at 25% 20%,
922
+ var(--cratis-primary-500),
923
+ var(--cratis-surface-ground)
924
+ );
925
+ /* Panning stays with the browser, pinching comes to us: without this a touch device
926
+ resolves a two-finger gesture as its own page zoom and never delivers the moves the
927
+ viewer needs to scale the cards. */
928
+ touch-action: pan-x pan-y;
929
+ }
930
+
931
+ .pv-groups-grouped {
932
+ flex: 1;
933
+ padding-bottom: 0;
934
+ }
935
+
936
+ .pv-group {
937
+ display: flex;
938
+ flex-direction: column;
939
+ align-items: stretch;
940
+ background: transparent;
941
+ border-radius: 0;
942
+ border: none;
943
+ padding: 0;
944
+ box-shadow: none;
945
+ flex: 0 0 auto;
946
+ transition: background 180ms ease;
947
+ }
948
+
949
+ /* Grouped mode groups need to align cards to bottom and extend full height */
950
+ .pv-group-grouped {
951
+ justify-content: flex-end;
952
+ position: relative;
953
+ min-height: 100%; /* Ensure full height for hover */
954
+ width: var(--column-width); /* Fixed width even when empty */
955
+ }
956
+
957
+ /* Zebra striping for grouped mode - every other group gets a lighter background */
958
+ .pv-group-grouped:nth-child(even)::before {
959
+ background: rgba(255, 255, 255, 0.03);
960
+ }
961
+
962
+ /* Full-height hover highlight that extends to the top */
963
+ .pv-group-grouped::before {
964
+ content: '';
965
+ position: absolute;
966
+ inset: 0;
967
+ top: -100vh; /* Extend way above to ensure it reaches the top */
968
+ background: transparent;
969
+ transition: background 180ms ease;
970
+ pointer-events: none;
971
+ z-index: 0;
972
+ }
973
+
974
+ .pv-group-grouped:hover::before,
975
+ .pv-group-grouped.highlighted::before {
976
+ background: var(--cratis-surface-hover);
977
+ }
978
+
979
+ /* Zebra striping hover state - combine with stripe background */
980
+ .pv-group-grouped:nth-child(even):hover::before,
981
+ .pv-group-grouped:nth-child(even).highlighted::before {
982
+ background: var(--cratis-surface-hover);
983
+ }
984
+
985
+ .pv-group:hover {
986
+ background: transparent;
987
+ }
988
+
989
+ .pv-group.highlighted {
990
+ background: transparent;
991
+ }
992
+
993
+ .pv-group header {
994
+ display: none;
995
+ }
996
+
997
+ .pv-group header h2 {
998
+ margin: 0;
999
+ font-size: 1rem;
1000
+ letter-spacing: 0.01em;
1001
+ }
1002
+
1003
+ .pv-group header span {
1004
+ font-size: 0.75rem;
1005
+ color: var(--cratis-text-color-secondary);
1006
+ background: var(--cratis-highlight-bg);
1007
+ padding: 0.15rem 0.5rem;
1008
+ border-radius: 999px;
1009
+ }
1010
+
1011
+ .pv-cards {
1012
+ display: grid;
1013
+ gap: calc(4px * var(--zoom-scale, 1));
1014
+ width: var(--column-width, auto);
1015
+ }
1016
+
1017
+ .pv-cards-grouped {
1018
+ /* Grid fills left-to-right with fixed columns */
1019
+ grid-template-columns: repeat(var(--cards-per-row, 5), 1fr);
1020
+ grid-auto-flow: row;
1021
+ width: var(--column-width);
1022
+ }
1023
+
1024
+ .pv-cards-grouped .pv-card {
1025
+ transform: none;
1026
+ }
1027
+
1028
+ /* Empty placeholder cells in grouped grid */
1029
+ .pv-card-placeholder {
1030
+ visibility: hidden;
1031
+ width: var(--card-width);
1032
+ height: var(--card-height);
1033
+ }
1034
+
1035
+ /* Axis labels at bottom of grouped view */
1036
+ .pv-axis-labels {
1037
+ display: flex;
1038
+ align-items: stretch;
1039
+ background: var(--cratis-surface-section);
1040
+ border-top: 1px solid var(--cratis-surface-border);
1041
+ padding: 0.5rem 0; /* padding-left set dynamically from JS; no right padding to prevent skew */
1042
+ gap: 0; /* No extra gap to avoid skew */
1043
+ overflow-x: hidden; /* Disable independent scroll - synced via JS */
1044
+ flex-shrink: 0;
1045
+ }
1046
+
1047
+ .pv-axis-label {
1048
+ display: flex;
1049
+ flex-direction: column;
1050
+ align-items: center;
1051
+ justify-content: center;
1052
+ padding: 0.5rem 0;
1053
+ text-align: center;
1054
+ cursor: pointer;
1055
+ /* Note: opacity transition added later in the file for filter effects */
1056
+ transition:
1057
+ background 180ms ease,
1058
+ border-color 180ms ease;
1059
+ flex: 0 0 auto;
1060
+ border-radius: 0.5rem;
1061
+ border: 2px solid transparent;
1062
+ background: transparent;
1063
+ color: inherit;
1064
+ font: inherit;
1065
+ }
1066
+
1067
+ /* Zebra striping for axis labels - match the grouped columns */
1068
+ .pv-axis-label:nth-child(even) {
1069
+ background: rgba(255, 255, 255, 0.03);
1070
+ }
1071
+
1072
+ .pv-axis-label:hover,
1073
+ .pv-axis-label.highlighted {
1074
+ background: var(--cratis-surface-hover);
1075
+ }
1076
+
1077
+ /* Zebra striping hover/highlight for even labels */
1078
+ .pv-axis-label:nth-child(even):hover,
1079
+ .pv-axis-label:nth-child(even).highlighted {
1080
+ background: var(--cratis-surface-hover);
1081
+ }
1082
+
1083
+ .pv-axis-label.selected {
1084
+ border-color: var(--cratis-primary-color);
1085
+ background: var(--cratis-highlight-bg);
1086
+ }
1087
+
1088
+ .pv-axis-label:focus-visible {
1089
+ outline: none;
1090
+ border-color: var(--cratis-primary-color);
1091
+ box-shadow: var(--cratis-focus-ring);
1092
+ }
1093
+
1094
+ .pv-axis-label-text {
1095
+ font-size: 0.75rem;
1096
+ color: var(--cratis-text-color);
1097
+ font-weight: 500;
1098
+ white-space: nowrap;
1099
+ overflow: hidden;
1100
+ text-overflow: ellipsis;
1101
+ max-width: 100%;
1102
+ }
1103
+
1104
+ .pv-axis-label-count {
1105
+ font-size: 0.65rem;
1106
+ color: var(--cratis-text-color-secondary);
1107
+ margin-top: 0.15rem;
1108
+ font-variant-numeric: tabular-nums;
1109
+ }
1110
+
1111
+ /* Fade and collapse axis labels when switching views */
1112
+ .pivot-viewer .pv-axis-labels {
1113
+ transition:
1114
+ opacity 600ms ease,
1115
+ max-height 600ms ease,
1116
+ padding 600ms ease,
1117
+ border-color 600ms ease;
1118
+ overflow: hidden;
1119
+ }
1120
+ .pivot-viewer .pv-axis-labels.hidden {
1121
+ opacity: 0;
1122
+ max-height: 0;
1123
+ padding-top: 0;
1124
+ padding-bottom: 0;
1125
+ border-top-color: transparent;
1126
+ pointer-events: none;
1127
+ }
1128
+ .pivot-viewer .pv-axis-labels.visible {
1129
+ opacity: 1;
1130
+ max-height: 80px;
1131
+ pointer-events: auto;
1132
+ }
1133
+
1134
+ /* Fade individual axis labels when filtering groups */
1135
+ .pv-axis-label {
1136
+ transition:
1137
+ opacity 600ms ease,
1138
+ background 180ms ease,
1139
+ border-color 180ms ease;
1140
+ }
1141
+
1142
+ .pv-axis-label.filtered-out {
1143
+ opacity: 0.3;
1144
+ }
1145
+
1146
+ .pv-groups.pv-groups-collection {
1147
+ display: flex;
1148
+ flex-wrap: wrap;
1149
+ align-items: flex-start;
1150
+ align-content: flex-start;
1151
+ padding: 1.5rem;
1152
+ gap: calc(8px * var(--zoom-scale, 1));
1153
+ overflow: auto;
1154
+ }
1155
+
1156
+ /* Pause flex reflow during zoom animation for smoother effect */
1157
+ .pv-groups.pv-zooming {
1158
+ pointer-events: none;
1159
+ }
1160
+
1161
+ /* CRITICAL: Freeze collection layout during zoom - prevent any reflow */
1162
+ .pv-groups.pv-groups-collection.pv-zooming {
1163
+ /* Lock the gap to prevent layout shifts */
1164
+ gap: 8px !important;
1165
+ }
1166
+
1167
+ .pv-groups.pv-groups-collection.pv-zooming .pv-card {
1168
+ /* Prevent cards from resizing/reflowing during zoom */
1169
+ flex-shrink: 0 !important;
1170
+ flex-grow: 0 !important;
1171
+ }
1172
+
1173
+ .pv-groups.pv-groups-collection > div,
1174
+ .pv-groups.pv-groups-collection > section {
1175
+ width: auto;
1176
+ }
1177
+
1178
+ .pv-group-collection {
1179
+ display: contents;
1180
+ background: transparent;
1181
+ border: none;
1182
+ padding: 0;
1183
+ box-shadow: none;
1184
+ }
1185
+
1186
+ .pv-group-collection .pv-cards {
1187
+ display: contents;
1188
+ }
1189
+
1190
+ .pv-cards-collection {
1191
+ display: contents;
1192
+ }
1193
+
1194
+ .pv-cards-collection .pv-card {
1195
+ background: linear-gradient(
1196
+ 180deg,
1197
+ var(--cratis-surface-card),
1198
+ var(--cratis-surface-ground)
1199
+ );
1200
+ }
1201
+
1202
+ .pv-card {
1203
+ border: none;
1204
+ text-align: left;
1205
+ padding: 0;
1206
+ background: linear-gradient(
1207
+ 180deg,
1208
+ var(--cratis-surface-card),
1209
+ var(--cratis-surface-ground)
1210
+ );
1211
+ border-radius: 0.85rem;
1212
+ cursor: pointer;
1213
+ color: inherit;
1214
+ border: 1px solid transparent;
1215
+ transition: border-color 160ms ease;
1216
+ }
1217
+
1218
+ .pv-card:focus-visible {
1219
+ outline: none;
1220
+ border-color: var(--cratis-primary-color);
1221
+ box-shadow: var(--cratis-focus-ring);
1222
+ }
1223
+
1224
+ .pv-card.selected {
1225
+ border-color: var(--cratis-primary-color);
1226
+ box-shadow:
1227
+ var(--cratis-focus-ring),
1228
+ 0 8px 20px rgba(0, 0, 0, 0.2);
1229
+ }
1230
+
1231
+ .pv-card-body {
1232
+ padding: calc(0.85rem * var(--zoom-scale, 1)) calc(0.95rem * var(--zoom-scale, 1));
1233
+ font-size: calc(1rem * var(--zoom-scale, 1));
1234
+ overflow: hidden;
1235
+ }
1236
+
1237
+ .pv-card-title {
1238
+ font-size: calc(0.95rem * var(--zoom-scale, 1));
1239
+ font-weight: 600;
1240
+ margin-bottom: calc(0.65rem * var(--zoom-scale, 1));
1241
+ line-height: 1.2;
1242
+ overflow: hidden;
1243
+ text-overflow: ellipsis;
1244
+ white-space: nowrap;
1245
+ }
1246
+
1247
+ .pv-card-row {
1248
+ display: grid;
1249
+ grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
1250
+ gap: calc(0.5rem * var(--zoom-scale, 1));
1251
+ font-size: calc(0.8rem * var(--zoom-scale, 1));
1252
+ color: var(--cratis-text-color);
1253
+ margin-bottom: calc(0.35rem * var(--zoom-scale, 1));
1254
+ line-height: 1.3;
1255
+ }
1256
+
1257
+ .pv-card-row dt {
1258
+ margin: 0;
1259
+ color: var(--cratis-text-color-secondary);
1260
+ font-weight: 500;
1261
+ overflow: hidden;
1262
+ text-overflow: ellipsis;
1263
+ white-space: nowrap;
1264
+ }
1265
+
1266
+ .pv-card-row dd {
1267
+ margin: 0;
1268
+ overflow: hidden;
1269
+ text-overflow: ellipsis;
1270
+ white-space: nowrap;
1271
+ }
1272
+
1273
+ .pv-card-more {
1274
+ margin-top: calc(0.4rem * var(--zoom-scale, 1));
1275
+ color: var(--cratis-text-color-secondary);
1276
+ text-align: right;
1277
+ font-size: calc(0.9rem * var(--zoom-scale, 1));
1278
+ }
1279
+
1280
+ .pv-empty {
1281
+ width: 100%;
1282
+ text-align: center;
1283
+ padding: 3rem;
1284
+ color: var(--cratis-text-color-secondary);
1285
+ font-size: 1.05rem;
1286
+ }
1287
+
1288
+ /* Slide-in detail panel from the right */
1289
+ .pv-detail-panel {
1290
+ position: absolute;
1291
+ top: 0;
1292
+ right: 0;
1293
+ bottom: 0;
1294
+ width: 380px;
1295
+ background: var(--cratis-surface-overlay);
1296
+ border-left: 1px solid var(--cratis-surface-border);
1297
+ display: flex;
1298
+ flex-direction: column;
1299
+ z-index: 14;
1300
+ box-shadow: -8px 0 32px rgba(0, 0, 0, 0.3);
1301
+ }
1302
+
1303
+ .pv-detail-panel header {
1304
+ display: flex;
1305
+ align-items: center;
1306
+ justify-content: space-between;
1307
+ padding: 1rem 1.25rem;
1308
+ border-bottom: 1px solid var(--cratis-surface-border);
1309
+ flex-shrink: 0;
1310
+ }
1311
+
1312
+ .pv-detail-panel header h2 {
1313
+ margin: 0;
1314
+ font-size: 1.1rem;
1315
+ color: var(--cratis-text-color);
1316
+ }
1317
+
1318
+ .pv-detail-panel header p {
1319
+ margin: 0.25rem 0 0;
1320
+ font-size: 0.8rem;
1321
+ color: var(--cratis-text-color-secondary);
1322
+ }
1323
+
1324
+ .pv-detail-panel header button {
1325
+ appearance: none;
1326
+ border: none;
1327
+ background: var(--cratis-surface-hover);
1328
+ color: var(--cratis-text-color);
1329
+ width: 32px;
1330
+ height: 32px;
1331
+ border-radius: 8px;
1332
+ font-size: 1.3rem;
1333
+ cursor: pointer;
1334
+ display: flex;
1335
+ align-items: center;
1336
+ justify-content: center;
1337
+ transition: background 120ms ease;
1338
+ }
1339
+
1340
+ .pv-detail-panel header button:hover {
1341
+ background: var(--cratis-highlight-bg);
1342
+ }
1343
+
1344
+ .pv-detail-panel-content {
1345
+ flex: 1;
1346
+ overflow-y: auto;
1347
+ padding: 1rem 1.25rem 1.5rem;
1348
+ }
1349
+
1350
+ .pv-detail-panel section h3 {
1351
+ margin: 0 0 0.6rem;
1352
+ font-size: 0.85rem;
1353
+ text-transform: uppercase;
1354
+ letter-spacing: 0.06em;
1355
+ color: var(--cratis-text-color-secondary);
1356
+ }
1357
+
1358
+ .pv-detail-panel section + section {
1359
+ margin-top: 1.25rem;
1360
+ }
1361
+
1362
+ .pv-detail-panel dl {
1363
+ display: grid;
1364
+ gap: 0.4rem;
1365
+ }
1366
+
1367
+ .pv-detail-panel dl > div {
1368
+ background: var(--cratis-surface-section);
1369
+ border-radius: 0.6rem;
1370
+ padding: 0.5rem 0.7rem;
1371
+ }
1372
+
1373
+ .pv-detail-panel dt {
1374
+ margin: 0;
1375
+ font-size: 0.7rem;
1376
+ text-transform: uppercase;
1377
+ letter-spacing: 0.08em;
1378
+ color: var(--cratis-text-color-secondary);
1379
+ }
1380
+
1381
+ .pv-detail-panel dd {
1382
+ margin: 0.15rem 0 0;
1383
+ font-size: 0.85rem;
1384
+ color: var(--cratis-text-color);
1385
+ white-space: pre-wrap;
1386
+ word-break: break-word;
1387
+ }
1388
+
1389
+ .pv-detail-panel .pv-detail-meta dl {
1390
+ grid-template-columns: 1fr 1fr;
1391
+ }
1392
+
1393
+ .pv-detail-panel .pv-detail-causation .pv-pill-row {
1394
+ display: flex;
1395
+ flex-wrap: wrap;
1396
+ gap: 0.4rem;
1397
+ }
1398
+
1399
+ /* Legacy overlay styles - hidden */
1400
+ .pv-detail-overlay {
1401
+ display: none;
1402
+ position: fixed;
1403
+ inset: 0;
1404
+ background: var(--cratis-maskbg);
1405
+ backdrop-filter: blur(6px);
1406
+ display: flex;
1407
+ align-items: flex-end;
1408
+ justify-content: center;
1409
+ padding: 2rem;
1410
+ z-index: 20;
1411
+ }
1412
+
1413
+ .pv-detail {
1414
+ width: min(720px, 100%);
1415
+ background: var(--cratis-surface-overlay);
1416
+ border: 1px solid var(--cratis-surface-border);
1417
+ border-radius: 1.25rem;
1418
+ padding: 1.75rem;
1419
+ max-height: min(80vh, 640px);
1420
+ overflow-y: auto;
1421
+ color: var(--cratis-text-color);
1422
+ }
1423
+
1424
+ .pv-detail header {
1425
+ display: flex;
1426
+ align-items: center;
1427
+ justify-content: space-between;
1428
+ margin-bottom: 1.25rem;
1429
+ }
1430
+
1431
+ .pv-detail header h2 {
1432
+ margin: 0;
1433
+ font-size: 1.3rem;
1434
+ }
1435
+
1436
+ .pv-detail header p {
1437
+ margin: 0;
1438
+ font-size: 0.9rem;
1439
+ color: var(--cratis-text-color-secondary);
1440
+ }
1441
+
1442
+ .pv-detail header button {
1443
+ appearance: none;
1444
+ border: none;
1445
+ border-radius: 0.75rem;
1446
+ padding: 0.5rem 1rem;
1447
+ background: var(--cratis-highlight-bg);
1448
+ color: inherit;
1449
+ cursor: pointer;
1450
+ }
1451
+
1452
+ .pv-detail section h3 {
1453
+ margin-top: 0;
1454
+ font-size: 1rem;
1455
+ margin-bottom: 0.75rem;
1456
+ }
1457
+
1458
+ .pv-detail section + section {
1459
+ margin-top: 1.25rem;
1460
+ }
1461
+
1462
+ .pv-detail dl {
1463
+ display: grid;
1464
+ gap: 0.5rem;
1465
+ }
1466
+
1467
+ .pv-detail dl > div {
1468
+ background: var(--cratis-surface-section);
1469
+ border-radius: 0.75rem;
1470
+ padding: 0.55rem 0.75rem;
1471
+ }
1472
+
1473
+ .pv-detail dt {
1474
+ margin: 0;
1475
+ font-size: 0.75rem;
1476
+ text-transform: uppercase;
1477
+ letter-spacing: 0.08em;
1478
+ color: var(--cratis-text-color-secondary);
1479
+ }
1480
+
1481
+ .pv-detail dd {
1482
+ margin: 0.2rem 0 0;
1483
+ font-size: 0.9rem;
1484
+ color: var(--cratis-text-color);
1485
+ white-space: pre-wrap;
1486
+ word-break: break-word;
1487
+ }
1488
+
1489
+ .pv-detail-meta dl {
1490
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
1491
+ }
1492
+
1493
+ .pv-detail-causation .pv-pill-row {
1494
+ display: flex;
1495
+ flex-wrap: wrap;
1496
+ gap: 0.5rem;
1497
+ }
1498
+
1499
+ .pv-pill {
1500
+ display: inline-flex;
1501
+ align-items: center;
1502
+ gap: 0.35rem;
1503
+ padding: 0.35rem 0.65rem;
1504
+ border-radius: 999px;
1505
+ background: var(--cratis-highlight-bg);
1506
+ color: var(--cratis-text-color);
1507
+ font-size: 0.8rem;
1508
+ border: 1px solid var(--cratis-surface-border);
1509
+ }
1510
+
1511
+ /* Range Histogram Filter */
1512
+
1513
+ @media (max-width: 900px) {
1514
+ .pv-toolbar {
1515
+ flex-wrap: wrap;
1516
+ gap: 1rem;
1517
+ /* The base rule uses a fixed single-row height. Once controls wrap,
1518
+ let the toolbar grow so the second row pushes the canvas down. */
1519
+ height: auto;
1520
+ }
1521
+
1522
+ .pv-toolbar-right {
1523
+ flex-wrap: wrap;
1524
+ gap: 1rem;
1525
+ }
1526
+
1527
+ .pv-view-toggle {
1528
+ order: -1;
1529
+ }
1530
+
1531
+ .pv-groups {
1532
+ padding: 1.5rem;
1533
+ }
1534
+ }
1535
+
1536
+ @media (prefers-reduced-motion: reduce) {
1537
+ .pivot-viewer,
1538
+ .pivot-viewer * {
1539
+ scroll-behavior: auto !important;
1540
+ transition: none !important;
1541
+ animation: none !important;
1542
+ }
1543
+ }
1544
+
1545
+ /* ── ./PivotViewer/components/Spinner.css ─────────────────────────────────────── */
1546
+ /* Loading Spinner */
1547
+ .pv-loading {
1548
+ display: flex;
1549
+ align-items: center;
1550
+ justify-content: center;
1551
+ flex: 1;
1552
+ min-height: 400px;
1553
+ }
1554
+
1555
+ .pv-spinner {
1556
+ width: 80px;
1557
+ height: 80px;
1558
+ position: relative;
1559
+ }
1560
+
1561
+ .pv-spinner-ring {
1562
+ position: absolute;
1563
+ inset: 0;
1564
+ border-radius: 50%;
1565
+ border: 4px solid transparent;
1566
+ }
1567
+
1568
+ .pv-spinner-ring:nth-child(1) {
1569
+ border-top-color: var(--cratis-primary-300);
1570
+ animation: spinner-rotate 1.5s linear infinite;
1571
+ }
1572
+
1573
+ .pv-spinner-ring:nth-child(2) {
1574
+ border-right-color: var(--cratis-primary-400);
1575
+ animation: spinner-rotate 1.5s linear infinite;
1576
+ animation-delay: -0.1875s;
1577
+ }
1578
+
1579
+ .pv-spinner-ring:nth-child(3) {
1580
+ border-bottom-color: var(--cratis-primary-500);
1581
+ animation: spinner-rotate 1.5s linear infinite;
1582
+ animation-delay: -0.375s;
1583
+ }
1584
+
1585
+ .pv-spinner-ring:nth-child(4) {
1586
+ border-left-color: var(--cratis-primary-600);
1587
+ animation: spinner-rotate 1.5s linear infinite;
1588
+ animation-delay: -0.5625s;
1589
+ }
1590
+
1591
+ .pv-spinner-ring:nth-child(5) {
1592
+ border-top-color: var(--cratis-primary-400);
1593
+ animation: spinner-rotate 1.5s linear infinite reverse;
1594
+ animation-delay: -0.75s;
1595
+ }
1596
+
1597
+ .pv-spinner-ring:nth-child(6) {
1598
+ border-right-color: var(--cratis-primary-500);
1599
+ animation: spinner-rotate 1.5s linear infinite reverse;
1600
+ animation-delay: -0.9375s;
1601
+ }
1602
+
1603
+ .pv-spinner-ring:nth-child(7) {
1604
+ border-bottom-color: var(--cratis-primary-300);
1605
+ animation: spinner-rotate 1.5s linear infinite reverse;
1606
+ animation-delay: -1.125s;
1607
+ }
1608
+
1609
+ .pv-spinner-ring:nth-child(8) {
1610
+ border-left-color: var(--cratis-primary-600);
1611
+ animation: spinner-rotate 1.5s linear infinite reverse;
1612
+ animation-delay: -1.3125s;
1613
+ }
1614
+
1615
+ @keyframes spinner-rotate {
1616
+ 0% {
1617
+ transform: rotate(0deg);
1618
+ }
1619
+ 100% {
1620
+ transform: rotate(360deg);
1621
+ }
1622
+ }
1623
+
1624
+ }