@threadlabs/looma 0.11.3 → 0.11.4

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.11.3",
3
+ "version": "0.11.4",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -64,6 +64,8 @@
64
64
  --_callout-icon: var(--ui-danger-solid);
65
65
  }
66
66
 
67
+ /* A link in the callout's text is underlined, so it reads as a link by more than colour. */
68
+
67
69
  /* A component that sets its display still honours the hidden attribute on its root. */
68
70
  :scope[hidden] {
69
71
  display: none;
@@ -72,5 +74,13 @@
72
74
  @scope ([data-component~="ui-callout"]) to ([data-component]) {
73
75
  /* One line box tall, so the icon centres on the first line of text. */
74
76
 
77
+ /* A link in the callout's text is underlined, so it reads as a link by more than colour. */
78
+ .content :where([data-slotted], [data-slotted] *):is(a) {
79
+ color: var(--ui-accent-active);
80
+ text-decoration: underline;
81
+ text-decoration-thickness: 0.06em;
82
+ text-underline-offset: 0.18em;
83
+ }
84
+
75
85
  /* A component that sets its display still honours the hidden attribute on its root. */
76
86
  }
@@ -27,6 +27,8 @@
27
27
  line-height: var(--ui-line-height-md);
28
28
  }
29
29
 
30
+ /* An error reads in the danger colour, the one the invalid control's border takes. */
31
+
30
32
  /* A component that sets its display still honours the hidden attribute on its root. */
31
33
  :scope[hidden] {
32
34
  display: none;
@@ -40,9 +42,10 @@
40
42
  min-block-size: var(--ui-form-field-help-min-block-size, 0);
41
43
  }
42
44
 
45
+ /* An error reads in the danger colour, the one the invalid control's border takes. */
43
46
  .error,
44
47
  :where([data-slotted], [data-slotted] *):is([role="alert"]) {
45
- color: var(--ui-accent-active);
48
+ color: var(--ui-danger);
46
49
  font-size: var(--ui-font-size-sm);
47
50
  }
48
51
 
@@ -10,6 +10,8 @@
10
10
  --ui-input-border: transparent;
11
11
  --ui-input-border-hover: transparent;
12
12
  --ui-input-focus-border: transparent;
13
+ --ui-input-invalid-border: transparent;
14
+ --ui-input-invalid-focus-shadow: none;
13
15
  --ui-input-shadow: none;
14
16
  --ui-input-focus-shadow: none;
15
17
  --ui-input-radius: 0;
@@ -46,13 +46,15 @@
46
46
  /* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
47
47
  :scope[aria-invalid="true"],
48
48
  :scope:is(:user-invalid, [data-user-invalid]) {
49
- border-color: var(--ui-danger-solid);
49
+ border-color: var(--ui-input-invalid-border, var(--ui-danger-solid));
50
50
  }
51
51
 
52
52
  :scope:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
53
- box-shadow:
53
+ box-shadow: var(
54
+ --ui-input-invalid-focus-shadow,
54
55
  var(--ui-control-inset),
55
- 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
56
+ 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent)
57
+ );
56
58
  }
57
59
 
58
60
  :scope:disabled {
@@ -62,6 +62,9 @@
62
62
  font-family: var(--ui-font-family-mono);
63
63
  }
64
64
 
65
+ /* A link in running text is underlined, so it stands apart from the words around it by more than
66
+ colour. */
67
+
65
68
  :scope[data-ui-text-state~="truncate"] {
66
69
  overflow: hidden;
67
70
  text-overflow: ellipsis;
@@ -81,5 +84,14 @@
81
84
  /* Running text, set on the type scale and in a tone that says what it is, so a view never styles
82
85
  text of its own. The root is a paragraph unless as= names a span, div, small, strong, or label. */
83
86
 
87
+ /* A link in running text is underlined, so it stands apart from the words around it by more than
88
+ colour. */
89
+ :scope :where([data-slotted], [data-slotted] *):is(a) {
90
+ color: var(--ui-accent-active);
91
+ text-decoration: underline;
92
+ text-decoration-thickness: 0.06em;
93
+ text-underline-offset: 0.18em;
94
+ }
95
+
84
96
  /* A component that sets its display still honours the hidden attribute on its root. */
85
97
  }
package/vue/UiCallout.vue CHANGED
@@ -164,6 +164,14 @@ const hostState = computed(() =>
164
164
  --_callout-icon: var(--ui-danger-solid);
165
165
  }
166
166
 
167
+ /* A link in the callout's text is underlined, so it reads as a link by more than colour. */
168
+ .content :slotted(a) {
169
+ color: var(--ui-accent-active);
170
+ text-decoration: underline;
171
+ text-decoration-thickness: 0.06em;
172
+ text-underline-offset: 0.18em;
173
+ }
174
+
167
175
  /* A component that sets its display still honours the hidden attribute on its root. */
168
176
  [data-component~="ui-callout"][hidden] {
169
177
  display: none;
@@ -71,9 +71,10 @@ useComponentHost(controllerModule.default, {
71
71
  min-block-size: var(--ui-form-field-help-min-block-size, 0);
72
72
  }
73
73
 
74
+ /* An error reads in the danger colour, the one the invalid control's border takes. */
74
75
  .error,
75
76
  :slotted([role="alert"]) {
76
- color: var(--ui-accent-active);
77
+ color: var(--ui-danger);
77
78
  font-size: var(--ui-font-size-sm);
78
79
  }
79
80
 
package/vue/UiInput.vue CHANGED
@@ -108,13 +108,15 @@ useComponentHost(controllerModule.default, {
108
108
  /* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
109
109
  [data-component~="ui-input"][aria-invalid="true"],
110
110
  [data-component~="ui-input"]:is(:user-invalid, [data-user-invalid]) {
111
- border-color: var(--ui-danger-solid);
111
+ border-color: var(--ui-input-invalid-border, var(--ui-danger-solid));
112
112
  }
113
113
 
114
114
  [data-component~="ui-input"]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
115
- box-shadow:
115
+ box-shadow: var(
116
+ --ui-input-invalid-focus-shadow,
116
117
  var(--ui-control-inset),
117
- 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
118
+ 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent)
119
+ );
118
120
  }
119
121
 
120
122
  [data-component~="ui-input"]:disabled {
@@ -44,6 +44,8 @@ const hostState = computed(() =>
44
44
  --ui-input-border: transparent;
45
45
  --ui-input-border-hover: transparent;
46
46
  --ui-input-focus-border: transparent;
47
+ --ui-input-invalid-border: transparent;
48
+ --ui-input-invalid-focus-shadow: none;
47
49
  --ui-input-shadow: none;
48
50
  --ui-input-focus-shadow: none;
49
51
  --ui-input-radius: 0;
package/vue/UiText.vue CHANGED
@@ -108,6 +108,15 @@ const hostState = computed(() =>
108
108
  font-family: var(--ui-font-family-mono);
109
109
  }
110
110
 
111
+ /* A link in running text is underlined, so it stands apart from the words around it by more than
112
+ colour. */
113
+ [data-component~="ui-text"] :slotted(a) {
114
+ color: var(--ui-accent-active);
115
+ text-decoration: underline;
116
+ text-decoration-thickness: 0.06em;
117
+ text-underline-offset: 0.18em;
118
+ }
119
+
111
120
  [data-component~="ui-text"][data-ui-text-state~="truncate"] {
112
121
  overflow: hidden;
113
122
  text-overflow: ellipsis;
@@ -100,9 +100,9 @@ var UiCallout_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
100
100
  createElementVNode("path", { d: "m15 9-6 6" }, null, -1),
101
101
  createElementVNode("path", { d: "m9 9 6 6" }, null, -1)
102
102
  ])])) : createCommentVNode("v-if", true)
103
- ]), createElementVNode("div", _hoisted_8, [renderSlot(_ctx.$slots, "default", {}, void 0, true)])], 16, _hoisted_1);
103
+ ]), createElementVNode("div", _hoisted_8, [renderSlot(_ctx.$slots, "default")])], 16, _hoisted_1);
104
104
  };
105
105
  }
106
- }), [["__scopeId", "data-v-2fd6ab30"]]);
106
+ }), [["__scopeId", "data-v-36fb7e55"]]);
107
107
  //#endregion
108
108
  export { UiCallout_default as t };
@@ -46,6 +46,6 @@ var UiFormField_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
46
46
  ], 16);
47
47
  };
48
48
  }
49
- }), [["__scopeId", "data-v-eba1e76b"]]);
49
+ }), [["__scopeId", "data-v-4df6c2a6"]]);
50
50
  //#endregion
51
51
  export { UiFormField_default as t };
@@ -61,6 +61,6 @@ var UiInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
61
61
  }), null, 16, _hoisted_1)), [[vModelDynamic, model.value]]);
62
62
  };
63
63
  }
64
- }), [["__scopeId", "data-v-12ffae5a"]]);
64
+ }), [["__scopeId", "data-v-c19f8322"]]);
65
65
  //#endregion
66
66
  export { UiInput_default as t };
@@ -26,6 +26,6 @@ var UiInputGroup_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
26
26
  ], 16, _hoisted_1);
27
27
  };
28
28
  }
29
- }), [["__scopeId", "data-v-0a135fc1"]]);
29
+ }), [["__scopeId", "data-v-42ff173c"]]);
30
30
  //#endregion
31
31
  export { UiInputGroup_default as t };
@@ -30,11 +30,11 @@ var UiText_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
30
30
  ].filter(Boolean).join(" "));
31
31
  return (_ctx, _cache) => {
32
32
  return openBlock(), createBlock(resolveDynamicComponent(__props.as), mergeProps({ "data-component": "ui-text" }, _ctx.$attrs, { "data-ui-text-state": hostState.value || void 0 }), {
33
- default: withCtx(() => [renderSlot(_ctx.$slots, "default", {}, void 0, true)]),
33
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
34
34
  _: 3
35
35
  }, 16, ["data-ui-text-state"]);
36
36
  };
37
37
  }
38
- }), [["__scopeId", "data-v-70a75450"]]);
38
+ }), [["__scopeId", "data-v-b83a3ab9"]]);
39
39
  //#endregion
40
40
  export { UiText_default as t };
@@ -622,7 +622,7 @@ ol[data-v-0d86d58e] {
622
622
  display: none;
623
623
  }
624
624
 
625
- [data-component~="ui-callout"][data-v-2fd6ab30] {
625
+ [data-component~="ui-callout"][data-v-36fb7e55] {
626
626
  --_callout-surface: var(--ui-info-soft);
627
627
  --_callout-border: var(--ui-info-solid);
628
628
  --_callout-icon: var(--ui-info-solid);
@@ -648,43 +648,51 @@ ol[data-v-0d86d58e] {
648
648
  }
649
649
 
650
650
  /* One line box tall, so the icon centres on the first line of text. */
651
- .icon[data-v-2fd6ab30] {
651
+ .icon[data-v-36fb7e55] {
652
652
  display: grid;
653
653
  place-items: center;
654
654
  inline-size: var(--ui-callout-icon-column, 1.125rem);
655
655
  block-size: 1lh;
656
656
  color: var(--ui-callout-icon, var(--_callout-icon));
657
657
  }
658
- .icon svg[data-v-2fd6ab30] {
658
+ .icon svg[data-v-36fb7e55] {
659
659
  inline-size: var(--ui-callout-icon-size, 1.125rem);
660
660
  block-size: var(--ui-callout-icon-size, 1.125rem);
661
661
  }
662
- .content[data-v-2fd6ab30] {
662
+ .content[data-v-36fb7e55] {
663
663
  min-inline-size: 0;
664
664
  }
665
- [data-component~="ui-callout"][data-ui-callout-state~="tone=note"][data-v-2fd6ab30] {
665
+ [data-component~="ui-callout"][data-ui-callout-state~="tone=note"][data-v-36fb7e55] {
666
666
  --_callout-surface: var(--ui-surface-muted);
667
667
  --_callout-border: var(--ui-border-strong);
668
668
  --_callout-icon: var(--ui-text-secondary);
669
669
  }
670
- [data-component~="ui-callout"][data-ui-callout-state~="tone=warning"][data-v-2fd6ab30] {
670
+ [data-component~="ui-callout"][data-ui-callout-state~="tone=warning"][data-v-36fb7e55] {
671
671
  --_callout-surface: var(--ui-warning-soft);
672
672
  --_callout-border: var(--ui-warning-solid);
673
673
  --_callout-icon: var(--ui-warning-solid);
674
674
  }
675
- [data-component~="ui-callout"][data-ui-callout-state~="tone=success"][data-v-2fd6ab30] {
675
+ [data-component~="ui-callout"][data-ui-callout-state~="tone=success"][data-v-36fb7e55] {
676
676
  --_callout-surface: var(--ui-success-soft);
677
677
  --_callout-border: var(--ui-success-solid);
678
678
  --_callout-icon: var(--ui-success-solid);
679
679
  }
680
- [data-component~="ui-callout"][data-ui-callout-state~="tone=danger"][data-v-2fd6ab30] {
680
+ [data-component~="ui-callout"][data-ui-callout-state~="tone=danger"][data-v-36fb7e55] {
681
681
  --_callout-surface: var(--ui-danger-soft);
682
682
  --_callout-border: var(--ui-danger-solid);
683
683
  --_callout-icon: var(--ui-danger-solid);
684
684
  }
685
685
 
686
+ /* A link in the callout's text is underlined, so it reads as a link by more than colour. */
687
+ .content a[data-v-36fb7e55-s] {
688
+ color: var(--ui-accent-active);
689
+ text-decoration: underline;
690
+ text-decoration-thickness: 0.06em;
691
+ text-underline-offset: 0.18em;
692
+ }
693
+
686
694
  /* A component that sets its display still honours the hidden attribute on its root. */
687
- [data-component~="ui-callout"][hidden][data-v-2fd6ab30] {
695
+ [data-component~="ui-callout"][hidden][data-v-36fb7e55] {
688
696
  display: none;
689
697
  }
690
698
 
@@ -2869,7 +2877,7 @@ svg[data-v-dc9b5621-s] {
2869
2877
  display: none;
2870
2878
  }
2871
2879
 
2872
- [data-component~="ui-form-field"][data-v-eba1e76b] {
2880
+ [data-component~="ui-form-field"][data-v-4df6c2a6] {
2873
2881
  display: grid;
2874
2882
  gap: var(--ui-space-2);
2875
2883
  min-inline-size: 0;
@@ -2879,30 +2887,32 @@ svg[data-v-dc9b5621-s] {
2879
2887
 
2880
2888
  /* Each named region styles whatever fills it, however it was slotted (slot="…" in HTML, #label
2881
2889
  in Vue), and generates no box of its own, so an empty region adds no gap. */
2882
- .label[data-v-eba1e76b],
2883
- .help[data-v-eba1e76b],
2884
- .error[data-v-eba1e76b] {
2890
+ .label[data-v-4df6c2a6],
2891
+ .help[data-v-4df6c2a6],
2892
+ .error[data-v-4df6c2a6] {
2885
2893
  display: contents;
2886
2894
  }
2887
- .label[data-v-eba1e76b] {
2895
+ .label[data-v-4df6c2a6] {
2888
2896
  color: var(--ui-text-secondary);
2889
2897
  font-size: var(--ui-font-size-sm);
2890
2898
  }
2891
- .help[data-v-eba1e76b] {
2899
+ .help[data-v-4df6c2a6] {
2892
2900
  color: var(--ui-text-muted);
2893
2901
  font-size: var(--ui-font-size-sm);
2894
2902
  line-height: var(--ui-line-height-md);
2895
2903
  }
2896
- .help > [data-v-eba1e76b-s] {
2904
+ .help > [data-v-4df6c2a6-s] {
2897
2905
  min-block-size: var(--ui-form-field-help-min-block-size, 0);
2898
2906
  }
2899
- .error[data-v-eba1e76b],[role="alert"][data-v-eba1e76b-s] {
2900
- color: var(--ui-accent-active);
2907
+
2908
+ /* An error reads in the danger colour, the one the invalid control's border takes. */
2909
+ .error[data-v-4df6c2a6],[role="alert"][data-v-4df6c2a6-s] {
2910
+ color: var(--ui-danger);
2901
2911
  font-size: var(--ui-font-size-sm);
2902
2912
  }
2903
2913
 
2904
2914
  /* A component that sets its display still honours the hidden attribute on its root. */
2905
- [data-component~="ui-form-field"][hidden][data-v-eba1e76b] {
2915
+ [data-component~="ui-form-field"][hidden][data-v-4df6c2a6] {
2906
2916
  display: none;
2907
2917
  }
2908
2918
 
@@ -3123,7 +3133,7 @@ svg[data-v-bcedd63e-s] {
3123
3133
  display: none;
3124
3134
  }
3125
3135
 
3126
- [data-component~="ui-input"][data-v-12ffae5a] {
3136
+ [data-component~="ui-input"][data-v-c19f8322] {
3127
3137
  box-sizing: border-box;
3128
3138
  display: inline-block;
3129
3139
  inline-size: 100%;
@@ -3146,21 +3156,21 @@ svg[data-v-bcedd63e-s] {
3146
3156
  }
3147
3157
 
3148
3158
  /* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
3149
- [data-component~="ui-input"][data-v-12ffae5a]::selection {
3159
+ [data-component~="ui-input"][data-v-c19f8322]::selection {
3150
3160
  background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
3151
3161
  color: inherit;
3152
3162
  }
3153
- [data-component~="ui-input"][data-v-12ffae5a]::placeholder {
3163
+ [data-component~="ui-input"][data-v-c19f8322]::placeholder {
3154
3164
  color: var(--ui-control-placeholder, var(--ui-text-secondary));
3155
3165
  opacity: 1;
3156
3166
  }
3157
- [data-component~="ui-input"][data-v-12ffae5a]:hover:not(:focus):not(:disabled) {
3167
+ [data-component~="ui-input"][data-v-c19f8322]:hover:not(:focus):not(:disabled) {
3158
3168
  border-color: var(
3159
3169
  --ui-input-border-hover,
3160
3170
  var(--ui-control-border-hover, var(--ui-text-secondary))
3161
3171
  );
3162
3172
  }
3163
- [data-component~="ui-input"][data-v-12ffae5a]:focus-visible {
3173
+ [data-component~="ui-input"][data-v-c19f8322]:focus-visible {
3164
3174
  border-color: var(--ui-input-focus-border, var(--ui-control-focus, var(--ui-accent-solid)));
3165
3175
  outline: none;
3166
3176
  box-shadow: var(
@@ -3171,16 +3181,18 @@ svg[data-v-bcedd63e-s] {
3171
3181
  }
3172
3182
 
3173
3183
  /* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
3174
- [data-component~="ui-input"][aria-invalid="true"][data-v-12ffae5a],
3175
- [data-component~="ui-input"][data-v-12ffae5a]:is(:user-invalid, [data-user-invalid]) {
3176
- border-color: var(--ui-danger-solid);
3184
+ [data-component~="ui-input"][aria-invalid="true"][data-v-c19f8322],
3185
+ [data-component~="ui-input"][data-v-c19f8322]:is(:user-invalid, [data-user-invalid]) {
3186
+ border-color: var(--ui-input-invalid-border, var(--ui-danger-solid));
3177
3187
  }
3178
- [data-component~="ui-input"][data-v-12ffae5a]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
3179
- box-shadow:
3188
+ [data-component~="ui-input"][data-v-c19f8322]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
3189
+ box-shadow: var(
3190
+ --ui-input-invalid-focus-shadow,
3180
3191
  var(--ui-control-inset),
3181
- 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent);
3192
+ 0 0 0 3px color-mix(in srgb, var(--ui-danger-solid) 22%, transparent)
3193
+ );
3182
3194
  }
3183
- [data-component~="ui-input"][data-v-12ffae5a]:disabled {
3195
+ [data-component~="ui-input"][data-v-c19f8322]:disabled {
3184
3196
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
3185
3197
  color: var(--ui-text-muted);
3186
3198
  box-shadow: none;
@@ -3191,7 +3203,7 @@ svg[data-v-bcedd63e-s] {
3191
3203
  * scroll vertically inside the field. Native inputs already center their single line. */
3192
3204
 
3193
3205
  /* A component that sets its display still honours the hidden attribute on its root. */
3194
- [data-component~="ui-input"][hidden][data-v-12ffae5a] {
3206
+ [data-component~="ui-input"][hidden][data-v-c19f8322] {
3195
3207
  display: none;
3196
3208
  }
3197
3209
 
@@ -3201,10 +3213,12 @@ svg[data-v-bcedd63e-s] {
3201
3213
  its custom properties, so it is still the one ui-input, with its form behaviour intact. The
3202
3214
  affixes are plain text beside the input, so name the input with a label that says what the
3203
3215
  whole value is. */
3204
- [data-component~="ui-input-group"][data-v-0a135fc1] {
3216
+ [data-component~="ui-input-group"][data-v-42ff173c] {
3205
3217
  --ui-input-border: transparent;
3206
3218
  --ui-input-border-hover: transparent;
3207
3219
  --ui-input-focus-border: transparent;
3220
+ --ui-input-invalid-border: transparent;
3221
+ --ui-input-invalid-focus-shadow: none;
3208
3222
  --ui-input-shadow: none;
3209
3223
  --ui-input-focus-shadow: none;
3210
3224
  --ui-input-radius: 0;
@@ -3225,28 +3239,28 @@ svg[data-v-bcedd63e-s] {
3225
3239
  border-color var(--ui-motion-fast) var(--ui-motion-ease),
3226
3240
  box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
3227
3241
  }
3228
- [data-component~="ui-input-group"][data-v-0a135fc1]:hover:not(:focus-within) {
3242
+ [data-component~="ui-input-group"][data-v-42ff173c]:hover:not(:focus-within) {
3229
3243
  border-color: var(--ui-text-secondary);
3230
3244
  }
3231
- [data-component~="ui-input-group"][data-v-0a135fc1]:focus-within {
3245
+ [data-component~="ui-input-group"][data-v-42ff173c]:focus-within {
3232
3246
  border-color: var(--ui-accent-solid);
3233
3247
  box-shadow:
3234
3248
  var(--ui-control-inset),
3235
3249
  var(--ui-control-focus-halo-shadow);
3236
3250
  }
3237
- [data-component~="ui-input-group"][data-v-0a135fc1]:has([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])) {
3251
+ [data-component~="ui-input-group"][data-v-42ff173c]:has([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])) {
3238
3252
  border-color: var(--ui-danger-solid);
3239
3253
  }
3240
- [data-component~="ui-input-group"][data-ui-input-group-state~="disabled"][data-v-0a135fc1] {
3254
+ [data-component~="ui-input-group"][data-ui-input-group-state~="disabled"][data-v-42ff173c] {
3241
3255
  background: var(--ui-surface-muted);
3242
3256
  box-shadow: none;
3243
3257
  }
3244
- .field[data-v-0a135fc1] {
3258
+ .field[data-v-42ff173c] {
3245
3259
  display: flex;
3246
3260
  flex: 1;
3247
3261
  min-inline-size: 0;
3248
3262
  }
3249
- .affix[data-v-0a135fc1] {
3263
+ .affix[data-v-42ff173c] {
3250
3264
  display: inline-flex;
3251
3265
  flex: none;
3252
3266
  align-items: center;
@@ -3256,12 +3270,12 @@ svg[data-v-bcedd63e-s] {
3256
3270
  font-size: var(--ui-font-size-sm);
3257
3271
  white-space: nowrap;
3258
3272
  }
3259
- .affix[data-v-0a135fc1]:empty {
3273
+ .affix[data-v-42ff173c]:empty {
3260
3274
  display: none;
3261
3275
  }
3262
3276
 
3263
3277
  /* A component that sets its display still honours the hidden attribute on its root. */
3264
- [data-component~="ui-input-group"][hidden][data-v-0a135fc1] {
3278
+ [data-component~="ui-input-group"][hidden][data-v-42ff173c] {
3265
3279
  display: none;
3266
3280
  }
3267
3281
 
@@ -4788,72 +4802,81 @@ input[data-v-26ab3add], input[data-v-26ab3add]::after {
4788
4802
 
4789
4803
  /* Running text, set on the type scale and in a tone that says what it is, so a view never styles
4790
4804
  text of its own. The root is a paragraph unless as= names a span, div, small, strong, or label. */
4791
- [data-component~="ui-text"][data-v-70a75450] {
4805
+ [data-component~="ui-text"][data-v-b83a3ab9] {
4792
4806
  margin: 0;
4793
4807
  min-inline-size: 0;
4794
4808
  color: var(--ui-text-primary);
4795
4809
  text-align: start;
4796
4810
  }
4797
- [data-component~="ui-text"][data-ui-text-state~="size=xs"][data-v-70a75450] {
4811
+ [data-component~="ui-text"][data-ui-text-state~="size=xs"][data-v-b83a3ab9] {
4798
4812
  font-size: var(--ui-font-size-xs);
4799
4813
  line-height: var(--ui-line-height);
4800
4814
  }
4801
- [data-component~="ui-text"][data-ui-text-state~="size=sm"][data-v-70a75450] {
4815
+ [data-component~="ui-text"][data-ui-text-state~="size=sm"][data-v-b83a3ab9] {
4802
4816
  font-size: var(--ui-font-size-sm);
4803
4817
  line-height: var(--ui-line-height);
4804
4818
  }
4805
- [data-component~="ui-text"][data-ui-text-state~="size=md"][data-v-70a75450] {
4819
+ [data-component~="ui-text"][data-ui-text-state~="size=md"][data-v-b83a3ab9] {
4806
4820
  font-size: var(--ui-font-size-md);
4807
4821
  line-height: var(--ui-line-height);
4808
4822
  }
4809
- [data-component~="ui-text"][data-ui-text-state~="size=lg"][data-v-70a75450] {
4823
+ [data-component~="ui-text"][data-ui-text-state~="size=lg"][data-v-b83a3ab9] {
4810
4824
  font-size: var(--ui-font-size-lg);
4811
4825
  line-height: var(--ui-line-height-relaxed);
4812
4826
  }
4813
- [data-component~="ui-text"][data-ui-text-state~="tone=secondary"][data-v-70a75450] {
4827
+ [data-component~="ui-text"][data-ui-text-state~="tone=secondary"][data-v-b83a3ab9] {
4814
4828
  color: var(--ui-text-secondary);
4815
4829
  }
4816
- [data-component~="ui-text"][data-ui-text-state~="tone=muted"][data-v-70a75450] {
4830
+ [data-component~="ui-text"][data-ui-text-state~="tone=muted"][data-v-b83a3ab9] {
4817
4831
  color: var(--ui-text-muted);
4818
4832
  }
4819
- [data-component~="ui-text"][data-ui-text-state~="tone=accent"][data-v-70a75450] {
4833
+ [data-component~="ui-text"][data-ui-text-state~="tone=accent"][data-v-b83a3ab9] {
4820
4834
  color: var(--ui-accent-active);
4821
4835
  }
4822
- [data-component~="ui-text"][data-ui-text-state~="tone=danger"][data-v-70a75450] {
4836
+ [data-component~="ui-text"][data-ui-text-state~="tone=danger"][data-v-b83a3ab9] {
4823
4837
  color: var(--ui-danger);
4824
4838
  }
4825
- [data-component~="ui-text"][data-ui-text-state~="tone=success"][data-v-70a75450] {
4839
+ [data-component~="ui-text"][data-ui-text-state~="tone=success"][data-v-b83a3ab9] {
4826
4840
  color: var(--ui-success);
4827
4841
  }
4828
- [data-component~="ui-text"][data-ui-text-state~="weight=normal"][data-v-70a75450] {
4842
+ [data-component~="ui-text"][data-ui-text-state~="weight=normal"][data-v-b83a3ab9] {
4829
4843
  font-weight: var(--ui-font-normal);
4830
4844
  }
4831
- [data-component~="ui-text"][data-ui-text-state~="weight=medium"][data-v-70a75450] {
4845
+ [data-component~="ui-text"][data-ui-text-state~="weight=medium"][data-v-b83a3ab9] {
4832
4846
  font-weight: var(--ui-font-medium);
4833
4847
  }
4834
- [data-component~="ui-text"][data-ui-text-state~="weight=semibold"][data-v-70a75450] {
4848
+ [data-component~="ui-text"][data-ui-text-state~="weight=semibold"][data-v-b83a3ab9] {
4835
4849
  font-weight: var(--ui-font-semibold);
4836
4850
  }
4837
- [data-component~="ui-text"][data-ui-text-state~="variant=eyebrow"][data-v-70a75450] {
4851
+ [data-component~="ui-text"][data-ui-text-state~="variant=eyebrow"][data-v-b83a3ab9] {
4838
4852
  font-size: var(--ui-font-size-xs);
4839
4853
  font-weight: var(--ui-font-semibold);
4840
4854
  letter-spacing: 0.06em;
4841
4855
  text-transform: uppercase;
4842
4856
  }
4843
- [data-component~="ui-text"][data-ui-text-state~="variant=code"][data-v-70a75450] {
4857
+ [data-component~="ui-text"][data-ui-text-state~="variant=code"][data-v-b83a3ab9] {
4844
4858
  font-family: var(--ui-font-family-mono);
4845
4859
  }
4846
- [data-component~="ui-text"][data-ui-text-state~="truncate"][data-v-70a75450] {
4860
+
4861
+ /* A link in running text is underlined, so it stands apart from the words around it by more than
4862
+ colour. */
4863
+ [data-component~="ui-text"] a[data-v-b83a3ab9-s] {
4864
+ color: var(--ui-accent-active);
4865
+ text-decoration: underline;
4866
+ text-decoration-thickness: 0.06em;
4867
+ text-underline-offset: 0.18em;
4868
+ }
4869
+ [data-component~="ui-text"][data-ui-text-state~="truncate"][data-v-b83a3ab9] {
4847
4870
  overflow: hidden;
4848
4871
  text-overflow: ellipsis;
4849
4872
  white-space: nowrap;
4850
4873
  }
4851
- [data-component~="ui-text"][data-ui-text-state~="align=center"][data-v-70a75450] {
4874
+ [data-component~="ui-text"][data-ui-text-state~="align=center"][data-v-b83a3ab9] {
4852
4875
  text-align: center;
4853
4876
  }
4854
4877
 
4855
4878
  /* A component that sets its display still honours the hidden attribute on its root. */
4856
- [data-component~="ui-text"][hidden][data-v-70a75450] {
4879
+ [data-component~="ui-text"][hidden][data-v-b83a3ab9] {
4857
4880
  display: none;
4858
4881
  }
4859
4882