@danxbot/ui 7.0.2 → 7.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.
- package/dist/confidence.css +202 -0
- package/dist/index.js +22 -15
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/components/provenance/ConfidenceBar.d.ts +84 -27
- package/package.json +2 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
THE COLOUR RAMPS — TIER 1 primitives, and nothing else.
|
|
3
|
+
|
|
4
|
+
Split out of tokens.css (SG-901) so a surface that is NOT a consumer of this
|
|
5
|
+
design system can still read the ONE confidence scale: `dist/confidence.css`
|
|
6
|
+
ships these ramps plus the confidence tokens as a self-contained file, and a
|
|
7
|
+
separate Vue package (the demand letter's verification overlay) imports it
|
|
8
|
+
rather than keeping its own copy of five colours. tokens.css imports this file
|
|
9
|
+
first, so nothing about how the library itself resolves a colour changes.
|
|
10
|
+
|
|
11
|
+
Never referenced by a component — see tokens.css for the tier rules.
|
|
12
|
+
========================================================================= */
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
/* --- Neutral: SLATE ----------------------------------------------------
|
|
16
|
+
Cool, faintly violet-tinted (hue 267). The tint is small but load-bearing:
|
|
17
|
+
it makes large dark fills read as deep atmosphere rather than flat grey,
|
|
18
|
+
and it harmonises with the aqua/iris accents instead of fighting them.
|
|
19
|
+
|
|
20
|
+
The dark end deliberately STOPS at L 0.17 rather than approaching black.
|
|
21
|
+
Near-black surfaces make every accent scream and leave nowhere to go for
|
|
22
|
+
a recessed state; a lifted floor is what makes the dark theme read as
|
|
23
|
+
soft rather than severe. */
|
|
24
|
+
--slate-25: oklch(0.986 0.003 267);
|
|
25
|
+
--slate-50: oklch(0.970 0.005 267);
|
|
26
|
+
--slate-100: oklch(0.938 0.009 267);
|
|
27
|
+
--slate-200: oklch(0.882 0.013 267);
|
|
28
|
+
--slate-300: oklch(0.802 0.017 267);
|
|
29
|
+
--slate-400: oklch(0.694 0.020 267);
|
|
30
|
+
/* Two half-steps, added because the ramp's 500 lands almost exactly ON the
|
|
31
|
+
AA boundary (3.80:1 on the light canvas, 4.49:1 on the dark one) — which
|
|
32
|
+
is not a step you can build de-emphasised TEXT from in either theme. Both
|
|
33
|
+
were measured, not guessed: `node scripts/contrast.mjs`. */
|
|
34
|
+
--slate-450: oklch(0.620 0.022 267);
|
|
35
|
+
--slate-500: oklch(0.588 0.022 267);
|
|
36
|
+
--slate-550: oklch(0.545 0.022 267);
|
|
37
|
+
--slate-600: oklch(0.492 0.023 267);
|
|
38
|
+
--slate-700: oklch(0.402 0.023 268);
|
|
39
|
+
--slate-750: oklch(0.348 0.023 268);
|
|
40
|
+
--slate-800: oklch(0.302 0.022 268);
|
|
41
|
+
--slate-850: oklch(0.264 0.021 268);
|
|
42
|
+
--slate-900: oklch(0.242 0.020 269);
|
|
43
|
+
--slate-950: oklch(0.212 0.019 269);
|
|
44
|
+
--slate-975: oklch(0.186 0.018 269);
|
|
45
|
+
|
|
46
|
+
/* --- Primary: AQUA -----------------------------------------------------
|
|
47
|
+
Electric cyan-teal. Luminous and unmistakably technical, but off the
|
|
48
|
+
default blue (250-260) that every framework ships, so it reads as chosen
|
|
49
|
+
rather than inherited. */
|
|
50
|
+
--aqua-50: oklch(0.974 0.022 196);
|
|
51
|
+
--aqua-100: oklch(0.944 0.046 196);
|
|
52
|
+
--aqua-200: oklch(0.896 0.078 196);
|
|
53
|
+
--aqua-300: oklch(0.846 0.100 197);
|
|
54
|
+
--aqua-400: oklch(0.802 0.116 198);
|
|
55
|
+
--aqua-500: oklch(0.748 0.126 199);
|
|
56
|
+
--aqua-600: oklch(0.664 0.118 201);
|
|
57
|
+
--aqua-700: oklch(0.554 0.098 203);
|
|
58
|
+
--aqua-800: oklch(0.448 0.078 205);
|
|
59
|
+
--aqua-900: oklch(0.352 0.058 207);
|
|
60
|
+
--aqua-950: oklch(0.262 0.042 209);
|
|
61
|
+
|
|
62
|
+
/* --- Signal: IRIS ------------------------------------------------------
|
|
63
|
+
The high-energy counterpart, rationed hard — hero moments, live states,
|
|
64
|
+
the one thing on screen that should pull the eye. Sitting at hue 302 it
|
|
65
|
+
is deliberately off the 277/292 violet-indigo that reads as generic. */
|
|
66
|
+
--iris-50: oklch(0.970 0.024 302);
|
|
67
|
+
--iris-100: oklch(0.938 0.050 302);
|
|
68
|
+
--iris-200: oklch(0.888 0.086 302);
|
|
69
|
+
--iris-300: oklch(0.824 0.120 302);
|
|
70
|
+
--iris-400: oklch(0.760 0.148 303);
|
|
71
|
+
--iris-500: oklch(0.700 0.166 303);
|
|
72
|
+
--iris-600: oklch(0.620 0.174 304);
|
|
73
|
+
/* A half-step, because iris-600 under WHITE text measures 3.91:1 — the
|
|
74
|
+
brand button's exact case, and a fail. This is the lightest, most
|
|
75
|
+
saturated violet that still clears AA with white on it (4.71:1), so the
|
|
76
|
+
brand keeps its punch instead of retreating to the much duller 700. */
|
|
77
|
+
--iris-650: oklch(0.575 0.165 304);
|
|
78
|
+
--iris-700: oklch(0.518 0.148 305);
|
|
79
|
+
--iris-800: oklch(0.422 0.118 306);
|
|
80
|
+
--iris-900: oklch(0.336 0.090 307);
|
|
81
|
+
--iris-950: oklch(0.250 0.066 308);
|
|
82
|
+
|
|
83
|
+
/* --- Status ramps ------------------------------------------------------
|
|
84
|
+
Hues spread widely (18 / 88 / 158 / 252) so status survives colour-vision
|
|
85
|
+
deficiency: lightness and hue-distance carry the signal, never red-vs-
|
|
86
|
+
green alone. Success sits at 158 — far enough from the 199 primary that
|
|
87
|
+
"succeeded" never reads as "selected". */
|
|
88
|
+
--rose-50: oklch(0.968 0.020 18);
|
|
89
|
+
--rose-100: oklch(0.932 0.042 18);
|
|
90
|
+
--rose-200: oklch(0.876 0.080 18);
|
|
91
|
+
--rose-300: oklch(0.794 0.130 20);
|
|
92
|
+
--rose-400: oklch(0.714 0.170 22);
|
|
93
|
+
--rose-500: oklch(0.646 0.200 24);
|
|
94
|
+
--rose-600: oklch(0.574 0.200 25);
|
|
95
|
+
--rose-700: oklch(0.480 0.170 26);
|
|
96
|
+
--rose-800: oklch(0.390 0.134 26);
|
|
97
|
+
--rose-900: oklch(0.310 0.100 26);
|
|
98
|
+
--rose-950: oklch(0.230 0.072 26);
|
|
99
|
+
|
|
100
|
+
--amber-50: oklch(0.980 0.024 92);
|
|
101
|
+
--amber-100: oklch(0.954 0.054 92);
|
|
102
|
+
--amber-200: oklch(0.910 0.100 90);
|
|
103
|
+
--amber-300: oklch(0.862 0.134 88);
|
|
104
|
+
--amber-400: oklch(0.814 0.150 86);
|
|
105
|
+
--amber-500: oklch(0.762 0.146 84);
|
|
106
|
+
--amber-600: oklch(0.670 0.130 80);
|
|
107
|
+
/* A half-step, for the light-theme confidence scale (SG-896): the lightest amber that still
|
|
108
|
+
clears WCAG 1.4.11 3:1 on BOTH light grounds (3.07 on slate-50, 3.35 on white) — 600 is
|
|
109
|
+
2.79 on the canvas. Measured with scripts/contrast.mjs, pinned by confidence-contrast.test. */
|
|
110
|
+
--amber-650: oklch(0.645 0.124 78);
|
|
111
|
+
--amber-700: oklch(0.554 0.108 76);
|
|
112
|
+
--amber-800: oklch(0.450 0.086 74);
|
|
113
|
+
--amber-900: oklch(0.358 0.066 72);
|
|
114
|
+
--amber-950: oklch(0.264 0.050 70);
|
|
115
|
+
|
|
116
|
+
--mint-50: oklch(0.972 0.026 158);
|
|
117
|
+
--mint-100: oklch(0.942 0.052 158);
|
|
118
|
+
--mint-200: oklch(0.892 0.084 158);
|
|
119
|
+
--mint-300: oklch(0.836 0.108 158);
|
|
120
|
+
--mint-400: oklch(0.780 0.122 159);
|
|
121
|
+
--mint-500: oklch(0.722 0.126 160);
|
|
122
|
+
--mint-600: oklch(0.636 0.114 161);
|
|
123
|
+
/* A half-step, for the same reason as amber-650: the lightest mint clearing 3:1 on both
|
|
124
|
+
light grounds (3.10 on slate-50, 3.39 on white) — 600 is 2.97 on the canvas. */
|
|
125
|
+
--mint-650: oklch(0.625 0.110 161);
|
|
126
|
+
--mint-700: oklch(0.528 0.094 162);
|
|
127
|
+
--mint-800: oklch(0.428 0.074 163);
|
|
128
|
+
--mint-900: oklch(0.338 0.056 164);
|
|
129
|
+
--mint-950: oklch(0.250 0.040 165);
|
|
130
|
+
|
|
131
|
+
--azure-50: oklch(0.970 0.020 252);
|
|
132
|
+
--azure-100: oklch(0.938 0.040 252);
|
|
133
|
+
--azure-200: oklch(0.884 0.072 252);
|
|
134
|
+
--azure-300: oklch(0.810 0.104 252);
|
|
135
|
+
--azure-400: oklch(0.730 0.130 253);
|
|
136
|
+
--azure-500: oklch(0.656 0.146 254);
|
|
137
|
+
--azure-600: oklch(0.576 0.154 255);
|
|
138
|
+
--azure-700: oklch(0.482 0.130 256);
|
|
139
|
+
--azure-800: oklch(0.394 0.102 257);
|
|
140
|
+
--azure-900: oklch(0.314 0.076 258);
|
|
141
|
+
--azure-950: oklch(0.234 0.054 259);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* ============================================================================
|
|
145
|
+
THE FIVE-STEP CONFIDENCE SCALE (SG-843 / SG-896 / SG-901).
|
|
146
|
+
|
|
147
|
+
One colour per level of a 1-5 self-rating, named by the operator: dark red,
|
|
148
|
+
light red, yellow, light green, dark green, plus a visible colour for "not
|
|
149
|
+
rated". Deliberately NOT the three status bands in tokens.css — a 4 and a 5
|
|
150
|
+
are both fine but must read as different, and three bands cannot say that.
|
|
151
|
+
|
|
152
|
+
ITS OWN FILE, SO IT CAN BE THE ONLY COPY. Every surface that draws a rating
|
|
153
|
+
reads these tokens: this library's `ConfidenceBar` (through tokens.css's
|
|
154
|
+
theme, via authored.css), and the demand letter's verification overlay — a
|
|
155
|
+
separate Vue package that is not a consumer of this design system, which
|
|
156
|
+
imports `dist/confidence.css` (this file plus palette.css, self-contained)
|
|
157
|
+
instead of keeping its own five colours. A second copy of five colours is how
|
|
158
|
+
a letter and the screen beside it came to disagree about what a 4 looks like.
|
|
159
|
+
|
|
160
|
+
EVERY STATE CLEARS WCAG 1.4.11 3:1 against its theme's surface and canvas —
|
|
161
|
+
an invisible level is the hidden state the bar exists to rule out. Pinned by
|
|
162
|
+
`src/__tests__/confidence-contrast.test.ts`, which reads this file.
|
|
163
|
+
|
|
164
|
+
Selectors mirror tokens.css exactly: dark is the default, an explicit
|
|
165
|
+
`[data-theme]` wins, and the OS preference applies only when nothing is set.
|
|
166
|
+
========================================================================= */
|
|
167
|
+
|
|
168
|
+
/* DARK (the default). "Dark" and "light" are relative to each other within a
|
|
169
|
+
hue; on the dark canvas the darker step is still lifted enough to read. */
|
|
170
|
+
:root,
|
|
171
|
+
[data-theme="dark"] {
|
|
172
|
+
--confidence-1: var(--rose-600);
|
|
173
|
+
--confidence-2: var(--rose-300);
|
|
174
|
+
--confidence-3: var(--amber-400);
|
|
175
|
+
--confidence-4: var(--mint-300);
|
|
176
|
+
--confidence-5: var(--mint-600);
|
|
177
|
+
--confidence-none: var(--slate-500);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* LIGHT. Every step clears 3:1 on white (10.3, 3.6, 3.4, 3.4, 7.9) and on the
|
|
181
|
+
slate-50 canvas, which is why these stops sit darker than the dark theme's:
|
|
182
|
+
rose-400, amber-400 and mint-400 measure 2.7, 1.8 and 1.9 on white. */
|
|
183
|
+
[data-theme="light"],
|
|
184
|
+
html:has(> body > script[src$="_ds_bundle.js"]) {
|
|
185
|
+
--confidence-1: var(--rose-800);
|
|
186
|
+
--confidence-2: var(--rose-500);
|
|
187
|
+
--confidence-3: var(--amber-650);
|
|
188
|
+
--confidence-4: var(--mint-650);
|
|
189
|
+
--confidence-5: var(--mint-800);
|
|
190
|
+
--confidence-none: var(--slate-500);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@media (prefers-color-scheme: light) {
|
|
194
|
+
:root:not([data-theme="dark"]):not([data-theme="light"]) {
|
|
195
|
+
--confidence-1: var(--rose-800);
|
|
196
|
+
--confidence-2: var(--rose-500);
|
|
197
|
+
--confidence-3: var(--amber-650);
|
|
198
|
+
--confidence-4: var(--mint-650);
|
|
199
|
+
--confidence-5: var(--mint-800);
|
|
200
|
+
--confidence-none: var(--slate-500);
|
|
201
|
+
}
|
|
202
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -46542,25 +46542,31 @@ function Q4({
|
|
|
46542
46542
|
) });
|
|
46543
46543
|
}
|
|
46544
46544
|
const J4 = pt({
|
|
46545
|
-
|
|
46545
|
+
slots: {
|
|
46546
|
+
slot: "flex shrink-0 overflow-hidden rounded-full",
|
|
46547
|
+
fill: "h-full rounded-full"
|
|
46548
|
+
},
|
|
46546
46549
|
variants: {
|
|
46547
46550
|
size: {
|
|
46548
46551
|
/* The dense form: under a glyph, in a strip of them. */
|
|
46549
|
-
xs: "h-[3px] w-[19px]",
|
|
46552
|
+
xs: { slot: "h-[3px] w-[19px]" },
|
|
46550
46553
|
/* The stated form: on a surface someone opened to read one value. */
|
|
46551
|
-
sm: "h-[5px] w-10"
|
|
46554
|
+
sm: { slot: "h-[5px] w-10" }
|
|
46552
46555
|
},
|
|
46556
|
+
/* Each level's fill written out whole, never assembled from a template string —
|
|
46557
|
+
Tailwind finds classes by scanning source text, and a class built at runtime is
|
|
46558
|
+
simply absent from the stylesheet. */
|
|
46553
46559
|
level: {
|
|
46554
|
-
1: "bg-confidence-1",
|
|
46555
|
-
2: "bg-confidence-2",
|
|
46556
|
-
3: "bg-confidence-3",
|
|
46557
|
-
4: "bg-confidence-4",
|
|
46558
|
-
5: "bg-confidence-5",
|
|
46559
|
-
/* Not rated —
|
|
46560
|
-
own token, not a general border one: every general border token
|
|
46561
|
-
WCAG 1.4.11's 3:1 on this library's surfaces, and an empty bar
|
|
46562
|
-
the hidden state this component exists to rule out. */
|
|
46563
|
-
none: "border border-
|
|
46560
|
+
1: { fill: "w-1/5 bg-confidence-1" },
|
|
46561
|
+
2: { fill: "w-2/5 bg-confidence-2" },
|
|
46562
|
+
3: { fill: "w-3/5 bg-confidence-3" },
|
|
46563
|
+
4: { fill: "w-4/5 bg-confidence-4" },
|
|
46564
|
+
5: { fill: "w-full bg-confidence-5" },
|
|
46565
|
+
/* Not rated — a dotted outline of the whole slot, so it cannot be mistaken for any
|
|
46566
|
+
earned level. Its own token, not a general border one: every general border token
|
|
46567
|
+
measures under WCAG 1.4.11's 3:1 on this library's surfaces, and an empty bar
|
|
46568
|
+
nobody can see is the hidden state this component exists to rule out. */
|
|
46569
|
+
none: { slot: "border border-dotted border-confidence-none" }
|
|
46564
46570
|
}
|
|
46565
46571
|
},
|
|
46566
46572
|
defaultVariants: { size: "sm", level: "none" }
|
|
@@ -46572,14 +46578,15 @@ function eH({
|
|
|
46572
46578
|
size: r,
|
|
46573
46579
|
className: o
|
|
46574
46580
|
}) {
|
|
46575
|
-
const s = e === null ? null : Y4(e, t), i = s === null || e === null ? `${n} — not rated` : `${n} ${String(Math.round(e))} of ${String(Math.round(t))}
|
|
46581
|
+
const s = e === null ? null : Y4(e, t), i = s === null || e === null ? `${n} — not rated` : `${n} ${String(Math.round(e))} of ${String(Math.round(t))}`, a = J4({ size: r, level: s ?? "none" });
|
|
46576
46582
|
return /* @__PURE__ */ f(ln, { content: i, children: /* @__PURE__ */ f(
|
|
46577
46583
|
"span",
|
|
46578
46584
|
{
|
|
46579
46585
|
role: "img",
|
|
46580
46586
|
"aria-label": i,
|
|
46581
46587
|
"data-level": s ?? "none",
|
|
46582
|
-
className: W(
|
|
46588
|
+
className: W(a.slot(), o),
|
|
46589
|
+
children: s === null ? null : /* @__PURE__ */ f("span", { "aria-hidden": "true", className: a.fill() })
|
|
46583
46590
|
}
|
|
46584
46591
|
) });
|
|
46585
46592
|
}
|