@capillaryjs/capillary-viz 1.0.0-alpha.1 → 1.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.
@@ -30,6 +30,7 @@
30
30
  align-items: stretch;
31
31
  min-inline-size: 0;
32
32
  min-block-size: 0;
33
+ gap: calc(var(--_cap-island-flow, 0) * var(--island-gap, 0px));
33
34
  }
34
35
 
35
36
  .cap-layout-horizontal {
@@ -51,11 +52,55 @@
51
52
  }
52
53
 
53
54
  .cap-scroll {
55
+ /* Move the clip into the surrounding gutter without moving the
56
+ * content. The inherited allowance is owned by the parent layout,
57
+ * so local gaps and nested scrollports do not add extra spacing. */
58
+ --_cap-scroll-gutter: calc(var(--_cap-island-flow, 0) * var(--_cap-island-gutter, 0px));
59
+ margin: calc(-1 * var(--_cap-scroll-gutter));
60
+ padding: var(--_cap-scroll-gutter);
54
61
  overflow: auto;
55
62
  min-inline-size: 0;
56
63
  min-block-size: 0;
57
64
  }
58
65
 
66
+ /* The mode crosses wrappers; each layout resolves its own public gap.
67
+ * Only the first enabled scope contributes a perimeter inset. */
68
+ .cap-island-layout {
69
+ --_cap-island-flow: 1;
70
+ --_cap-island-margin: 0px;
71
+ --_cap-island-separator-background: transparent;
72
+ box-sizing: border-box;
73
+ padding: var(--_cap-island-outer-inset, var(--island-inset, 0px));
74
+ gap: calc(var(--_cap-island-flow, 0) * var(--island-gap, 0px));
75
+ }
76
+
77
+ .cap-island-layout > * {
78
+ --_cap-island-outer-inset: 0px;
79
+ }
80
+
81
+ .cap-layout-horizontal > *,
82
+ .cap-layout-vertical > *,
83
+ .cap-island-layout > * {
84
+ --_cap-island-gutter: calc(var(--_cap-island-flow, 0) * var(--island-gap, 0px) / 2);
85
+ }
86
+
87
+ .cap-island-layout.cap-scroll {
88
+ padding: calc(var(--_cap-island-outer-inset, var(--island-inset, 0px))
89
+ + var(--_cap-scroll-gutter));
90
+ }
91
+
92
+ .cap-island-layout-off {
93
+ --_cap-island-flow: 0;
94
+ --_cap-island-margin: initial;
95
+ --_cap-island-separator-background: initial;
96
+ }
97
+
98
+ .cap-island-layout-off > *,
99
+ .island > * {
100
+ --_cap-island-outer-inset: initial;
101
+ --_cap-island-gutter: 0px;
102
+ }
103
+
59
104
  .colored {
60
105
  --colored-base-bg:
61
106
  linear-gradient(
@@ -73,10 +118,12 @@
73
118
 
74
119
  .app-footer.island,
75
120
  .island {
121
+ --_cap-island-flow: 0;
122
+ --_cap-island-separator-background: initial;
76
123
  box-sizing: border-box;
77
124
  min-width: 0;
78
125
  min-height: 0;
79
- margin: var(--island-margin);
126
+ margin: var(--_cap-island-margin, var(--island-margin));
80
127
  padding: var(--island-padding);
81
128
  background: var(--island-background);
82
129
  border: var(--island-border);
@@ -86,13 +133,13 @@
86
133
 
87
134
  .cap-fill-horizontal.island,
88
135
  .cap-fill-horizontal .island {
89
- max-width: calc(100% - (2 * var(--island-margin)));
136
+ max-width: calc(100% - (2 * var(--_cap-island-margin, var(--island-margin))));
90
137
  overflow-x: auto;
91
138
  }
92
139
 
93
140
  .cap-fill-vertical.island,
94
141
  .cap-fill-vertical .island {
95
- max-height: calc(100% - (2 * var(--island-margin)));
142
+ max-height: calc(100% - (2 * var(--_cap-island-margin, var(--island-margin))));
96
143
  overflow-y: auto;
97
144
  }
98
145
 
@@ -136,6 +183,33 @@ cap-blockgraph {
136
183
  overflow: auto;
137
184
  }
138
185
 
186
+ cap-blockgraph > cap-blockskeleton {
187
+ display: flex;
188
+ flex: 1;
189
+ gap: var(--viz-space, 0.7rem);
190
+ min-block-size: 24rem;
191
+ }
192
+
193
+ cap-blockgraph cap-blockskeletoncolumn {
194
+ display: flex;
195
+ flex: 1;
196
+ flex-direction: column;
197
+ gap: var(--viz-space, 0.7rem);
198
+ }
199
+
200
+ cap-blockgraph cap-blockskeletoncolumn:nth-child(2) {
201
+ flex: 2;
202
+ }
203
+
204
+ cap-blockgraph cap-blockskeletoncolumn > cap-placeholder {
205
+ flex: 1;
206
+ block-size: auto;
207
+ }
208
+
209
+ cap-blockgraph cap-blockskeletoncolumn:nth-child(odd) > cap-placeholder:first-child {
210
+ flex: 2;
211
+ }
212
+
139
213
  cap-blockgraph cap-blocks,
140
214
  cap-blockgraph cap-blockgroup {
141
215
  display: flex;
@@ -179,9 +253,8 @@ cap-blockgraph {
179
253
  inset-block-start: 0;
180
254
  inset-inline-start: 0;
181
255
  box-sizing: border-box;
182
- display: grid;
183
- grid-template-columns: minmax(0, 1fr) auto;
184
- grid-template-areas: "label count";
256
+ display: flex;
257
+ flex-flow: row nowrap;
185
258
  align-items: center;
186
259
  gap: 0 0.35rem;
187
260
  width: 100%;
@@ -205,9 +278,9 @@ cap-blockgraph {
205
278
  }
206
279
 
207
280
  cap-blockgraph cap-blocklabel > cap-blockname {
208
- grid-area: label;
209
- display: grid;
210
- grid-template-columns: auto minmax(0, 1fr);
281
+ display: flex;
282
+ flex: 1 1 auto;
283
+ flex-flow: row nowrap;
211
284
  align-items: baseline;
212
285
  gap: 0.2rem;
213
286
  min-width: 0;
@@ -216,6 +289,7 @@ cap-blockgraph {
216
289
  }
217
290
 
218
291
  cap-blockgraph cap-blockname > small {
292
+ flex: 0 1 auto;
219
293
  overflow: hidden;
220
294
  font-size: 0.68rem;
221
295
  opacity: 0.82;
@@ -224,6 +298,7 @@ cap-blockgraph {
224
298
  }
225
299
 
226
300
  cap-blockgraph cap-blockname > strong {
301
+ flex: 1 1 auto;
227
302
  min-width: 0;
228
303
  overflow: hidden;
229
304
  text-overflow: ellipsis;
@@ -231,7 +306,7 @@ cap-blockgraph {
231
306
  }
232
307
 
233
308
  cap-blockgraph cap-blocklabel > data {
234
- grid-area: count;
309
+ flex: 0 0 auto;
235
310
  align-self: center;
236
311
  font-weight: 750;
237
312
  }
@@ -262,19 +337,34 @@ cap-blockgraph {
262
337
  }
263
338
  }
264
339
 
340
+ cap-button,
341
+ cap-checkbox {
342
+ --_cap-control-row-min: var(--_cap-control-compact-min,
343
+ max(var(--control-min-height, 2em), var(--control-row-min-height, 0px)));
344
+ min-height: calc(var(--_cap-control-row-min)
345
+ + 2 * var(--control-row-padding-block, .25em));
346
+ padding-block: var(--control-row-padding-block, .25em);
347
+ box-sizing: border-box;
348
+ font-family: inherit;
349
+ font-size: var(--ui-font-size);
350
+ line-height: 1.2;
351
+ }
352
+
265
353
  cap-button > button {
266
- min-height: var(--control-min-height, 2rem);
267
- padding: var(--space-xs) var(--space-sm);
354
+ display: inline-flex;
355
+ align-items: center;
356
+ justify-content: center;
357
+ min-height: var(--control-min-height, 2em);
358
+ margin: 0;
359
+ padding: var(--ui-control-padding);
268
360
  color: var(--button-color);
269
361
  background: var(--button-background);
270
362
  border: var(--button-border);
271
- border-radius: var(--radius-md);
363
+ border-radius: var(--ui-border-radius);
272
364
  box-shadow: var(--button-shadow);
273
365
  box-sizing: border-box;
274
366
  cursor: default;
275
- font-family: inherit;
276
- font-size: var(--ui-font-size);
277
- line-height: calc(var(--ui-font-size) + var(--ui-padding) + var(--ui-padding));
367
+ font: inherit;
278
368
  user-select: none;
279
369
  white-space: nowrap;
280
370
  }
@@ -283,6 +373,8 @@ cap-button > button {
283
373
  display: inline-flex;
284
374
  position: relative;
285
375
  flex-flow: row wrap;
376
+ align-items: center;
377
+ align-content: center;
286
378
  }
287
379
 
288
380
  cap-button > button:hover:not(:disabled, [aria-disabled="true"]) {
@@ -301,24 +393,27 @@ cap-button > button {
301
393
  box-shadow: var(--focus-ring);
302
394
  }
303
395
 
304
- cap-button > button:disabled,
305
- cap-button > button[aria-disabled="true"] {
396
+ cap-button > button:disabled:not([aria-busy="true"]),
397
+ cap-button > button[aria-disabled="true"]:not([aria-busy="true"]) {
306
398
  color: var(--input-color-disabled);
307
399
  background: var(--button-background-disabled);
308
- border: var(--button-border-disabled);
400
+ border-color: var(--button-border-disabled);
309
401
  cursor: not-allowed;
310
402
  pointer-events: none;
311
403
  }
312
404
 
313
405
  cap-button > button[aria-busy="true"]:not([aria-invalid="true"]) {
314
- background: var(--working-background-image), var(--button-background-disabled);
406
+ /* Busy is unavailable for activation, but remains a normal button
407
+ * surface with the loading texture layered on top. */
408
+ background: var(--working-background-image), var(--button-background);
315
409
  background-repeat: repeat, no-repeat;
316
410
  background-size: 2rem 2rem, 100% 100%;
317
411
  animation: cap-working-progress .55s linear infinite;
318
412
  }
319
413
 
320
414
  cap-button > button[aria-invalid="true"] {
321
- border-color: var(--error-color);
415
+ border-color: var(--error-control-border);
416
+ box-shadow: var(--error-control-shadow);
322
417
  }
323
418
 
324
419
  @media (prefers-reduced-motion: reduce) {
@@ -337,8 +432,8 @@ cap-button > button {
337
432
  cap-error {
338
433
  position: absolute;
339
434
  z-index: 1200;
340
- inset-block-start: -.35em;
341
- inset-inline-end: -.35em;
435
+ inset-block-start: -.5rem;
436
+ inset-inline-end: -.5rem;
342
437
  display: block;
343
438
  width: 1.25em;
344
439
  height: 1.25em;
@@ -352,18 +447,20 @@ cap-error {
352
447
 
353
448
  cap-error > cap-erroricon {
354
449
  position: absolute;
355
- inset: 0;
356
- display: grid;
357
- width: 1.25em;
358
- height: 1.25em;
450
+ display: flex;
451
+ width: 1rem;
452
+ height: 1rem;
453
+ font-size: .9rem;
359
454
  color: var(--error-contrast);
360
455
  background: var(--error-color);
361
- border: 1px solid var(--error-color);
456
+ border: var(--error-icon-border);
362
457
  border-radius: 50%;
458
+ box-shadow: var(--error-icon-shadow);
363
459
  box-sizing: border-box;
364
- font-weight: 700;
365
- line-height: 1;
366
- place-items: center;
460
+ font-weight: bold;
461
+ justify-content: center;
462
+ align-items: center;
463
+
367
464
  }
368
465
 
369
466
  cap-error > cap-erroricon::before {
@@ -382,8 +479,8 @@ cap-error {
382
479
  padding: var(--space-xs) var(--space-sm);
383
480
  color: var(--ui-color);
384
481
  background: var(--error-bg-neutral, var(--application-background));
385
- border: 1px solid var(--error-color);
386
- border-radius: var(--radius-md);
482
+ border: 1px solid var(--error-control-border);
483
+ border-radius: var(--ui-border-radius);
387
484
  box-shadow: var(--ui-shadow);
388
485
  opacity: 0;
389
486
  overflow-wrap: anywhere;
@@ -421,6 +518,49 @@ cap-error {
421
518
  to { background-position: 2rem 0, 0 0; }
422
519
  }
423
520
 
521
+ cap-placeholder {
522
+ display: block;
523
+ width: 5em;
524
+ height: 1em;
525
+ background: #ccc;
526
+ border-radius: var(--ui-border-radius);
527
+ position: relative;
528
+ }
529
+
530
+ cap-placeholder::after {
531
+ content: "";
532
+ display: block;
533
+ position: absolute;
534
+ z-index: 1;
535
+ inset: 0;
536
+ margin: auto;
537
+ animation: cap-working-progress .55s linear infinite;
538
+ background-repeat: repeat;
539
+ background-size: 2rem 2rem;
540
+ background-image: var(--working-background-image);
541
+ border: 0 solid transparent;
542
+ border-radius: inherit;
543
+ box-sizing: border-box;
544
+ pointer-events: none;
545
+ }
546
+
547
+ @media (prefers-reduced-motion: reduce) {
548
+ cap-placeholder::after {
549
+ animation: none !important;
550
+ }
551
+ }
552
+
553
+ @media (forced-colors: active) {
554
+ cap-placeholder {
555
+ background: CanvasText;
556
+ forced-color-adjust: none;
557
+ }
558
+
559
+ cap-placeholder::after {
560
+ display: none;
561
+ }
562
+ }
563
+
424
564
  cap-categoryhidepanel,
425
565
  cap-groupbox {
426
566
  display: flex;
@@ -429,15 +569,20 @@ cap-groupbox {
429
569
  box-sizing: border-box;
430
570
  gap: var(--cap-groupbox-gap, 0 0.35rem);
431
571
  padding: var(--cap-groupbox-padding, 0.125rem 0.35rem 0.125rem 0.125rem);
572
+ padding-top: var(--cap-groupbox-padding-top, .125rem);
432
573
  border: var(--cap-groupbox-border, 1px solid var(--ui-border-color));
433
574
  border-radius: var(--ui-border-radius);
434
575
  position: relative;
435
576
  min-width: 0;
436
577
  min-height: 0;
578
+ flex: var(--cap-groupbox-flex, 0 1 auto);
437
579
  }
438
580
 
439
581
  cap-categoryhidepanel > cap-header,
440
582
  cap-groupbox > cap-header {
583
+ position: var(--cap-groupbox-header-position, static);
584
+ left: var(--cap-groupbox-header-inset, auto);
585
+ top: var(--cap-groupbox-header-inset, auto);
441
586
  display: grid;
442
587
  place-items: var(--cap-groupbox-header-align, center);
443
588
  box-sizing: border-box;
@@ -457,21 +602,16 @@ cap-groupbox {
457
602
 
458
603
  cap-categoryhidepanel > cap-content,
459
604
  cap-groupbox > cap-content {
460
- display: block;
461
- min-width: 0;
462
- min-height: 0;
463
- margin-left: var(--cap-groupbox-content-margin, .25em);
464
- }
465
-
466
- .cap-layout-horizontal cap-categoryhidepanel > cap-content > cap-layout,
467
- .cap-layout-horizontal cap-groupbox > cap-content > cap-layout,
468
- .cap-layout-vertical cap-categoryhidepanel > cap-content > cap-layout,
469
- .cap-layout-vertical cap-groupbox > cap-content > cap-layout {
470
- gap: .5rem;
605
+ display: flex;
606
+ flex-flow: column nowrap;
471
607
  justify-content: flex-start;
472
608
  align-content: flex-start;
473
- justify-items: flex-start;
474
609
  align-items: flex-start;
610
+ gap: var(--groupbox-content-gap, .5rem);
611
+ min-width: 0;
612
+ min-height: 0;
613
+ margin-left: var(--cap-groupbox-content-margin, .25em);
614
+ flex: 1 1 auto;
475
615
  }
476
616
 
477
617
  /* Presentation contexts: each marker sets the complete context-sensitive
@@ -492,6 +632,10 @@ cap-groupbox {
492
632
  --cap-groupbox-header-writing: vertical-rl;
493
633
  --cap-groupbox-header-transform: rotate(180deg);
494
634
  --cap-groupbox-content-margin: .25em;
635
+ --cap-groupbox-flex: 0 1 auto;
636
+ --cap-groupbox-padding-top: .125rem;
637
+ --cap-groupbox-header-position: static;
638
+ --cap-groupbox-header-inset: auto;
495
639
  }
496
640
 
497
641
  [data-cap-context='form'] {
@@ -501,51 +645,230 @@ cap-groupbox {
501
645
  --cap-groupbox-border: 1px solid var(--ui-border-color);
502
646
  --cap-groupbox-header-align: center start;
503
647
  --cap-groupbox-header-width: auto;
504
- --cap-groupbox-header-padding: 0;
648
+ --cap-groupbox-header-padding: 2px 5px;
505
649
  --cap-groupbox-header-color: var(--text-color);
506
- --cap-groupbox-header-background: none;
650
+ --cap-groupbox-header-background: var(--panel-background);
507
651
  --cap-groupbox-header-shadow: none;
508
652
  --cap-groupbox-header-writing: horizontal-tb;
509
653
  --cap-groupbox-header-transform: none;
510
654
  --cap-groupbox-content-margin: 0;
655
+ --cap-groupbox-flex: 0 1 auto;
656
+ --cap-groupbox-padding-top: 1em;
657
+ --cap-groupbox-header-position: absolute;
658
+ --cap-groupbox-header-inset: calc(0px - var(--ui-font-size) / 2);
511
659
  }
512
660
 
513
- [data-cap-context='form'] cap-categoryhidepanel,
514
- [data-cap-context='form'] cap-groupbox {
515
- flex: 1 1 auto;
661
+ .cap-layout-horizontal > cap-categoryhidepanel,
662
+ .cap-layout-horizontal > cap-groupbox {
663
+ max-inline-size: max-content;
664
+ min-inline-size: min-content;
665
+ }
666
+
667
+ cap-categoryhidepanel.cap-groupbox-section,
668
+ cap-groupbox.cap-groupbox-section {
669
+ display: grid;
670
+ grid-template-columns: max-content minmax(0, 1fr);
671
+ grid-template-rows: max-content minmax(max-content, 1fr);
516
672
  align-self: stretch;
517
- padding-top: 1em;
673
+ align-items: start;
674
+ gap: 0;
675
+ padding: 0;
676
+ padding-top: 0;
677
+ border: 0;
678
+ border-radius: 0;
679
+ min-inline-size: 0;
680
+ max-inline-size: none;
681
+ flex: 0 0 auto;
682
+ }
683
+
684
+ cap-categoryhidepanel.cap-groupbox-section::before,
685
+ cap-groupbox.cap-groupbox-section::before {
686
+ content: "";
687
+ grid-column: 2;
688
+ grid-row: 1;
689
+ align-self: center;
690
+ border-block-start: var(--groupbox-section-separator);
518
691
  }
519
692
 
520
- .cap-layout-horizontal cap-categoryhidepanel,
521
- .cap-layout-horizontal cap-groupbox {
522
- max-width: 15rem;
693
+ cap-categoryhidepanel.cap-groupbox-section > cap-header,
694
+ cap-groupbox.cap-groupbox-section > cap-header {
695
+ position: static;
696
+ grid-column: 1;
697
+ grid-row: 1;
698
+ display: block;
699
+ width: auto;
523
700
  min-width: 0;
701
+ min-height: 0;
702
+ padding: 0 0.5rem 0 0;
703
+ border-radius: 0;
704
+ color: var(--groupbox-section-header-color);
705
+ background: transparent;
706
+ box-shadow: none;
707
+ writing-mode: horizontal-tb;
708
+ transform: none;
709
+ font-size: var(--groupbox-section-font-size, 1.2em);
710
+ font-weight: 600;
524
711
  }
525
712
 
526
- .cap-layout-vertical cap-categoryhidepanel,
527
- .cap-layout-vertical cap-groupbox {
528
- max-height: 15rem;
713
+ cap-categoryhidepanel.cap-groupbox-section > cap-content,
714
+ cap-groupbox.cap-groupbox-section > cap-content {
715
+ grid-column: 1 / -1;
716
+ grid-row: 2;
717
+ flex-flow: row nowrap;
718
+ margin-left: 0;
719
+ padding-block: 0.75rem;
720
+ min-width: 0;
721
+ }
722
+
723
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-section,
724
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-section {
725
+ grid-template-columns: max-content minmax(0, 1fr);
726
+ grid-template-rows: max-content minmax(max-content, 1fr);
727
+ }
728
+
729
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-section::before,
730
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-section::before {
731
+ grid-column: 1;
732
+ grid-row: 2;
733
+ justify-self: stretch;
734
+ align-self: stretch;
735
+ border-block-start: 0;
736
+ border-inline-end: var(--groupbox-section-separator);
737
+ }
738
+
739
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-section > cap-header,
740
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-section > cap-header {
741
+ padding: 0 0.5rem 0.5rem 0;
742
+ }
743
+
744
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-section > cap-content,
745
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-section > cap-content {
746
+ grid-column: 2;
747
+ grid-row: 1 / -1;
748
+ padding-block: 0;
749
+ padding-inline: 0.75rem;
750
+ min-block-size: 0;
751
+ }
752
+
753
+ cap-categoryhidepanel.cap-groupbox-column,
754
+ cap-groupbox.cap-groupbox-column {
755
+ gap: 0;
756
+ padding: 0 1rem;
757
+ padding-top: 0;
758
+ border: 0;
759
+ border-radius: 0;
760
+ flex: 0 1 auto;
761
+ }
762
+
763
+ cap-categoryhidepanel.cap-groupbox-column > cap-header,
764
+ cap-groupbox.cap-groupbox-column > cap-header {
765
+ position: static;
766
+ display: block;
767
+ width: auto;
768
+ min-width: 0;
529
769
  min-height: 0;
770
+ padding: 0;
771
+ margin-block-end: 0.75rem;
772
+ border-radius: 0;
773
+ color: var(--groupbox-column-header-color);
774
+ background: transparent;
775
+ box-shadow: none;
776
+ writing-mode: horizontal-tb;
777
+ transform: none;
778
+ font-size: var(--ui-font-size);
779
+ font-weight: 600;
530
780
  }
531
781
 
532
- [data-cap-context='form'] cap-groupbox > cap-header {
533
- position: absolute;
534
- left: calc(0px - var(--ui-font-size) / 2);
535
- top: calc(0px - var(--ui-font-size) / 2);
536
- background: var(--panel-background);
537
- padding: 2px 5px;
782
+ cap-categoryhidepanel.cap-groupbox-column > cap-content,
783
+ cap-groupbox.cap-groupbox-column > cap-content {
784
+ margin-left: 0;
785
+ }
786
+
787
+ /* A section's own content body is the ordinary horizontal column row.
788
+ Preserve the same stretch, edge padding, and separators formerly
789
+ provided when an application inserted a Layout just for that row. */
790
+ cap-categoryhidepanel.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column,
791
+ /* A section's own content body is the ordinary horizontal column row.
792
+ Preserve the same stretch, edge padding, and separators formerly
793
+ provided when an application inserted a Layout just for that row. */
794
+ cap-groupbox.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column {
795
+ align-self: stretch;
796
+ }
797
+
798
+ cap-categoryhidepanel.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column
799
+ + cap-groupbox.cap-groupbox-column,
800
+ cap-groupbox.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column
801
+ + cap-groupbox.cap-groupbox-column {
802
+ border-inline-start: var(--groupbox-column-separator);
803
+ }
804
+
805
+ cap-categoryhidepanel.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column:first-child,
806
+ cap-groupbox.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column:first-child {
807
+ padding-inline-start: 0;
808
+ }
809
+
810
+ cap-categoryhidepanel.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column:last-child,
811
+ cap-groupbox.cap-groupbox-section > cap-content > cap-groupbox.cap-groupbox-column:last-child {
812
+ padding-inline-end: 0;
813
+ }
814
+
815
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-column,
816
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-column,
817
+ .cap-layout-vertical > cap-categoryhidepanel.cap-groupbox-column,
818
+ .cap-layout-vertical > cap-groupbox.cap-groupbox-column {
819
+ align-self: stretch;
820
+ }
821
+
822
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-column + cap-categoryhidepanel.cap-groupbox-column,
823
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-column + cap-groupbox.cap-groupbox-column {
824
+ border-inline-start: var(--groupbox-column-separator);
825
+ }
826
+
827
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-column:first-child,
828
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-column:first-child {
829
+ padding-inline-start: 0;
830
+ }
831
+
832
+ .cap-layout-horizontal > cap-categoryhidepanel.cap-groupbox-column:last-child,
833
+ .cap-layout-horizontal > cap-groupbox.cap-groupbox-column:last-child {
834
+ padding-inline-end: 0;
835
+ }
836
+
837
+ .cap-layout-vertical > cap-categoryhidepanel.cap-groupbox-column,
838
+ .cap-layout-vertical > cap-groupbox.cap-groupbox-column {
839
+ padding-inline: 0;
840
+ padding-block: 1rem;
841
+ }
842
+
843
+ .cap-layout-vertical > cap-categoryhidepanel.cap-groupbox-column + cap-categoryhidepanel.cap-groupbox-column,
844
+ .cap-layout-vertical > cap-groupbox.cap-groupbox-column + cap-groupbox.cap-groupbox-column {
845
+ border-block-start: var(--groupbox-column-separator);
846
+ }
847
+
848
+ .cap-layout-vertical > cap-categoryhidepanel.cap-groupbox-column:first-child,
849
+ .cap-layout-vertical > cap-groupbox.cap-groupbox-column:first-child {
850
+ padding-block-start: 0;
538
851
  }
539
852
 
540
- cap-categoryhidepanel > cap-content {
853
+ .cap-layout-vertical > cap-categoryhidepanel.cap-groupbox-column:last-child,
854
+ .cap-layout-vertical > cap-groupbox.cap-groupbox-column:last-child {
855
+ padding-block-end: 0;
856
+ }
857
+
858
+ cap-categoryhidepanel {
859
+ --_cap-control-compact-min: 0px;
860
+ --control-row-padding-block: 0px;
861
+ }
862
+
863
+ cap-categoryhidepanel > cap-content {
541
864
  display: flex;
542
865
  flex-direction: column;
543
866
  align-self: stretch;
544
867
  flex: 1 1 0;
545
- gap: .5em;
868
+ gap: 2px;
546
869
  }
547
870
 
548
- cap-categoryhidepanel > cap-content * > fieldset > legend {
871
+ cap-categoryhidepanel > cap-content cap-optiongroup > fieldset > legend {
549
872
  display: flex;
550
873
  justify-content: space-between;
551
874
  align-items: center;
@@ -554,23 +877,30 @@ cap-categoryhidepanel > cap-content {
554
877
  color: var(--palette-neutral-950);
555
878
  gap: 0.5rem;
556
879
  width: 100%;
557
- padding: 0 0 0.25em;
558
- margin-bottom: 0.25em;
880
+ padding: 0 0 1px;
881
+ margin-bottom: 1px;
559
882
  border-bottom: 1px solid var(--ui-border-color);
560
883
  user-select: none;
561
884
  }
562
885
 
563
- cap-categoryhidepanel > cap-content * > fieldset {
886
+ cap-categoryhidepanel > cap-content cap-optiongroup > fieldset {
564
887
  display: flex;
565
- flex-flow: column;
888
+ flex-flow: column nowrap;
566
889
  justify-content: stretch;
567
890
  justify-items: stretch;
568
891
  align-items: stretch;
569
892
  align-content: stretch;
570
893
  box-sizing: border-box;
571
894
  width: 100%;
572
- gap: 0;
573
- padding: .25em 0 .5em 0;
895
+ gap: 2px;
896
+ padding: 1px 0 2px;
897
+ }
898
+
899
+ /* OptionsBox is deliberately a dense, vertical filter surface. Keep
900
+ RadioGroup in the same rhythm as checkbox options, regardless of
901
+ theme-level RadioGroup spacing. */
902
+ cap-categoryhidepanel > cap-content cap-radiogroup > fieldset {
903
+ gap: 2px;
574
904
  }
575
905
 
576
906
  cap-categoryhidepanel {
@@ -580,8 +910,9 @@ cap-categoryhidepanel {
580
910
  }
581
911
 
582
912
  cap-categoryhidepanel > cap-content > cap-categoryhidecontent {
583
- display: grid;
584
- align-content: start;
913
+ display: flex;
914
+ flex-flow: column nowrap;
915
+ align-items: stretch;
585
916
  gap: var(--viz-space, 0.6rem);
586
917
  min-width: 0;
587
918
  }
@@ -593,7 +924,8 @@ cap-categoryhidepanel {
593
924
  }
594
925
 
595
926
  cap-categoryhidepanel > cap-content > cap-categoryhidecontent > cap-criteriongroups {
596
- display: grid;
927
+ display: flex;
928
+ flex-flow: column nowrap;
597
929
  gap: 1em;
598
930
  min-width: 0;
599
931
  }
@@ -618,7 +950,7 @@ cap-categoryhidepanel {
618
950
  align-items: center;
619
951
  gap: 0.45rem;
620
952
  min-width: 0;
621
- max-height: 1em;
953
+
622
954
  }
623
955
 
624
956
  cap-categoryhidepanel cap-categoryswatch {
@@ -650,6 +982,8 @@ cap-categoryhidepanel {
650
982
  cap-header {
651
983
  display: block;
652
984
  color: var(--section-header-color);
985
+ font-size: var(--section-header-font-size);
986
+ font-weight: var(--section-header-font-weight);
653
987
  border-radius: var(--ui-border-radius) var(--ui-border-radius) 0 0;
654
988
  padding: .25em;
655
989
  background: var(--section-header-background);
@@ -668,29 +1002,102 @@ cap-header {
668
1002
  font: inherit;
669
1003
  }
670
1004
 
1005
+ cap-optiongroup,
1006
+ cap-collapsibleoptiongroup {
1007
+ display: block;
1008
+ position: relative;
1009
+ min-width: 0;
1010
+ }
1011
+
1012
+ cap-optiongroup > fieldset,
1013
+ cap-collapsibleoptiongroup > fieldset {
1014
+ margin: 0;
1015
+ padding: 0;
1016
+ min-inline-size: 0;
1017
+ border: 0;
1018
+ width: 100%;
1019
+ box-sizing: border-box;
1020
+ }
1021
+
1022
+ cap-optiongroup > fieldset > legend,
1023
+ cap-collapsibleoptiongroup > fieldset > legend {
1024
+ display: flex;
1025
+ justify-content: space-between;
1026
+ align-items: center;
1027
+ box-sizing: border-box;
1028
+ gap: 0.5rem;
1029
+ width: 100%;
1030
+ padding: 0 0 0.25em;
1031
+ margin-bottom: 0.5em;
1032
+ border-bottom: 1px solid var(--ui-border-color);
1033
+ font: inherit;
1034
+ user-select: none;
1035
+ }
1036
+
1037
+ cap-optiongroup > fieldset > legend > span,
1038
+ cap-collapsibleoptiongroup > fieldset > legend > span {
1039
+ flex: 1;
1040
+ min-width: 0;
1041
+ }
1042
+
1043
+ cap-optiongroup > fieldset[aria-busy="true"]:not([aria-invalid="true"]),
1044
+ cap-collapsibleoptiongroup > fieldset[aria-busy="true"]:not([aria-invalid="true"]) {
1045
+ background-image: var(--working-background-image);
1046
+ background-repeat: repeat;
1047
+ background-size: 2rem 2rem;
1048
+ animation: cap-working-progress .55s linear infinite;
1049
+ }
1050
+
1051
+ cap-optiongroup > fieldset[aria-invalid="true"],
1052
+ cap-collapsibleoptiongroup > fieldset[aria-invalid="true"] {
1053
+ border: 1px solid var(--error-control-border);
1054
+ border-radius: var(--ui-border-radius);
1055
+ box-shadow: var(--error-control-shadow);
1056
+ }
1057
+
1058
+ @media (prefers-reduced-motion: reduce) {
1059
+ cap-optiongroup > fieldset[aria-busy="true"],
1060
+ cap-collapsibleoptiongroup > fieldset[aria-busy="true"] {
1061
+ animation: none !important;
1062
+ }
1063
+ }
1064
+
1065
+ @media (forced-colors: active) {
1066
+ cap-optiongroup > fieldset[aria-invalid="true"],
1067
+ cap-collapsibleoptiongroup > fieldset[aria-invalid="true"] {
1068
+ outline: 2px solid Mark;
1069
+ outline-offset: 1px;
1070
+ }
1071
+ }
1072
+
671
1073
  cap-checkbox {
672
1074
  display: inline-flex;
673
1075
  position: relative;
674
1076
  flex-flow: row wrap;
675
- line-height: 1;
1077
+ align-items: center;
1078
+ align-content: center;
1079
+ --_cap-checkable-label-color: var(--ui-text-color);
1080
+ --_cap-checkable-cursor: pointer;
1081
+ --_cap-checkable-box-background: var(--checkbox-box-background,
1082
+ var(--ui-input-bg, transparent));
1083
+ --_cap-checkable-box-border: var(--checkbox-box-border,
1084
+ var(--cbx-o-border, 1px solid currentColor));
1085
+ --_cap-checkable-box-shadow: var(--checkbox-box-shadow);
1086
+ --_cap-checkable-box-filter: none;
676
1087
  }
677
1088
 
678
1089
  cap-checkbox > label {
679
1090
  display: flex;
680
1091
  flex-flow: row nowrap;
681
1092
  position: relative;
682
- line-height: calc(var(--ui-font-size) + var(--ui-padding) + var(--ui-padding));
683
- font-size: var(--ui-font-size);
684
- height: calc(var(--ui-font-size) + var(--ui-padding-h) + var(--ui-padding-h));
685
- color: var(--ui-text-color);
1093
+ min-height: var(--_cap-control-row-min);
1094
+ margin: 0;
1095
+ color: var(--_cap-checkable-label-color);
686
1096
  border-radius: var(--ui-border-radius);
687
1097
  box-sizing: border-box;
688
1098
  align-items: center;
689
1099
  gap: .3em;
690
- align-content: center;
691
- justify-content: center;
692
- justify-items: center;
693
- cursor: pointer;
1100
+ cursor: var(--_cap-checkable-cursor);
694
1101
  user-select: none;
695
1102
  }
696
1103
 
@@ -699,6 +1106,15 @@ cap-checkbox {
699
1106
  cursor: not-allowed;
700
1107
  }
701
1108
 
1109
+ cap-checkbox > label:has(> input[aria-readonly="true"]:not(:disabled)) {
1110
+ --_cap-checkable-label-color: var(--checkable-label-color-readonly);
1111
+ --_cap-checkable-cursor: default;
1112
+ --_cap-checkable-box-background: var(--checkbox-box-background-readonly);
1113
+ --_cap-checkable-box-border: var(--checkbox-box-border-readonly);
1114
+ --_cap-checkable-box-shadow: var(--checkbox-box-shadow-readonly);
1115
+ --_cap-checkable-box-filter: saturate(.78);
1116
+ }
1117
+
702
1118
  cap-checkbox > label > input {
703
1119
  position: absolute;
704
1120
  width: 1px;
@@ -715,31 +1131,74 @@ cap-checkbox {
715
1131
 
716
1132
  cap-checkbox > label > input + cap-checkshell {
717
1133
  position: relative;
718
- display: grid;
719
- width: 1em;
720
- height: 1em;
721
- flex: 0 0 1em;
1134
+ display: flex;
1135
+ align-items: center;
1136
+ justify-content: center;
1137
+ width: var(--checkbox-box-size, 1em);
1138
+ height: var(--checkbox-box-size, 1em);
1139
+ flex: 0 0 var(--checkbox-box-size, 1em);
722
1140
  box-sizing: border-box;
723
1141
  text-align: center;
724
- line-height: 120%;
1142
+ line-height: 1;
725
1143
  color: var(--input-color, var(--ui-text-color, currentColor));
726
- background: var(--checkbox-box-background, var(--ui-input-bg, transparent));
727
- border: var(--checkbox-box-border, var(--cbx-o-border, 1px solid currentColor));
728
- border-radius: var(--cbx-border-radius, var(--radius-sm, 0.2rem));
729
- box-shadow: var(--checkbox-box-shadow);
1144
+ background: var(--_cap-checkable-box-background);
1145
+ border: var(--_cap-checkable-box-border);
1146
+ border-radius: var(--checkbox-box-radius,
1147
+ var(--cbx-border-radius, var(--radius-sm, 0.2rem)));
1148
+ box-shadow: var(--_cap-checkable-box-shadow);
1149
+ filter: var(--_cap-checkable-box-filter);
730
1150
  font-family: inherit;
731
1151
  font-size: 1em;
732
1152
  user-select: none;
733
- place-items: center;
734
1153
  }
735
1154
 
736
1155
  cap-checkbox > label > input:checked + cap-checkshell {
737
1156
  color: var(--checkbox-symbol-color, var(--selection-color, currentColor));
738
1157
  background: var(--checkbox-box-background-checked,
739
1158
  var(--selection-background, var(--ui-accent-color, Highlight)));
1159
+ border: var(--checkbox-box-border-checked, var(--checkbox-box-border,
1160
+ var(--cbx-o-border, 1px solid currentColor)));
740
1161
  box-shadow: var(--checkbox-box-shadow-checked);
741
1162
  }
742
1163
 
1164
+
1165
+
1166
+ cap-checkbox > label:has(> input:required:invalid:not(:disabled):not([aria-invalid="true"]))::before {
1167
+ content: "";
1168
+ position: absolute;
1169
+ z-index: 0;
1170
+ inset-block: -4px;
1171
+ inset-inline-start: -4px;
1172
+ inset-inline-end: calc(-4px - 1em);
1173
+ border: 1px dashed var(--required-color);
1174
+ border-radius: inherit;
1175
+ pointer-events: none;
1176
+ }
1177
+
1178
+
1179
+ cap-checkbox > label:has(> input:required:invalid:not(:disabled):not([aria-invalid="true"]))::after {
1180
+ content: "✲";
1181
+ position: absolute;
1182
+ z-index: 1;
1183
+ inset-block-start: -.5em;
1184
+ inset-inline-end: -1em;
1185
+ display: flex;
1186
+ inline-size: 1rem;
1187
+ block-size: 1rem;
1188
+ align-items: center;
1189
+ justify-content: center;
1190
+ color: var(--required-indicator-color);
1191
+ background: var(--required-indicator-background);
1192
+ font-size: .75rem;
1193
+ font-weight: 700;
1194
+ line-height: 1;
1195
+ pointer-events: none;
1196
+ }
1197
+
1198
+ cap-checkbox > label:has(> input[aria-invalid="true"]) {
1199
+ box-shadow: var(--error-control-shadow);
1200
+ }
1201
+
743
1202
  cap-checkbox > label > input:focus-visible + cap-checkshell {
744
1203
  outline: 2px solid var(--focus-color, var(--ui-accent-color, Highlight));
745
1204
  outline-offset: 1px;
@@ -758,12 +1217,9 @@ cap-checkbox {
758
1217
  animation: cap-working-progress .55s linear infinite;
759
1218
  }
760
1219
 
761
- cap-checkbox > label:has(> input[aria-invalid="true"]) {
762
- color: var(--error-color);
763
- }
764
-
765
1220
  cap-checkbox > label > input[aria-invalid="true"] + cap-checkshell {
766
- border-color: var(--error-color);
1221
+ border-color: var(--error-control-border);
1222
+ box-shadow: none;
767
1223
  }
768
1224
 
769
1225
  @media (prefers-reduced-motion: reduce) {
@@ -773,78 +1229,7 @@ cap-checkbox {
773
1229
  }
774
1230
 
775
1231
  @media (forced-colors: active) {
776
- cap-checkbox > label > input[aria-invalid="true"] + cap-checkshell {
777
- outline: 2px solid Mark;
778
- outline-offset: 1px;
779
- }
780
- }
781
-
782
- cap-checkbox > label > input[value="require"] + cap-checkshell {
783
- color: var(--palette-contrast-light);
784
- background: var(--palette-green);
785
- box-shadow: var(--checkbox-box-shadow-checked);
786
- }
787
-
788
- cap-checkbox > label > input[value="deny"] + cap-checkshell {
789
- color: var(--palette-contrast-light);
790
- background: var(--palette-red);
791
- box-shadow: var(--checkbox-box-shadow-checked);
792
- }
793
-
794
- cap-collapsibleoptiongroup {
795
- display: block;
796
- position: relative;
797
- min-width: 0;
798
- }
799
-
800
- cap-collapsibleoptiongroup > fieldset {
801
- margin: 0;
802
- padding: 0;
803
- min-inline-size: 0;
804
- border: 0;
805
- width: 100%;
806
- box-sizing: border-box;
807
- }
808
-
809
- cap-collapsibleoptiongroup > fieldset > legend {
810
- display: flex;
811
- justify-content: space-between;
812
- align-items: center;
813
- box-sizing: border-box;
814
- gap: 0.5rem;
815
- width: 100%;
816
- padding: 0 0 0.25em;
817
- margin-bottom: 0.5em;
818
- border-bottom: 1px solid var(--ui-border-color);
819
- font: inherit;
820
- user-select: none;
821
- }
822
-
823
- cap-collapsibleoptiongroup > fieldset > legend > span {
824
- flex: 1;
825
- min-width: 0;
826
- }
827
-
828
- cap-collapsibleoptiongroup > fieldset[aria-busy="true"]:not([aria-invalid="true"]) {
829
- background-image: var(--working-background-image);
830
- background-repeat: repeat;
831
- background-size: 2rem 2rem;
832
- animation: cap-working-progress .55s linear infinite;
833
- }
834
-
835
- cap-collapsibleoptiongroup > fieldset[aria-invalid="true"] {
836
- border: 1px solid var(--error-color);
837
- border-radius: var(--radius-md);
838
- }
839
-
840
- @media (prefers-reduced-motion: reduce) {
841
- cap-collapsibleoptiongroup > fieldset[aria-busy="true"] {
842
- animation: none !important;
843
- }
844
- }
845
-
846
- @media (forced-colors: active) {
847
- cap-collapsibleoptiongroup > fieldset[aria-invalid="true"] {
1232
+ cap-checkbox > label:has(> input[aria-invalid="true"]) {
848
1233
  outline: 2px solid Mark;
849
1234
  outline-offset: 1px;
850
1235
  }
@@ -985,7 +1370,8 @@ cap-linegraph {
985
1370
  }
986
1371
 
987
1372
  cap-splitselectionpanel {
988
- display: grid;
1373
+ display: flex;
1374
+ flex-flow: column nowrap;
989
1375
  gap: var(--viz-space, 0.6rem);
990
1376
  min-width: 0;
991
1377
  user-select: none;
@@ -1013,10 +1399,10 @@ cap-splitselectionpanel {
1013
1399
  }
1014
1400
 
1015
1401
  cap-splitselectionpanel > cap-groupbox > cap-content > cap-presets {
1016
- display: grid;
1402
+ display: flex;
1403
+ flex-flow: column nowrap;
1017
1404
  gap: 0.35rem;
1018
- align-content: stretch;
1019
- justify-content: stretch;
1405
+ align-items: stretch;
1020
1406
  }
1021
1407
 
1022
1408
  cap-splitselectionpanel > cap-groupbox > cap-content > cap-presets > cap-button {
@@ -1026,8 +1412,9 @@ cap-splitselectionpanel {
1026
1412
  }
1027
1413
 
1028
1414
  cap-splitselectionpanel ol {
1029
- display: grid;
1030
- gap: 0.25rem;
1415
+ display: flex;
1416
+ flex-flow: column nowrap;
1417
+ gap: .33rem;
1031
1418
  padding: 0;
1032
1419
  list-style: none;
1033
1420
  }
@@ -1039,7 +1426,7 @@ cap-splitselectionpanel {
1039
1426
  justify-content: space-between;
1040
1427
  gap: 0.35rem;
1041
1428
  min-width: 0;
1042
- padding: 0 .35rem;
1429
+ padding: .15rem .35rem;
1043
1430
  border-radius: var(--ui-border-radius);
1044
1431
  box-shadow: var(--box-shadow);
1045
1432
  }