ionbase-ui 0.24.0 → 0.25.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.
Files changed (42) hide show
  1. package/dist/components/AgentActivity.d.ts +41 -0
  2. package/dist/components/AgentActivity.d.ts.map +1 -0
  3. package/dist/components/AgentActivity.js +84 -0
  4. package/dist/components/AgentActivity.js.map +1 -0
  5. package/dist/components/Citation.d.ts +51 -0
  6. package/dist/components/Citation.d.ts.map +1 -0
  7. package/dist/components/Citation.js +41 -0
  8. package/dist/components/Citation.js.map +1 -0
  9. package/dist/components/ConfidenceIndicator.d.ts +37 -0
  10. package/dist/components/ConfidenceIndicator.d.ts.map +1 -0
  11. package/dist/components/ConfidenceIndicator.js +41 -0
  12. package/dist/components/ConfidenceIndicator.js.map +1 -0
  13. package/dist/components/StreamingText.d.ts +47 -0
  14. package/dist/components/StreamingText.d.ts.map +1 -0
  15. package/dist/components/StreamingText.js +44 -0
  16. package/dist/components/StreamingText.js.map +1 -0
  17. package/dist/components/index.d.ts +8 -0
  18. package/dist/components/index.d.ts.map +1 -1
  19. package/dist/components/index.js +4 -0
  20. package/dist/components/index.js.map +1 -1
  21. package/dist/figma-descriptions.json +29 -29
  22. package/dist/figma-map.json +1 -1
  23. package/dist/meta/AgentActivity.json +103 -0
  24. package/dist/meta/AgentActivityStep.json +117 -0
  25. package/dist/meta/Citation.json +101 -0
  26. package/dist/meta/CitationList.json +94 -0
  27. package/dist/meta/CitationListItem.json +88 -0
  28. package/dist/meta/ConfidenceIndicator.json +115 -0
  29. package/dist/meta/Input.json +2 -2
  30. package/dist/meta/PhoneInput.json +2 -2
  31. package/dist/meta/StreamingText.json +99 -0
  32. package/dist/meta/components.json +722 -5
  33. package/dist/meta/contrast.json +240 -0
  34. package/dist/meta/index.json +64 -1
  35. package/dist/meta/patterns/index.json +1 -1
  36. package/dist/styles/agent-activity.css +95 -0
  37. package/dist/styles/citation.css +93 -0
  38. package/dist/styles/confidence-indicator.css +97 -0
  39. package/dist/styles/index.css +4 -0
  40. package/dist/styles/streaming-text.css +56 -0
  41. package/llms.txt +2 -2
  42. package/package.json +1 -1
@@ -8,6 +8,118 @@
8
8
  "Dark"
9
9
  ],
10
10
  "pairings": [
11
+ {
12
+ "component": "confidence-indicator",
13
+ "context": "ion-confidence--medium&ion-confidence__bar--on ion-confidence__bar--on",
14
+ "state": "default",
15
+ "fg": "--text-secondary",
16
+ "bg": "--icon-information",
17
+ "backdrop": null,
18
+ "kind": "text",
19
+ "mode": "Light",
20
+ "fgHex": "#384252",
21
+ "bgHex": "#4f3cc8",
22
+ "ratio": 1.36,
23
+ "min": 4.5
24
+ },
25
+ {
26
+ "component": "confidence-indicator",
27
+ "context": "ion-confidence--low&ion-confidence__bar--on ion-confidence__bar--on",
28
+ "state": "default",
29
+ "fg": "--text-secondary",
30
+ "bg": "--icon-warning",
31
+ "backdrop": null,
32
+ "kind": "text",
33
+ "mode": "Light",
34
+ "fgHex": "#384252",
35
+ "bgHex": "#af3e0e",
36
+ "ratio": 1.7,
37
+ "min": 4.5
38
+ },
39
+ {
40
+ "component": "confidence-indicator",
41
+ "context": "ion-confidence--high&ion-confidence__bar--on ion-confidence__bar--on",
42
+ "state": "default",
43
+ "fg": "--text-secondary",
44
+ "bg": "--icon-success",
45
+ "backdrop": null,
46
+ "kind": "text",
47
+ "mode": "Light",
48
+ "fgHex": "#384252",
49
+ "bgHex": "#0d7d38",
50
+ "ratio": 1.94,
51
+ "min": 4.5
52
+ },
53
+ {
54
+ "component": "confidence-indicator",
55
+ "context": "ion-confidence--low&ion-confidence__bar--on ion-confidence__bar--on",
56
+ "state": "default",
57
+ "fg": "--text-secondary",
58
+ "bg": "--icon-warning",
59
+ "backdrop": null,
60
+ "kind": "text",
61
+ "mode": "Dark",
62
+ "fgHex": "#dde0e4",
63
+ "bgHex": "#ef8539",
64
+ "ratio": 1.96,
65
+ "min": 4.5
66
+ },
67
+ {
68
+ "component": "confidence-indicator",
69
+ "context": "ion-confidence--high&ion-confidence__bar--on ion-confidence__bar--on",
70
+ "state": "default",
71
+ "fg": "--text-secondary",
72
+ "bg": "--icon-success",
73
+ "backdrop": null,
74
+ "kind": "text",
75
+ "mode": "Dark",
76
+ "fgHex": "#dde0e4",
77
+ "bgHex": "#39b378",
78
+ "ratio": 2.01,
79
+ "min": 4.5
80
+ },
81
+ {
82
+ "component": "streaming-text",
83
+ "context": "ion-streaming-text ion-streaming-text__cursor",
84
+ "state": "default",
85
+ "fg": "--text-default",
86
+ "bg": "--text-tertiary",
87
+ "backdrop": null,
88
+ "kind": "text",
89
+ "mode": "Light",
90
+ "fgHex": "#131923",
91
+ "bgHex": "#4b5563",
92
+ "ratio": 2.33,
93
+ "min": 4.5
94
+ },
95
+ {
96
+ "component": "streaming-text",
97
+ "context": "ion-streaming-text ion-streaming-text__cursor",
98
+ "state": "default",
99
+ "fg": "--text-default",
100
+ "bg": "--text-tertiary",
101
+ "backdrop": null,
102
+ "kind": "text",
103
+ "mode": "Dark",
104
+ "fgHex": "#f6f8f9",
105
+ "bgHex": "#9ca3b0",
106
+ "ratio": 2.38,
107
+ "min": 4.5
108
+ },
109
+ {
110
+ "component": "confidence-indicator",
111
+ "context": "ion-confidence--medium&ion-confidence__bar--on ion-confidence__bar--on",
112
+ "state": "default",
113
+ "fg": "--text-secondary",
114
+ "bg": "--icon-information",
115
+ "backdrop": null,
116
+ "kind": "text",
117
+ "mode": "Dark",
118
+ "fgHex": "#dde0e4",
119
+ "bgHex": "#7e6ff1",
120
+ "ratio": 2.92,
121
+ "min": 4.5
122
+ },
11
123
  {
12
124
  "component": "approval-gate",
13
125
  "context": "ion-approval-gate ion-approval-gate__action",
@@ -359,6 +471,20 @@
359
471
  "ratio": 4.25,
360
472
  "min": 4.5
361
473
  },
474
+ {
475
+ "component": "citation",
476
+ "context": "ion-citation",
477
+ "state": "hover",
478
+ "fg": "--text-link",
479
+ "bg": "--surface-primary-subtle-hover",
480
+ "backdrop": "--surface-primary-subtle",
481
+ "kind": "text",
482
+ "mode": "Dark",
483
+ "fgHex": "#609cf0",
484
+ "bgHex": "#0e2d8b",
485
+ "ratio": 4.25,
486
+ "min": 4.5
487
+ },
362
488
  {
363
489
  "component": "approval-gate",
364
490
  "context": "ion-approval-gate ion-approval-gate__action",
@@ -863,6 +989,34 @@
863
989
  "ratio": 5.37,
864
990
  "min": 4.5
865
991
  },
992
+ {
993
+ "component": "citation",
994
+ "context": "ion-citation",
995
+ "state": "default",
996
+ "fg": "--text-link",
997
+ "bg": "--surface-primary-subtle",
998
+ "backdrop": "--surface-primary-subtle",
999
+ "kind": "text",
1000
+ "mode": "Dark",
1001
+ "fgHex": "#609cf0",
1002
+ "bgHex": "#071e69",
1003
+ "ratio": 5.37,
1004
+ "min": 4.5
1005
+ },
1006
+ {
1007
+ "component": "citation",
1008
+ "context": "ion-citation",
1009
+ "state": "focus",
1010
+ "fg": "--text-link",
1011
+ "bg": "--surface-primary-subtle",
1012
+ "backdrop": "--surface-primary-subtle",
1013
+ "kind": "text",
1014
+ "mode": "Dark",
1015
+ "fgHex": "#609cf0",
1016
+ "bgHex": "#071e69",
1017
+ "ratio": 5.37,
1018
+ "min": 4.5
1019
+ },
866
1020
  {
867
1021
  "component": "menu",
868
1022
  "context": "ion-menu__item--selected ion-menu__item--selected",
@@ -1578,6 +1732,20 @@
1578
1732
  "ratio": 7.47,
1579
1733
  "min": 3
1580
1734
  },
1735
+ {
1736
+ "component": "citation",
1737
+ "context": "ion-citation",
1738
+ "state": "hover",
1739
+ "fg": "--text-link",
1740
+ "bg": "--surface-primary-subtle-hover",
1741
+ "backdrop": "--surface-primary-subtle",
1742
+ "kind": "text",
1743
+ "mode": "Light",
1744
+ "fgHex": "#1541b2",
1745
+ "bgHex": "#e2f1fd",
1746
+ "ratio": 7.5,
1747
+ "min": 4.5
1748
+ },
1581
1749
  {
1582
1750
  "component": "approval-gate",
1583
1751
  "context": "ion-approval-gate__action--approve ion-approval-gate__action--approve",
@@ -1802,6 +1970,34 @@
1802
1970
  "ratio": 7.93,
1803
1971
  "min": 4.5
1804
1972
  },
1973
+ {
1974
+ "component": "citation",
1975
+ "context": "ion-citation",
1976
+ "state": "default",
1977
+ "fg": "--text-link",
1978
+ "bg": "--surface-primary-subtle",
1979
+ "backdrop": "--surface-primary-subtle",
1980
+ "kind": "text",
1981
+ "mode": "Light",
1982
+ "fgHex": "#1541b2",
1983
+ "bgHex": "#ebf7ff",
1984
+ "ratio": 7.93,
1985
+ "min": 4.5
1986
+ },
1987
+ {
1988
+ "component": "citation",
1989
+ "context": "ion-citation",
1990
+ "state": "focus",
1991
+ "fg": "--text-link",
1992
+ "bg": "--surface-primary-subtle",
1993
+ "backdrop": "--surface-primary-subtle",
1994
+ "kind": "text",
1995
+ "mode": "Light",
1996
+ "fgHex": "#1541b2",
1997
+ "bgHex": "#ebf7ff",
1998
+ "ratio": 7.93,
1999
+ "min": 4.5
2000
+ },
1805
2001
  {
1806
2002
  "component": "select",
1807
2003
  "context": "ion-select--placeholder ion-select__field",
@@ -4350,6 +4546,50 @@
4350
4546
  "Input",
4351
4547
  "Select"
4352
4548
  ]
4549
+ },
4550
+ {
4551
+ "fg": "--text-secondary",
4552
+ "bg": "--icon-warning",
4553
+ "mode": "Light",
4554
+ "kind": "wcag-exempt",
4555
+ "ratio": 1.7,
4556
+ "reason": "Not a text pairing. `.ion-confidence__bar--on` is an empty, aria-hidden <span> — the gate pairs the inherited text colour against its background because it models every element as potentially holding text. There is no text here and SC 1.4.3 does not apply. What DOES apply is SC 1.4.11, and it was measured by hand: the filled bar reads 5.32:1 against the unfilled one, and the unfilled bar's outline reads 7.09:1 against the page. Both clear 3:1.",
4557
+ "affects": [
4558
+ "ConfidenceIndicator"
4559
+ ]
4560
+ },
4561
+ {
4562
+ "fg": "--text-secondary",
4563
+ "bg": "--icon-information",
4564
+ "mode": "Light",
4565
+ "kind": "wcag-exempt",
4566
+ "ratio": 1.36,
4567
+ "reason": "As above — an empty bar, not text. Filled vs unfilled measures 6.65:1, over the 3:1 SC 1.4.11 asks of a non-text indicator.",
4568
+ "affects": [
4569
+ "ConfidenceIndicator"
4570
+ ]
4571
+ },
4572
+ {
4573
+ "fg": "--text-secondary",
4574
+ "bg": "--icon-success",
4575
+ "mode": "Light",
4576
+ "kind": "wcag-exempt",
4577
+ "ratio": 1.94,
4578
+ "reason": "As above — an empty bar, not text. Filled vs unfilled measures 4.67:1, over 3:1.",
4579
+ "affects": [
4580
+ "ConfidenceIndicator"
4581
+ ]
4582
+ },
4583
+ {
4584
+ "fg": "--text-default",
4585
+ "bg": "--text-tertiary",
4586
+ "mode": "Light",
4587
+ "kind": "wcag-exempt",
4588
+ "ratio": 2.33,
4589
+ "reason": "Not a text pairing. `.ion-streaming-text__cursor` is an empty, aria-hidden <span> drawn as a block — deliberately not a text character, since some screen readers read a literal cursor glyph aloud. The gate pairs the paragraph's inherited colour against the cursor's background. Measured properly, the cursor is 7.09:1 against the page.",
4590
+ "affects": [
4591
+ "StreamingText"
4592
+ ]
4353
4593
  }
4354
4594
  ],
4355
4595
  "deferred": [
@@ -1,11 +1,33 @@
1
1
  {
2
2
  "package": "ionbase-ui",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "usage": "Pick a component here, then read dist/meta/<Name>.json for its full contract.",
5
5
  "hooks": [
6
6
  "useToast"
7
7
  ],
8
8
  "components": {
9
+ "AgentActivity": {
10
+ "summary": "An ordered, plain-language log of what the agent is doing. Status is text and shape, never colour alone.",
11
+ "status": "stable",
12
+ "variants": {},
13
+ "detail": "dist/meta/AgentActivity.json",
14
+ "hasIntent": true
15
+ },
16
+ "AgentActivityStep": {
17
+ "summary": "One step in an activity log: what happened, in the user's language, with a status carried by shape and text.",
18
+ "status": "stable",
19
+ "variants": {
20
+ "status": [
21
+ "pending",
22
+ "active",
23
+ "done",
24
+ "failed",
25
+ "skipped"
26
+ ]
27
+ },
28
+ "detail": "dist/meta/AgentActivityStep.json",
29
+ "hasIntent": true
30
+ },
9
31
  "AgentStop": {
10
32
  "summary": "The always-visible way to end a running agent. Not optional, and not behind a menu.",
11
33
  "status": "stable",
@@ -155,6 +177,40 @@
155
177
  "detail": "dist/meta/Checkbox.json",
156
178
  "hasIntent": true
157
179
  },
180
+ "Citation": {
181
+ "summary": "The inline source marker. The visible number is for the eye; the accessible name is the sentence.",
182
+ "status": "stable",
183
+ "variants": {},
184
+ "detail": "dist/meta/Citation.json",
185
+ "hasIntent": true
186
+ },
187
+ "CitationList": {
188
+ "summary": "The footer list of sources, as an ordered list so the count and order are structural.",
189
+ "status": "stable",
190
+ "variants": {},
191
+ "detail": "dist/meta/CitationList.json",
192
+ "hasIntent": true
193
+ },
194
+ "CitationListItem": {
195
+ "summary": "One source row: its number, what it is, and the passage it supports.",
196
+ "status": "stable",
197
+ "variants": {},
198
+ "detail": "dist/meta/CitationListItem.json",
199
+ "hasIntent": true
200
+ },
201
+ "ConfidenceIndicator": {
202
+ "summary": "How much to trust the thing next to it — three levels with a required basis, never a percentage.",
203
+ "status": "stable",
204
+ "variants": {
205
+ "level": [
206
+ "low",
207
+ "medium",
208
+ "high"
209
+ ]
210
+ },
211
+ "detail": "dist/meta/ConfidenceIndicator.json",
212
+ "hasIntent": true
213
+ },
158
214
  "Divider": {
159
215
  "summary": "A semantic thematic break, rendered as a real <hr>.",
160
216
  "status": "stable",
@@ -389,6 +445,13 @@
389
445
  "detail": "dist/meta/Select.json",
390
446
  "hasIntent": true
391
447
  },
448
+ "StreamingText": {
449
+ "summary": "Model output arriving a token at a time, in a container that does not move. Deliberately not a live region.",
450
+ "status": "stable",
451
+ "variants": {},
452
+ "detail": "dist/meta/StreamingText.json",
453
+ "hasIntent": true
454
+ },
392
455
  "TabItem": {
393
456
  "summary": "One tab and its panel. Re-exported from react-stately's collection Item — `title` is the tab label, children are the panel.",
394
457
  "status": "stable",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "ionbase-ui",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "usage": "A pattern is a documented composition of components, not a component. Read one here, then read the contracts of what it composes.",
5
5
  "patterns": {
6
6
  "DataTable": {
@@ -0,0 +1,95 @@
1
+ /*
2
+ * AgentActivity
3
+ *
4
+ * NOT DRAWN IN FIGMA. The rail-and-body layout is Alert's, one step down in
5
+ * scale; colours are the status roles used everywhere else in the system.
6
+ */
7
+ .ion-agent-activity {
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: var(--spacing-8);
11
+ margin: 0;
12
+ padding: 0;
13
+ list-style: none;
14
+ font-family: var(--font-family-sans);
15
+ font-size: var(--type-body-sm);
16
+ line-height: var(--type-body-sm-line-height);
17
+ }
18
+
19
+ .ion-agent-activity__step {
20
+ display: flex;
21
+ align-items: flex-start;
22
+ gap: var(--spacing-8);
23
+ color: var(--text-secondary);
24
+ }
25
+
26
+ .ion-agent-activity__glyph {
27
+ display: inline-flex;
28
+ flex: none;
29
+ width: var(--icon-size-sm);
30
+ height: var(--icon-size-sm);
31
+
32
+ /* Optical alignment to the first line of the label, not to the box. */
33
+ margin-top: var(--spacing-2);
34
+ color: var(--icon-tertiary);
35
+ }
36
+
37
+ .ion-agent-activity__glyph svg {
38
+ width: 100%;
39
+ height: 100%;
40
+ }
41
+
42
+ .ion-agent-activity__body {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: var(--spacing-2);
46
+ min-width: 0;
47
+ }
48
+
49
+ .ion-agent-activity__detail {
50
+ color: var(--text-tertiary);
51
+ font-size: var(--type-caption);
52
+ line-height: var(--type-caption-line-height);
53
+ }
54
+
55
+ /*
56
+ * Status colour is the second signal, never the only one: each status also has
57
+ * a differently SHAPED glyph, and its name in visually hidden text. A row of
58
+ * dots that differ only in hue fails WCAG 1.4.1 outright.
59
+ */
60
+ .ion-agent-activity__step--active {
61
+ color: var(--text-default);
62
+ }
63
+
64
+ .ion-agent-activity__step--active .ion-agent-activity__glyph {
65
+ color: var(--icon-primary);
66
+ animation: ion-agent-activity-spin 1.2s linear infinite;
67
+ }
68
+
69
+ .ion-agent-activity__step--done .ion-agent-activity__glyph {
70
+ color: var(--icon-success);
71
+ }
72
+
73
+ .ion-agent-activity__step--failed {
74
+ color: var(--text-error);
75
+ }
76
+
77
+ .ion-agent-activity__step--failed .ion-agent-activity__glyph {
78
+ color: var(--icon-error);
79
+ }
80
+
81
+ .ion-agent-activity__step--skipped {
82
+ color: var(--text-tertiary);
83
+ }
84
+
85
+ @keyframes ion-agent-activity-spin {
86
+ to {
87
+ transform: rotate(360deg);
88
+ }
89
+ }
90
+
91
+ @media (prefers-reduced-motion: reduce) {
92
+ .ion-agent-activity__step--active .ion-agent-activity__glyph {
93
+ animation: none;
94
+ }
95
+ }
@@ -0,0 +1,93 @@
1
+ /*
2
+ * Citation
3
+ *
4
+ * NOT DRAWN IN FIGMA. The inline marker borrows Badge's pill geometry at the
5
+ * smallest size; the footer list borrows the Table's row rhythm.
6
+ */
7
+ .ion-citation {
8
+ display: inline-flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ min-width: var(--spacing-16);
12
+ height: var(--spacing-16);
13
+ padding: 0 var(--spacing-4);
14
+
15
+ /* Sits with the text, not on it: superscript positioning would shift the
16
+ * line box and make a paragraph of citations ripple. */
17
+ margin-inline-start: var(--spacing-2);
18
+ border-radius: var(--radius-xs);
19
+ background-color: var(--surface-primary-subtle);
20
+ color: var(--text-link);
21
+ font-size: var(--type-caption);
22
+ line-height: var(--type-caption-line-height);
23
+ font-weight: var(--font-weight-medium);
24
+ text-decoration: none;
25
+ vertical-align: baseline;
26
+ }
27
+
28
+ a.ion-citation:hover {
29
+ background-color: var(--surface-primary-subtle-hover);
30
+ }
31
+
32
+ a.ion-citation:focus-visible {
33
+ outline: var(--border-width-thick) solid var(--border-focus);
34
+ outline-offset: 1px;
35
+ }
36
+
37
+ .ion-citation-list {
38
+ font-family: var(--font-family-sans);
39
+ font-size: var(--type-body-sm);
40
+ line-height: var(--type-body-sm-line-height);
41
+ }
42
+
43
+ .ion-citation-list__label {
44
+ margin: 0 0 var(--spacing-8);
45
+ color: var(--text-tertiary);
46
+ font-size: var(--type-caption);
47
+ line-height: var(--type-caption-line-height);
48
+ font-weight: var(--font-weight-semibold);
49
+ }
50
+
51
+ .ion-citation-list__items {
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: var(--spacing-8);
55
+ margin: 0;
56
+ padding: 0;
57
+
58
+ /* The <ol> keeps its semantics and loses its markers: the visible number is
59
+ * the citation's own, which must match the inline marker exactly. */
60
+ list-style: none;
61
+ }
62
+
63
+ .ion-citation-list__item {
64
+ display: flex;
65
+ align-items: flex-start;
66
+ gap: var(--spacing-8);
67
+ }
68
+
69
+ .ion-citation-list__marker {
70
+ flex: none;
71
+ min-width: var(--spacing-16);
72
+ color: var(--text-tertiary);
73
+ font-size: var(--type-caption);
74
+ line-height: var(--type-body-sm-line-height);
75
+ text-align: end;
76
+ }
77
+
78
+ .ion-citation-list__body {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: var(--spacing-2);
82
+ min-width: 0;
83
+ }
84
+
85
+ .ion-citation-list__source {
86
+ color: var(--text-link);
87
+ }
88
+
89
+ .ion-citation-list__passage {
90
+ color: var(--text-tertiary);
91
+ font-size: var(--type-caption);
92
+ line-height: var(--type-caption-line-height);
93
+ }
@@ -0,0 +1,97 @@
1
+ /*
2
+ * ConfidenceIndicator
3
+ *
4
+ * NOT DRAWN IN FIGMA. Three bars and a line of text; the colours are the
5
+ * system's status roles.
6
+ *
7
+ * THE BARS ARE THE SECOND SIGNAL, NOT THE FIRST. The count of filled bars
8
+ * carries the level, so it reads in greyscale and in forced-colours mode; the
9
+ * colour only reinforces it. The label spells the level out regardless, which
10
+ * is what makes the meter safe to look at quickly.
11
+ */
12
+ .ion-confidence {
13
+ display: inline-flex;
14
+ align-items: baseline;
15
+ gap: var(--spacing-8);
16
+ font-family: var(--font-family-sans);
17
+ font-size: var(--type-caption);
18
+ line-height: var(--type-caption-line-height);
19
+ color: var(--text-secondary);
20
+ }
21
+
22
+ .ion-confidence__meter {
23
+ display: inline-flex;
24
+ align-items: flex-end;
25
+ gap: var(--spacing-2);
26
+
27
+ /* Baseline-aligned with the label rather than centred, so the meter sits on
28
+ * the text's baseline the way a small-caps run would. */
29
+ align-self: center;
30
+ }
31
+
32
+ /*
33
+ * EVERY bar is outlined; only the filled ones take a colour.
34
+ *
35
+ * The first draft used `surface/muted` as the empty bar's fill, which measures
36
+ * 1.05:1 against `surface/page` — invisible. That breaks the reading the meter
37
+ * depends on: "one bar filled of three" collapses into "one bar", and the level
38
+ * can no longer be judged without reading the label. Found by computing the
39
+ * pairing the contrast gate does not model, since these spans hold no text.
40
+ *
41
+ * `icon/tertiary` is 7.09:1 against the page and 7.56:1 against a card, so the
42
+ * empty bars are legible on both surfaces. This is also the same construction
43
+ * the forced-colours block below uses, so the two no longer diverge.
44
+ */
45
+ .ion-confidence__bar {
46
+ width: var(--spacing-4);
47
+ height: var(--spacing-8);
48
+ border: var(--border-width-default) solid var(--icon-tertiary);
49
+ border-radius: var(--radius-2xs);
50
+ background-color: transparent;
51
+ }
52
+
53
+ .ion-confidence__bar:nth-child(2) {
54
+ height: var(--spacing-12);
55
+ }
56
+
57
+ .ion-confidence__bar:nth-child(3) {
58
+ height: var(--spacing-16);
59
+ }
60
+
61
+ .ion-confidence--low .ion-confidence__bar--on {
62
+ border-color: var(--icon-warning);
63
+ background-color: var(--icon-warning);
64
+ }
65
+
66
+ .ion-confidence--medium .ion-confidence__bar--on {
67
+ border-color: var(--icon-information);
68
+ background-color: var(--icon-information);
69
+ }
70
+
71
+ .ion-confidence--high .ion-confidence__bar--on {
72
+ border-color: var(--icon-success);
73
+ background-color: var(--icon-success);
74
+ }
75
+
76
+ .ion-confidence__label {
77
+ color: var(--text-default);
78
+ font-weight: var(--font-weight-medium);
79
+ }
80
+
81
+ .ion-confidence__basis {
82
+ color: var(--text-tertiary);
83
+ }
84
+
85
+ @media (forced-colors: active) {
86
+ /* Colour is remapped away entirely here, so the filled bars must still be
87
+ * distinguishable from the empty ones by fill rather than hue. */
88
+ .ion-confidence__bar {
89
+ forced-color-adjust: none;
90
+ background-color: Canvas;
91
+ border: var(--border-width-default) solid CanvasText;
92
+ }
93
+
94
+ .ion-confidence__bar--on {
95
+ background-color: CanvasText;
96
+ }
97
+ }
@@ -59,6 +59,10 @@
59
59
  */
60
60
  @import url('./agent-stop.css');
61
61
  @import url('./approval-gate.css');
62
+ @import url('./agent-activity.css');
63
+ @import url('./streaming-text.css');
64
+ @import url('./citation.css');
65
+ @import url('./confidence-indicator.css');
62
66
 
63
67
  /*
64
68
  * Visually hidden, but not hidden from assistive tech.