@threadlabs/looma 0.11.5 → 0.12.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.
@@ -368,7 +368,7 @@ ol[data-v-0d86d58e] {
368
368
  display: none;
369
369
  }
370
370
 
371
- [data-component~="ui-button"][data-v-6c8750a9] {
371
+ [data-component~="ui-button"][data-v-75541d8a] {
372
372
  --_hue: var(--ui-accent);
373
373
  --_hue-hover: var(--ui-accent-hover);
374
374
  --_hue-active: var(--ui-accent-active);
@@ -387,15 +387,15 @@ ol[data-v-0d86d58e] {
387
387
  vertical-align: middle;
388
388
  color: var(--_tone-text);
389
389
  }
390
- [data-component~="ui-button"][data-ui-button-state~="align=start"][data-v-6c8750a9] {
390
+ [data-component~="ui-button"][data-ui-button-state~="align=start"][data-v-75541d8a] {
391
391
  justify-content: flex-start;
392
392
  text-align: start;
393
393
  }
394
- [data-component~="ui-button"][data-ui-button-state~="stretch"][data-v-6c8750a9] {
394
+ [data-component~="ui-button"][data-ui-button-state~="stretch"][data-v-75541d8a] {
395
395
  display: flex;
396
396
  inline-size: 100%;
397
397
  }
398
- [data-component~="ui-button"][data-v-6c8750a9] {
398
+ [data-component~="ui-button"][data-v-75541d8a] {
399
399
  appearance: none;
400
400
  min-block-size: var(--ui-button-min-block-size, var(--ui-control-size-md));
401
401
  border-style: solid;
@@ -420,17 +420,17 @@ ol[data-v-0d86d58e] {
420
420
  margin: 0;
421
421
  }
422
422
  @supports (text-box-trim: trim-both) {
423
- [data-component~="ui-button"][data-v-6c8750a9] {
423
+ [data-component~="ui-button"][data-v-75541d8a] {
424
424
  text-box-trim: trim-both;
425
425
  text-box-edge: cap alphabetic;
426
426
  }
427
427
  }
428
- [data-component~="ui-button"][data-ui-button-state~="size=sm"][data-v-6c8750a9] {
428
+ [data-component~="ui-button"][data-ui-button-state~="size=sm"][data-v-75541d8a] {
429
429
  min-block-size: var(--ui-control-size-sm);
430
430
  padding: var(--ui-space-1) var(--ui-space-2);
431
431
  font-size: var(--ui-font-size-sm);
432
432
  }
433
- [data-component~="ui-button"][data-ui-button-state~="size=lg"][data-v-6c8750a9] {
433
+ [data-component~="ui-button"][data-ui-button-state~="size=lg"][data-v-75541d8a] {
434
434
  min-block-size: var(--ui-control-size-lg);
435
435
  padding: var(--ui-space-3) var(--ui-space-4);
436
436
  font-size: var(--ui-font-size-md);
@@ -438,29 +438,29 @@ ol[data-v-0d86d58e] {
438
438
 
439
439
  /* A link is never :enabled, so interactive states test "not unavailable" instead: for a button that
440
440
  is exactly :enabled, at the same specificity, and it also matches a link that can be followed. */
441
- [data-component~="ui-button"][data-v-6c8750a9]:hover:not(:disabled, [aria-disabled="true"]) {
441
+ [data-component~="ui-button"][data-v-75541d8a]:hover:not(:disabled, [aria-disabled="true"]) {
442
442
  border-color: var(--ui-button-hover-border, var(--_tone-hover));
443
443
  background-color: var(--ui-button-hover-surface, oklch(from var(--_tone) l c h / 12%));
444
444
  }
445
445
 
446
446
  /* Pressed reads as pressed in: the highlight goes, and the shadow moves inside. */
447
- [data-component~="ui-button"][data-v-6c8750a9]:active:not(:disabled, [aria-disabled="true"]) {
447
+ [data-component~="ui-button"][data-v-75541d8a]:active:not(:disabled, [aria-disabled="true"]) {
448
448
  background-color: var(--ui-button-active-surface, oklch(from var(--_tone) l c h / 18%));
449
449
  background-image: none;
450
450
  box-shadow: var(--ui-pressed);
451
451
  }
452
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-6c8750a9],
453
- [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-6c8750a9] {
452
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-75541d8a],
453
+ [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-75541d8a] {
454
454
  border-color: var(--_tone);
455
455
  background-color: var(--_tone);
456
456
  color: var(--_on-tone);
457
457
  box-shadow: var(--ui-button-solid-shadow, var(--ui-raised));
458
458
  }
459
- :is([data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-6c8750a9], [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-6c8750a9]):hover:not(:disabled, [aria-disabled="true"]) {
459
+ :is([data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-75541d8a], [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-75541d8a]):hover:not(:disabled, [aria-disabled="true"]) {
460
460
  background-color: var(--_tone-hover);
461
461
  border-color: var(--_tone-hover);
462
462
  }
463
- :is([data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-6c8750a9], [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-6c8750a9]):active:not(:disabled, [aria-disabled="true"]) {
463
+ :is([data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-75541d8a], [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-75541d8a]):active:not(:disabled, [aria-disabled="true"]) {
464
464
  background-color: var(--_tone-active);
465
465
  border-color: var(--_tone-active);
466
466
  background-image: none;
@@ -469,43 +469,43 @@ ol[data-v-0d86d58e] {
469
469
 
470
470
  /* Tone is the colour, variant is the volume. Every pairing works: a danger outline is a
471
471
  destructive secondary action, not a special case. */
472
- [data-component~="ui-button"][data-ui-button-state~="tone=neutral"][data-v-6c8750a9] {
472
+ [data-component~="ui-button"][data-ui-button-state~="tone=neutral"][data-v-75541d8a] {
473
473
  --_hue: var(--ui-text);
474
474
  --_hue-hover: var(--ui-text);
475
475
  --_hue-active: var(--ui-text);
476
476
  --_hue-text: var(--ui-text);
477
477
  --_on-hue: var(--ui-surface);
478
478
  }
479
- [data-component~="ui-button"][data-ui-button-state~="tone=danger"][data-v-6c8750a9],
480
- [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-6c8750a9] {
479
+ [data-component~="ui-button"][data-ui-button-state~="tone=danger"][data-v-75541d8a],
480
+ [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-75541d8a] {
481
481
  --_hue: var(--ui-danger);
482
482
  --_hue-hover: var(--ui-danger-hover);
483
483
  --_hue-active: var(--ui-danger-hover);
484
484
  --_hue-text: var(--ui-danger-hover);
485
485
  --_on-hue: var(--ui-on-danger);
486
486
  }
487
- [data-component~="ui-button"][data-ui-button-state~="tone=success"][data-v-6c8750a9] {
487
+ [data-component~="ui-button"][data-ui-button-state~="tone=success"][data-v-75541d8a] {
488
488
  --_hue: var(--ui-success);
489
489
  --_hue-hover: color-mix(in srgb, var(--ui-success) 85%, #000);
490
490
  --_hue-active: color-mix(in srgb, var(--ui-success) 75%, #000);
491
491
  --_hue-text: color-mix(in srgb, var(--ui-success) 85%, #000);
492
492
  --_on-hue: var(--ui-surface);
493
493
  }
494
- [data-component~="ui-button"][data-ui-button-state~="tone=warning"][data-v-6c8750a9] {
494
+ [data-component~="ui-button"][data-ui-button-state~="tone=warning"][data-v-75541d8a] {
495
495
  --_hue: var(--ui-warning);
496
496
  --_hue-hover: color-mix(in srgb, var(--ui-warning) 85%, #000);
497
497
  --_hue-active: color-mix(in srgb, var(--ui-warning) 75%, #000);
498
498
  --_hue-text: color-mix(in srgb, var(--ui-warning) 85%, #000);
499
499
  --_on-hue: var(--ui-surface);
500
500
  }
501
- [data-component~="ui-button"][data-ui-button-state~="tone=info"][data-v-6c8750a9] {
501
+ [data-component~="ui-button"][data-ui-button-state~="tone=info"][data-v-75541d8a] {
502
502
  --_hue: var(--ui-info);
503
503
  --_hue-hover: color-mix(in srgb, var(--ui-info) 85%, #000);
504
504
  --_hue-active: color-mix(in srgb, var(--ui-info) 75%, #000);
505
505
  --_hue-text: color-mix(in srgb, var(--ui-info) 85%, #000);
506
506
  --_on-hue: var(--ui-surface);
507
507
  }
508
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-6c8750a9] {
508
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-75541d8a] {
509
509
  border-color: transparent;
510
510
  background: transparent;
511
511
  box-shadow: none;
@@ -513,75 +513,66 @@ ol[data-v-0d86d58e] {
513
513
  }
514
514
 
515
515
  /* Tints derive from the text colour, not a surface token, so hover and press show on any background. */
516
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-6c8750a9]:hover:not(:disabled, [aria-disabled="true"]) {
516
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-75541d8a]:hover:not(:disabled, [aria-disabled="true"]) {
517
517
  background-color: var(--ui-button-ghost-hover-surface, oklch(from var(--_tone) l c h / 10%));
518
518
  border-color: transparent;
519
519
  }
520
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-6c8750a9]:active:not(:disabled, [aria-disabled="true"]) {
520
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-75541d8a]:active:not(:disabled, [aria-disabled="true"]) {
521
521
  background-color: var(--ui-button-ghost-active-surface, oklch(from var(--_tone) l c h / 16%));
522
522
  border-color: transparent;
523
523
  box-shadow: var(--ui-pressed);
524
524
  }
525
525
 
526
526
  /* A soft halo that transitions in with the other box-shadow changes, layered on the raised shadow. */
527
- [data-component~="ui-button"][data-v-6c8750a9]:focus-visible {
527
+ [data-component~="ui-button"][data-v-75541d8a]:focus-visible {
528
528
  outline: none;
529
529
  box-shadow:
530
530
  var(--ui-button-shadow, var(--ui-raised)),
531
531
  var(--ui-focus-halo);
532
532
  }
533
- [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-6c8750a9]:focus-visible {
533
+ [data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-75541d8a]:focus-visible {
534
534
  box-shadow:
535
535
  var(--ui-button-solid-shadow, var(--ui-raised)),
536
536
  var(--ui-focus-halo);
537
537
  }
538
538
 
539
- /* Disabled drops the tone rather than the shape: every variant keeps its own structure, so a
540
- disabled outline is still an outline and a disabled ghost still has no edge. Intent goes — an
541
- unavailable action says "unavailable", not "unavailable, and destructive" — and so do the
542
- highlight and shadow, because nothing that cannot be pressed should look raised. */
543
- [data-component~="ui-button"][data-v-6c8750a9]:is(:disabled, [aria-disabled="true"]) {
544
- /* Derived from the tone itself, not from a separate disabled palette: faded toward the
545
- page, which desaturates it at the same time. Toward the page rather than toward white,
546
- so a dark theme dims where a light one lightens — the same rule, both schemes. */
547
- --_tone: color-mix(in oklab, var(--_hue) 58%, var(--ui-surface));
548
- --_tone-hover: var(--_tone);
549
- --_tone-active: var(--_tone);
550
- --_tone-text: color-mix(in oklab, var(--_hue-text) 72%, var(--ui-surface));
551
- --_on-tone: var(--_tone-text);
552
-
539
+ /* Disabled keeps the shape and washes out the rest: every variant keeps its own structure, so a
540
+ disabled outline is still an outline and a disabled ghost still has no edge. One filter fades
541
+ fill, border, and text together (--ui-disabled-filter), and the theme decides which way is
542
+ toward the page. The highlight and shadow go, because nothing that cannot be pressed should
543
+ look raised. */
544
+ [data-component~="ui-button"][data-v-75541d8a]:is(:disabled, [aria-disabled="true"]) {
545
+ filter: var(--ui-button-disabled-filter, var(--ui-disabled-filter));
553
546
  opacity: var(--ui-button-disabled-opacity, 1);
554
547
  cursor: not-allowed;
555
548
  background-image: none;
556
549
  box-shadow: none;
557
550
  }
558
551
 
559
- /* A filled button keeps its fill, faded further so its text stays legible on it. */
560
- :is([data-component~="ui-button"][data-ui-button-state~="variant=solid"][data-v-6c8750a9], [data-component~="ui-button"][data-ui-button-state~="variant=danger"][data-v-6c8750a9]):is(:disabled, [aria-disabled="true"]) {
561
- --_tone: color-mix(in oklab, var(--_hue) 34%, var(--ui-surface));
562
- }
563
-
564
552
  /* Ghost has no hover to fall back on, so disabled is the one state it has to state outright:
565
553
  it takes a surface rather than reading as plain text. The surface is a wash of the faded tone,
566
554
  the way hover washes the live one, so it stays light in every tone. An opaque mix toward the
567
555
  hue came out a mid-grey slab for neutral, whose hue is the ink: louder than the enabled button. */
568
- [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-6c8750a9]:is(:disabled, [aria-disabled="true"]) {
556
+ [data-component~="ui-button"][data-ui-button-state~="variant=ghost"][data-v-75541d8a]:is(:disabled, [aria-disabled="true"]) {
569
557
  background-color: oklch(from var(--_tone) l c h / 14%);
570
558
  border-color: transparent;
571
559
  }
572
560
  @media (pointer: coarse) {
573
- [data-component~="ui-button"][data-v-6c8750a9] {
561
+ [data-component~="ui-button"][data-v-75541d8a] {
574
562
  min-block-size: var(--ui-control-min-block-size);
575
563
  }
576
564
  }
577
565
 
578
- /* Under touch, every button's press lands within the control minimum: an invisible hit area,
579
- centred on it, like IconButton's. A standalone link-style button (a "See all" beside a
580
- heading) is a target of its own, not text, so it gets one too. */
581
- html[data-ui-input-modality="touch"] [data-component~="ui-button"][data-v-6c8750a9] {
566
+ /* Under touch, a link-style button's press lands within the control minimum: an invisible hit
567
+ area, centred on it, like IconButton's. A boxed button grows to the minimum itself (below);
568
+ a link-style one keeps its text size, so a standalone one ("See all" under a list) needs the
569
+ area. Only the link needs it: a hit area on every button would reach over its neighbours. */
570
+ html[data-ui-input-modality="touch"]
571
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-75541d8a] {
582
572
  position: relative;
583
573
  }
584
- html[data-ui-input-modality="touch"] [data-component~="ui-button"][data-v-6c8750a9]::after {
574
+ html[data-ui-input-modality="touch"]
575
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-75541d8a]::after {
585
576
  position: absolute;
586
577
  inset: 50% auto auto 50%;
587
578
  inline-size: max(100%, var(--ui-control-min-block-size));
@@ -592,7 +583,7 @@ html[data-ui-input-modality="touch"] [data-component~="ui-button"][data-v-6c8750
592
583
 
593
584
  /* Link: an inline text action. No box, padding, or minimum height (inline targets are exempt under
594
585
  WCAG 2.5.8); the inherited font; an underline that strengthens on hover; a visible focus ring. */
595
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-6c8750a9] {
586
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-75541d8a] {
596
587
  display: inline;
597
588
  min-block-size: 0;
598
589
  padding: 0;
@@ -610,22 +601,21 @@ html[data-ui-input-modality="touch"] [data-component~="ui-button"][data-v-6c8750
610
601
  color var(--ui-motion-fast) var(--ui-motion-ease),
611
602
  text-decoration-color var(--ui-motion-fast) var(--ui-motion-ease);
612
603
  }
613
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-6c8750a9]:hover:not(:disabled, [aria-disabled="true"]) {
604
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-75541d8a]:hover:not(:disabled, [aria-disabled="true"]) {
614
605
  color: var(--ui-button-link-hover-text, var(--ui-text-primary));
615
606
  text-decoration-color: currentColor;
616
607
  background: none;
617
608
  transform: none;
618
609
  }
619
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-6c8750a9]:active:not(:disabled, [aria-disabled="true"]) {
610
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-75541d8a]:active:not(:disabled, [aria-disabled="true"]) {
620
611
  background: none;
621
612
  transform: none;
622
613
  }
623
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-6c8750a9]:is(:disabled, [aria-disabled="true"]) {
614
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-75541d8a]:is(:disabled, [aria-disabled="true"]) {
624
615
  background: none;
625
616
  border-color: transparent;
626
- color: var(--ui-button-disabled-text, var(--ui-disabled-text));
627
617
  }
628
- [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-6c8750a9]:focus-visible {
618
+ [data-component~="ui-button"][data-ui-button-state~="variant=link"][data-v-75541d8a]:focus-visible {
629
619
  box-shadow: none;
630
620
  /* Fallback keeps the ring if the token is missing: an unresolved var() would void the outline. */
631
621
  outline: 2px solid var(--ui-focus-ring);
@@ -633,7 +623,7 @@ html[data-ui-input-modality="touch"] [data-component~="ui-button"][data-v-6c8750
633
623
  }
634
624
 
635
625
  /* A component that sets its display still honours the hidden attribute on its root. */
636
- [data-component~="ui-button"][hidden][data-v-6c8750a9] {
626
+ [data-component~="ui-button"][hidden][data-v-75541d8a] {
637
627
  display: none;
638
628
  }
639
629
 
@@ -749,7 +739,7 @@ html[data-ui-input-modality="touch"] [data-component~="ui-button"][data-v-6c8750
749
739
  display: none;
750
740
  }
751
741
 
752
- [data-component~="ui-checkbox"][data-v-9c9d1eaa] {
742
+ [data-component~="ui-checkbox"][data-v-4d65c3b0] {
753
743
  display: inline-flex;
754
744
  align-items: flex-start;
755
745
  gap: var(--ui-checkbox-gap, var(--ui-space-2));
@@ -757,11 +747,27 @@ html[data-ui-input-modality="touch"] [data-component~="ui-button"][data-v-6c8750
757
747
  color: var(--ui-text-primary);
758
748
  cursor: pointer;
759
749
  }
760
- .label[data-v-9c9d1eaa] {
750
+
751
+ /* The label, and under it an optional line saying what the choice means. */
752
+ .text[data-v-4d65c3b0] {
753
+ display: flex;
754
+ flex-direction: column;
755
+ gap: var(--ui-space-1);
756
+ min-inline-size: 0;
757
+ }
758
+ .label[data-v-4d65c3b0] {
761
759
  min-inline-size: 0;
762
760
  line-height: var(--ui-line-height-md);
763
761
  }
764
- input[data-v-9c9d1eaa] {
762
+ .description[data-v-4d65c3b0] {
763
+ color: var(--ui-text-secondary);
764
+ font-size: var(--ui-font-size-sm);
765
+ line-height: var(--ui-line-height);
766
+ }
767
+ .description[data-v-4d65c3b0]:empty {
768
+ display: none;
769
+ }
770
+ input[data-v-4d65c3b0] {
765
771
  appearance: none;
766
772
  -webkit-appearance: none;
767
773
  position: relative;
@@ -779,20 +785,20 @@ input[data-v-9c9d1eaa] {
779
785
  border-color var(--ui-motion-fast) var(--ui-motion-ease),
780
786
  box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
781
787
  }
782
- input[data-v-9c9d1eaa]::after {
788
+ input[data-v-4d65c3b0]::after {
783
789
  content: "";
784
790
  position: absolute;
785
791
  opacity: 0;
786
792
  }
787
- input[data-v-9c9d1eaa]:checked,
788
- input[data-v-9c9d1eaa]:indeterminate {
793
+ input[data-v-4d65c3b0]:checked,
794
+ input[data-v-4d65c3b0]:indeterminate {
789
795
  border-color: var(--ui-accent-solid);
790
796
  background: var(--ui-accent-solid);
791
797
  box-shadow: inset 0 1px 2px color-mix(in srgb, #000 16%, transparent);
792
798
  }
793
799
 
794
800
  /* Centre the tick's box, then lift it: a rotated L's ink sits ~0.11rem below its box centre. */
795
- input[data-v-9c9d1eaa]:checked::after {
801
+ input[data-v-4d65c3b0]:checked::after {
796
802
  inset: 0;
797
803
  margin: auto;
798
804
  inline-size: 0.32rem;
@@ -805,7 +811,7 @@ input[data-v-9c9d1eaa]:checked::after {
805
811
  opacity: 1;
806
812
  transform: translateY(-0.11rem) rotate(45deg);
807
813
  }
808
- input[data-v-9c9d1eaa]:indeterminate::after {
814
+ input[data-v-4d65c3b0]:indeterminate::after {
809
815
  inset: 50% 0.23rem auto;
810
816
  block-size: 0.125rem;
811
817
  border-radius: var(--ui-radius-round);
@@ -813,25 +819,25 @@ input[data-v-9c9d1eaa]:indeterminate::after {
813
819
  opacity: 1;
814
820
  transform: translateY(-50%);
815
821
  }
816
- input[data-v-9c9d1eaa]:hover:enabled {
822
+ input[data-v-4d65c3b0]:hover:enabled {
817
823
  border-color: var(--ui-accent-solid);
818
824
  }
819
- input[data-v-9c9d1eaa]:focus-visible {
825
+ input[data-v-4d65c3b0]:focus-visible {
820
826
  outline: 2px solid var(--ui-focus-ring, var(--ui-accent-solid));
821
827
  outline-offset: 2px;
822
828
  }
823
- [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"][data-v-9c9d1eaa] {
829
+ [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"][data-v-4d65c3b0] {
824
830
  color: var(--ui-text-muted);
825
831
  cursor: not-allowed;
826
832
  }
827
- [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"] input[data-v-9c9d1eaa] {
833
+ [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"] input[data-v-4d65c3b0] {
828
834
  border-color: var(--ui-border-default);
829
835
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
830
836
  cursor: not-allowed;
831
837
  }
832
838
 
833
839
  /* A component that sets its display still honours the hidden attribute on its root. */
834
- [data-component~="ui-checkbox"][hidden][data-v-9c9d1eaa] {
840
+ [data-component~="ui-checkbox"][hidden][data-v-4d65c3b0] {
835
841
  display: none;
836
842
  }
837
843
 
@@ -2969,14 +2975,14 @@ svg[data-v-dc9b5621-s] {
2969
2975
  display: none;
2970
2976
  }
2971
2977
 
2972
- [data-component~="ui-icon-button"][data-v-bcedd63e] {
2978
+ [data-component~="ui-icon-button"][data-v-c322b7ed] {
2973
2979
  display: inline-flex;
2974
2980
  color: var(--ui-text-secondary);
2975
2981
  }
2976
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-bcedd63e] {
2982
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-c322b7ed] {
2977
2983
  position: relative;
2978
2984
  }
2979
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-bcedd63e]::before {
2985
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-c322b7ed]::before {
2980
2986
  content: "";
2981
2987
  position: absolute;
2982
2988
  inset: 50% auto auto 50%;
@@ -2995,17 +3001,17 @@ svg[data-v-dc9b5621-s] {
2995
3001
  * surface and icon. The root is the native button, so hiding it outright would hide the dot
2996
3002
  * too, and slotted icons sit outside this scope; `color: transparent` hides currentColor icons. */
2997
3003
  @media (hover: hover) and (pointer: fine) {
2998
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-bcedd63e]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible) {
3004
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-c322b7ed]:not([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible) {
2999
3005
  border-color: transparent;
3000
3006
  background: transparent;
3001
3007
  box-shadow: none;
3002
3008
  color: transparent;
3003
3009
  }
3004
3010
  }
3005
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-bcedd63e]:is([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
3011
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-c322b7ed]:is([data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"], [data-ui-proximity="near"], :hover, :focus-visible)::before {
3006
3012
  opacity: 0;
3007
3013
  }
3008
- [data-component~="ui-icon-button"][data-v-bcedd63e] {
3014
+ [data-component~="ui-icon-button"][data-v-c322b7ed] {
3009
3015
  /* The size prop resolves here; --ui-icon-button-size overrides it on an element. */
3010
3016
  --_size: 2rem;
3011
3017
  appearance: none;
@@ -3031,7 +3037,7 @@ svg[data-v-dc9b5621-s] {
3031
3037
  transform var(--ui-motion-fast) var(--ui-motion-ease);
3032
3038
  }
3033
3039
  @media (hover: none), (pointer: coarse) {
3034
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-bcedd63e]::before {
3040
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="anticipatory"][data-v-c322b7ed]::before {
3035
3041
  opacity: 0;
3036
3042
  }
3037
3043
  }
@@ -3039,10 +3045,10 @@ svg[data-v-dc9b5621-s] {
3039
3045
  /* A touch target without a bigger button: an invisible hit area, at least the control
3040
3046
  minimum, centred on the button (::before is the anticipatory guide). */
3041
3047
  @media (pointer: coarse) {
3042
- [data-component~="ui-icon-button"][data-v-bcedd63e] {
3048
+ [data-component~="ui-icon-button"][data-v-c322b7ed] {
3043
3049
  position: relative;
3044
3050
  }
3045
- [data-component~="ui-icon-button"][data-v-bcedd63e]::after {
3051
+ [data-component~="ui-icon-button"][data-v-c322b7ed]::after {
3046
3052
  content: "";
3047
3053
  position: absolute;
3048
3054
  inset: 50% auto auto 50%;
@@ -3051,10 +3057,10 @@ svg[data-v-dc9b5621-s] {
3051
3057
  transform: translate(-50%, -50%);
3052
3058
  }
3053
3059
  }
3054
- html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-bcedd63e] {
3060
+ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-c322b7ed] {
3055
3061
  position: relative;
3056
3062
  }
3057
- html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-bcedd63e]::after {
3063
+ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-c322b7ed]::after {
3058
3064
  content: "";
3059
3065
  position: absolute;
3060
3066
  inset: 50% auto auto 50%;
@@ -3062,29 +3068,29 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-b
3062
3068
  block-size: max(100%, var(--ui-control-min-block-size));
3063
3069
  transform: translate(-50%, -50%);
3064
3070
  }
3065
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-bcedd63e] {
3071
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-c322b7ed] {
3066
3072
  --_size: 1.75rem;
3067
3073
  inline-size: var(--ui-icon-button-size, var(--_size));
3068
3074
  block-size: var(--ui-icon-button-size, var(--_size));
3069
3075
  min-inline-size: var(--ui-icon-button-size, var(--_size));
3070
3076
  min-block-size: var(--ui-icon-button-size, var(--_size));
3071
3077
  }
3072
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-bcedd63e] {
3078
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-c322b7ed] {
3073
3079
  --_size: 2.5rem;
3074
3080
  inline-size: var(--ui-icon-button-size, var(--_size));
3075
3081
  block-size: var(--ui-icon-button-size, var(--_size));
3076
3082
  min-inline-size: var(--ui-icon-button-size, var(--_size));
3077
3083
  min-block-size: var(--ui-icon-button-size, var(--_size));
3078
3084
  }
3079
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"][data-v-bcedd63e] {
3085
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"][data-v-c322b7ed] {
3080
3086
  border-radius: var(--ui-radius-round);
3081
3087
  }
3082
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-bcedd63e] {
3088
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-c322b7ed] {
3083
3089
  border-color: var(--ui-icon-button-border, var(--ui-border-default));
3084
3090
  background: var(--ui-icon-button-outline-surface, var(--ui-surface-default));
3085
3091
  color: var(--ui-icon-button-outline-text, var(--ui-text-primary));
3086
3092
  }
3087
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-bcedd63e] {
3093
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-c322b7ed] {
3088
3094
  background: var(--ui-icon-button-solid-surface, var(--ui-accent-solid));
3089
3095
  color: var(--ui-icon-button-solid-text, var(--ui-text-on-accent));
3090
3096
  box-shadow: var(
@@ -3092,51 +3098,43 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"][data-v-b
3092
3098
  0 1px 2px color-mix(in srgb, var(--ui-accent-solid) 18%, transparent)
3093
3099
  );
3094
3100
  }
3095
- [data-component~="ui-icon-button"][data-v-bcedd63e]:hover:enabled {
3101
+ [data-component~="ui-icon-button"][data-v-c322b7ed]:hover:enabled {
3096
3102
  /* Derived from the text colour so the ghost hover shows on any background. */
3097
3103
  background: var(--ui-icon-button-hover-surface, color-mix(in srgb, currentColor 8%, transparent));
3098
3104
  color: var(--ui-icon-button-hover-text, var(--ui-text-primary));
3099
3105
  }
3100
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-bcedd63e]:hover:enabled {
3106
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-c322b7ed]:hover:enabled {
3101
3107
  border-color: var(--ui-icon-button-hover-border, var(--ui-border-strong));
3102
3108
  }
3103
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-bcedd63e]:hover:enabled {
3109
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-c322b7ed]:hover:enabled {
3104
3110
  background: var(--ui-icon-button-solid-hover-surface, var(--ui-accent-hover));
3105
3111
  }
3106
- [data-component~="ui-icon-button"][data-v-bcedd63e]:active:enabled {
3112
+ [data-component~="ui-icon-button"][data-v-c322b7ed]:active:enabled {
3107
3113
  transform: scale(var(--ui-icon-button-active-scale, 0.96));
3108
3114
  }
3109
- [data-component~="ui-icon-button"][data-v-bcedd63e]:focus-visible {
3115
+ [data-component~="ui-icon-button"][data-v-c322b7ed]:focus-visible {
3110
3116
  outline: none;
3111
3117
  box-shadow: var(--ui-focus-halo);
3112
3118
  }
3113
3119
 
3114
3120
  /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
3115
- [data-component~="ui-icon-button"][data-v-bcedd63e]:disabled {
3121
+ /* Disabled washes the button out the way Button does: the same shape, one filter. */
3122
+ [data-component~="ui-icon-button"][data-v-c322b7ed]:disabled {
3123
+ filter: var(--ui-icon-button-disabled-filter, var(--ui-disabled-filter));
3116
3124
  opacity: var(--ui-icon-button-disabled-opacity, 1);
3117
- color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
3118
3125
  cursor: not-allowed;
3126
+ box-shadow: none;
3119
3127
  }
3120
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"][data-v-bcedd63e]:disabled {
3121
- border-color: var(--ui-icon-button-disabled-border, var(--ui-border));
3122
- background-color: var(--ui-icon-button-disabled-surface, var(--ui-disabled-surface));
3123
- color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
3124
- }
3125
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"][data-v-bcedd63e]:disabled {
3126
- border-color: var(--ui-icon-button-disabled-border, var(--ui-border));
3127
- background-color: var(--ui-icon-button-disabled-surface, var(--ui-disabled-surface));
3128
- color: var(--ui-icon-button-disabled-text, var(--ui-disabled-text));
3129
- }
3130
- [data-component~="ui-icon-button"][data-v-bcedd63e] {
3128
+ [data-component~="ui-icon-button"][data-v-c322b7ed] {
3131
3129
  --_icon-button-icon-default: var(--ui-icon-size-md);
3132
3130
  }
3133
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-bcedd63e] {
3131
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"][data-v-c322b7ed] {
3134
3132
  --_icon-button-icon-default: var(--ui-icon-size-sm);
3135
3133
  }
3136
- [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-bcedd63e] {
3134
+ [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"][data-v-c322b7ed] {
3137
3135
  --_icon-button-icon-default: var(--ui-icon-size-lg);
3138
3136
  }
3139
- svg[data-v-bcedd63e-s] {
3137
+ svg[data-v-c322b7ed-s] {
3140
3138
  inline-size: var(--ui-icon-button-icon-size, var(--_icon-button-icon-default));
3141
3139
  block-size: var(--ui-icon-button-icon-size, var(--_icon-button-icon-default));
3142
3140
  flex-shrink: 0;
@@ -3144,7 +3142,7 @@ svg[data-v-bcedd63e-s] {
3144
3142
  }
3145
3143
 
3146
3144
  /* A component that sets its display still honours the hidden attribute on its root. */
3147
- [data-component~="ui-icon-button"][hidden][data-v-bcedd63e] {
3145
+ [data-component~="ui-icon-button"][hidden][data-v-c322b7ed] {
3148
3146
  display: none;
3149
3147
  }
3150
3148
 
@@ -3696,7 +3694,7 @@ svg[data-v-bcedd63e-s] {
3696
3694
  }
3697
3695
  }
3698
3696
 
3699
- [data-component~="ui-radio"][data-v-e31949a7] {
3697
+ [data-component~="ui-radio"][data-v-f9c61d50] {
3700
3698
  display: inline-flex;
3701
3699
  align-items: flex-start;
3702
3700
  gap: var(--ui-radio-gap, var(--ui-space-2));
@@ -3704,11 +3702,27 @@ svg[data-v-bcedd63e-s] {
3704
3702
  color: var(--ui-text-primary);
3705
3703
  cursor: pointer;
3706
3704
  }
3707
- .label[data-v-e31949a7] {
3705
+
3706
+ /* The label, and under it an optional line saying what the choice means. */
3707
+ .text[data-v-f9c61d50] {
3708
+ display: flex;
3709
+ flex-direction: column;
3710
+ gap: var(--ui-space-1);
3711
+ min-inline-size: 0;
3712
+ }
3713
+ .label[data-v-f9c61d50] {
3708
3714
  min-inline-size: 0;
3709
3715
  line-height: var(--ui-line-height-md);
3710
3716
  }
3711
- input[data-v-e31949a7] {
3717
+ .description[data-v-f9c61d50] {
3718
+ color: var(--ui-text-secondary);
3719
+ font-size: var(--ui-font-size-sm);
3720
+ line-height: var(--ui-line-height);
3721
+ }
3722
+ .description[data-v-f9c61d50]:empty {
3723
+ display: none;
3724
+ }
3725
+ input[data-v-f9c61d50] {
3712
3726
  flex: 0 0 auto;
3713
3727
  inline-size: var(--ui-radio-size, 1.125rem);
3714
3728
  block-size: var(--ui-radio-size, 1.125rem);
@@ -3716,20 +3730,20 @@ input[data-v-e31949a7] {
3716
3730
  accent-color: var(--ui-accent-solid);
3717
3731
  cursor: pointer;
3718
3732
  }
3719
- input[data-v-e31949a7]:focus-visible {
3733
+ input[data-v-f9c61d50]:focus-visible {
3720
3734
  outline: 2px solid var(--ui-focus-ring, var(--ui-accent-solid));
3721
3735
  outline-offset: 2px;
3722
3736
  }
3723
- [data-component~="ui-radio"][data-ui-radio-state~="disabled"][data-v-e31949a7] {
3737
+ [data-component~="ui-radio"][data-ui-radio-state~="disabled"][data-v-f9c61d50] {
3724
3738
  color: var(--ui-text-muted);
3725
3739
  cursor: not-allowed;
3726
3740
  }
3727
- [data-component~="ui-radio"][data-ui-radio-state~="disabled"] input[data-v-e31949a7] {
3741
+ [data-component~="ui-radio"][data-ui-radio-state~="disabled"] input[data-v-f9c61d50] {
3728
3742
  cursor: not-allowed;
3729
3743
  }
3730
3744
 
3731
3745
  /* A component that sets its display still honours the hidden attribute on its root. */
3732
- [data-component~="ui-radio"][hidden][data-v-e31949a7] {
3746
+ [data-component~="ui-radio"][hidden][data-v-f9c61d50] {
3733
3747
  display: none;
3734
3748
  }
3735
3749
 
@@ -4566,7 +4580,7 @@ to {
4566
4580
  display: none;
4567
4581
  }
4568
4582
 
4569
- [data-component~="ui-switch"][data-v-26ab3add] {
4583
+ [data-component~="ui-switch"][data-v-85cb3260] {
4570
4584
  display: inline-flex;
4571
4585
  align-items: flex-start;
4572
4586
  gap: var(--ui-switch-gap, var(--ui-space-2));
@@ -4574,11 +4588,27 @@ to {
4574
4588
  color: var(--ui-text-primary);
4575
4589
  cursor: pointer;
4576
4590
  }
4577
- .label[data-v-26ab3add] {
4591
+
4592
+ /* The label, and under it an optional line saying what the choice means. */
4593
+ .text[data-v-85cb3260] {
4594
+ display: flex;
4595
+ flex-direction: column;
4596
+ gap: var(--ui-space-1);
4597
+ min-inline-size: 0;
4598
+ }
4599
+ .label[data-v-85cb3260] {
4578
4600
  min-inline-size: 0;
4579
4601
  line-height: var(--ui-line-height-md);
4580
4602
  }
4581
- input[data-v-26ab3add] {
4603
+ .description[data-v-85cb3260] {
4604
+ color: var(--ui-text-secondary);
4605
+ font-size: var(--ui-font-size-sm);
4606
+ line-height: var(--ui-line-height);
4607
+ }
4608
+ .description[data-v-85cb3260]:empty {
4609
+ display: none;
4610
+ }
4611
+ input[data-v-85cb3260] {
4582
4612
  appearance: none;
4583
4613
  -webkit-appearance: none;
4584
4614
  position: relative;
@@ -4596,7 +4626,7 @@ input[data-v-26ab3add] {
4596
4626
  border-color var(--ui-motion-fast) var(--ui-motion-ease);
4597
4627
  margin: 0;
4598
4628
  }
4599
- input[data-v-26ab3add]::after {
4629
+ input[data-v-85cb3260]::after {
4600
4630
  content: "";
4601
4631
  position: absolute;
4602
4632
  top: 3px;
@@ -4608,35 +4638,35 @@ input[data-v-26ab3add]::after {
4608
4638
  box-shadow: var(--ui-shadow-xs);
4609
4639
  transition: transform var(--ui-motion-fast) var(--ui-motion-ease);
4610
4640
  }
4611
- input[data-v-26ab3add]:checked {
4641
+ input[data-v-85cb3260]:checked {
4612
4642
  background: var(--ui-accent-solid);
4613
4643
  border-color: var(--ui-accent-solid);
4614
4644
  }
4615
- input[data-v-26ab3add]:checked::after {
4645
+ input[data-v-85cb3260]:checked::after {
4616
4646
  transform: translateX(1rem);
4617
4647
  background: var(--ui-text-on-accent);
4618
4648
  }
4619
- input[data-v-26ab3add]:focus-visible {
4649
+ input[data-v-85cb3260]:focus-visible {
4620
4650
  outline: 2px solid var(--ui-focus-ring, var(--ui-accent-solid));
4621
4651
  outline-offset: 2px;
4622
4652
  }
4623
- [data-component~="ui-switch"][data-ui-switch-state~="disabled"][data-v-26ab3add] {
4653
+ [data-component~="ui-switch"][data-ui-switch-state~="disabled"][data-v-85cb3260] {
4624
4654
  color: var(--ui-text-muted);
4625
4655
  cursor: not-allowed;
4626
4656
  }
4627
- [data-component~="ui-switch"][data-ui-switch-state~="disabled"] input[data-v-26ab3add] {
4657
+ [data-component~="ui-switch"][data-ui-switch-state~="disabled"] input[data-v-85cb3260] {
4628
4658
  border-color: var(--ui-border-default);
4629
4659
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
4630
4660
  cursor: not-allowed;
4631
4661
  }
4632
4662
  @media (prefers-reduced-motion: reduce) {
4633
- input[data-v-26ab3add], input[data-v-26ab3add]::after {
4663
+ input[data-v-85cb3260], input[data-v-85cb3260]::after {
4634
4664
  transition: none;
4635
4665
  }
4636
4666
  }
4637
4667
 
4638
4668
  /* A component that sets its display still honours the hidden attribute on its root. */
4639
- [data-component~="ui-switch"][hidden][data-v-26ab3add] {
4669
+ [data-component~="ui-switch"][hidden][data-v-85cb3260] {
4640
4670
  display: none;
4641
4671
  }
4642
4672