@ponchia/ui 0.4.0 → 0.5.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/CHANGELOG.md +352 -12
- package/MIGRATIONS.json +92 -0
- package/README.md +27 -17
- package/annotations/index.d.ts +280 -0
- package/annotations/index.js +522 -0
- package/behaviors/carousel.js +197 -0
- package/behaviors/combobox.js +195 -0
- package/behaviors/command.js +187 -0
- package/behaviors/connectors.js +96 -0
- package/behaviors/crosshair.js +58 -0
- package/behaviors/dialog.js +73 -0
- package/behaviors/disclosure.js +25 -0
- package/behaviors/dismissible.js +24 -0
- package/behaviors/forms.js +158 -0
- package/behaviors/glyph.js +109 -0
- package/behaviors/index.d.ts +82 -1
- package/behaviors/index.js +18 -1336
- package/behaviors/internal.js +50 -0
- package/behaviors/legend.js +46 -0
- package/behaviors/menu.js +46 -0
- package/behaviors/popover.js +108 -0
- package/behaviors/spotlight.js +53 -0
- package/behaviors/table.js +109 -0
- package/behaviors/tabs.js +103 -0
- package/behaviors/theme.js +82 -0
- package/behaviors/toast.js +152 -0
- package/classes/index.d.ts +318 -0
- package/classes/index.js +352 -0
- package/classes/vscode.css-custom-data.json +18 -14
- package/connectors/index.d.ts +71 -0
- package/connectors/index.js +179 -0
- package/css/analytical.css +21 -0
- package/css/annotations.css +292 -0
- package/css/command.css +97 -0
- package/css/connectors.css +93 -0
- package/css/crosshair.css +100 -0
- package/css/disclosure.css +29 -0
- package/css/dots.css +2 -0
- package/css/feedback.css +104 -0
- package/css/fonts.css +11 -7
- package/css/generated.css +117 -0
- package/css/legend.css +268 -0
- package/css/marks.css +144 -0
- package/css/motion.css +88 -0
- package/css/overlay.css +52 -1
- package/css/primitives.css +18 -0
- package/css/report.css +363 -0
- package/css/selection.css +46 -0
- package/css/sources.css +179 -0
- package/css/spotlight.css +104 -0
- package/css/state.css +121 -0
- package/css/tokens.css +78 -60
- package/css/workbench.css +83 -0
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -0
- package/dist/css/annotations.css +1 -0
- package/dist/css/command.css +1 -0
- package/dist/css/connectors.css +1 -0
- package/dist/css/crosshair.css +1 -0
- package/dist/css/disclosure.css +1 -1
- package/dist/css/dots.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/fonts.css +1 -1
- package/dist/css/generated.css +1 -0
- package/dist/css/legend.css +1 -0
- package/dist/css/marks.css +1 -0
- package/dist/css/motion.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report.css +1 -0
- package/dist/css/selection.css +1 -0
- package/dist/css/sources.css +1 -0
- package/dist/css/spotlight.css +1 -0
- package/dist/css/state.css +1 -0
- package/dist/css/tokens.css +1 -1
- package/dist/css/workbench.css +1 -0
- package/docs/adr/0001-color-system.md +26 -27
- package/docs/adr/0002-scope-and-2026-baseline.md +104 -0
- package/docs/adr/0003-theme-model.md +97 -0
- package/docs/annotations.md +345 -0
- package/docs/architecture.md +202 -0
- package/docs/command.md +95 -0
- package/docs/connectors.md +91 -0
- package/docs/contrast.md +42 -42
- package/docs/crosshair.md +63 -0
- package/docs/generated.md +91 -0
- package/docs/legends.md +168 -0
- package/docs/marks.md +86 -0
- package/docs/reference.md +418 -15
- package/docs/reporting.md +305 -0
- package/docs/selection.md +40 -0
- package/docs/sources.md +110 -0
- package/docs/spotlight.md +78 -0
- package/docs/stability.md +52 -0
- package/docs/state.md +85 -0
- package/docs/theming.md +18 -6
- package/docs/usage.md +43 -3
- package/docs/workbench.md +72 -0
- package/fonts/doto-400.woff2 +0 -0
- package/fonts/doto-500.woff2 +0 -0
- package/fonts/doto-600.woff2 +0 -0
- package/fonts/doto-700.woff2 +0 -0
- package/fonts/doto-800.woff2 +0 -0
- package/fonts/doto-900.woff2 +0 -0
- package/llms.txt +288 -8
- package/package.json +95 -5
- package/qwik/index.d.ts +60 -0
- package/qwik/index.js +149 -0
- package/react/index.d.ts +40 -14
- package/react/index.js +32 -5
- package/solid/index.d.ts +40 -14
- package/solid/index.js +31 -3
- package/tokens/index.d.ts +3 -3
- package/tokens/index.js +25 -19
- package/tokens/index.json +32 -28
- package/tokens/resolved.json +34 -32
- package/tokens/tokens.dtcg.json +22 -14
- package/fonts/doto-400.ttf +0 -0
- package/fonts/doto-500.ttf +0 -0
- package/fonts/doto-600.ttf +0 -0
- package/fonts/doto-700.ttf +0 -0
- package/fonts/doto-800.ttf +0 -0
- package/fonts/doto-900.ttf +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
crosshair — opt-in ruler + readout for reading a value off a plot.
|
|
3
|
+
|
|
4
|
+
A pointer-tracking crosshair (vertical/horizontal rules), axis value badges,
|
|
5
|
+
and a pinned readout chip — the *visual* language of precise reading. Bronto
|
|
6
|
+
draws the rules and (via `initCrosshair`) tracks the pointer, setting
|
|
7
|
+
`--crosshair-x/y` (pixels within the plot) and emitting the pointer position
|
|
8
|
+
as a fraction. It does NOT find the nearest data point or map pixels to data
|
|
9
|
+
— that needs the host's scales. Not imported by core.css.
|
|
10
|
+
========================================================================== */
|
|
11
|
+
|
|
12
|
+
.ui-crosshair {
|
|
13
|
+
--crosshair-x: 0;
|
|
14
|
+
--crosshair-y: 0;
|
|
15
|
+
--crosshair-color: var(--accent);
|
|
16
|
+
|
|
17
|
+
inset: 0;
|
|
18
|
+
opacity: 0;
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
position: absolute;
|
|
21
|
+
transition: opacity 0.12s ease;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ui-crosshair.is-active {
|
|
25
|
+
opacity: 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@media (prefers-reduced-motion: reduce) {
|
|
29
|
+
.ui-crosshair {
|
|
30
|
+
transition: none;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.ui-crosshair--muted {
|
|
35
|
+
--crosshair-color: var(--line-strong);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.ui-crosshair__line {
|
|
39
|
+
background: var(--crosshair-color);
|
|
40
|
+
position: absolute;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.ui-crosshair__line--x {
|
|
44
|
+
inline-size: 1px;
|
|
45
|
+
inset-block: 0;
|
|
46
|
+
inset-inline-start: 0;
|
|
47
|
+
transform: translateX(var(--crosshair-x));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ui-crosshair__line--y {
|
|
51
|
+
block-size: 1px;
|
|
52
|
+
inset-block-start: 0;
|
|
53
|
+
inset-inline: 0;
|
|
54
|
+
transform: translateY(var(--crosshair-y));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* An axis value chip (host sets its text + which edge it sits on). On the
|
|
58
|
+
accent fill it uses the tested on-accent text (same as buttons). */
|
|
59
|
+
.ui-crosshair__badge {
|
|
60
|
+
background: var(--crosshair-color);
|
|
61
|
+
border-radius: var(--radius-sm);
|
|
62
|
+
color: var(--button-text);
|
|
63
|
+
font-family: var(--mono);
|
|
64
|
+
font-size: var(--text-2xs);
|
|
65
|
+
padding-block: 0.05rem;
|
|
66
|
+
padding-inline: 0.3rem;
|
|
67
|
+
position: absolute;
|
|
68
|
+
white-space: nowrap;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* The muted crosshair's grey fill can't carry on-accent text — use a neutral chip. */
|
|
72
|
+
.ui-crosshair--muted .ui-crosshair__badge {
|
|
73
|
+
background: var(--panel);
|
|
74
|
+
border: 1px solid var(--line-strong);
|
|
75
|
+
color: var(--text);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* A pinned readout chip — host fills the content; it follows the crosshair. */
|
|
79
|
+
.ui-readout {
|
|
80
|
+
background: var(--panel);
|
|
81
|
+
border: 1px solid var(--line);
|
|
82
|
+
border-radius: var(--radius-sm);
|
|
83
|
+
box-shadow: var(--shadow-raised);
|
|
84
|
+
color: var(--text);
|
|
85
|
+
font-family: var(--mono);
|
|
86
|
+
font-size: var(--text-xs);
|
|
87
|
+
inset-block-start: 0;
|
|
88
|
+
inset-inline-start: 0;
|
|
89
|
+
padding-block: 0.2rem;
|
|
90
|
+
padding-inline: 0.4rem;
|
|
91
|
+
pointer-events: none;
|
|
92
|
+
position: absolute;
|
|
93
|
+
transform: translate(var(--crosshair-x), var(--crosshair-y));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@media (forced-colors: active) {
|
|
97
|
+
.ui-crosshair__line {
|
|
98
|
+
background: CanvasText;
|
|
99
|
+
}
|
|
100
|
+
}
|
package/css/disclosure.css
CHANGED
|
@@ -128,6 +128,35 @@
|
|
|
128
128
|
margin-block-start: 0;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/* Auto-height open/close for the native <details> accordion: animate the
|
|
132
|
+
content box from 0 to its intrinsic height. `interpolate-size:
|
|
133
|
+
allow-keywords` makes `auto` interpolable; `::details-content` exposes
|
|
134
|
+
the otherwise-anonymous content box; `content-visibility ... allow-discrete`
|
|
135
|
+
keeps the content laid out (and the dot marker's own rotation in sync)
|
|
136
|
+
through the close. Strict progressive enhancement — gated on
|
|
137
|
+
`@supports selector(::details-content)` (Chrome 131+/Safari 18.4+; Firefox
|
|
138
|
+
not yet) so engines without it just snap open/closed exactly as before —
|
|
139
|
+
and on `prefers-reduced-motion: no-preference`. */
|
|
140
|
+
@supports selector(::details-content) {
|
|
141
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
142
|
+
.ui-accordion {
|
|
143
|
+
interpolate-size: allow-keywords;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.ui-accordion__item::details-content {
|
|
147
|
+
block-size: 0;
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
transition:
|
|
150
|
+
block-size var(--duration-base) var(--ease-out),
|
|
151
|
+
content-visibility var(--duration-base) allow-discrete;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.ui-accordion__item[open]::details-content {
|
|
155
|
+
block-size: auto;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
131
160
|
/* --- Segmented control — CSS-only radio group --- */
|
|
132
161
|
|
|
133
162
|
.ui-segmented {
|
package/css/dots.css
CHANGED
|
@@ -129,6 +129,8 @@
|
|
|
129
129
|
block-size: var(--icon-size, 1em);
|
|
130
130
|
background: currentcolor;
|
|
131
131
|
vertical-align: -0.125em;
|
|
132
|
+
/* stylelint-disable-next-line property-no-vendor-prefix -- Safari still needs the prefixed mask property. */
|
|
133
|
+
-webkit-mask: var(--icon-mask) center / contain no-repeat;
|
|
132
134
|
mask: var(--icon-mask) center / contain no-repeat;
|
|
133
135
|
}
|
|
134
136
|
|
package/css/feedback.css
CHANGED
|
@@ -27,6 +27,9 @@
|
|
|
27
27
|
block-size: 0.5rem;
|
|
28
28
|
margin-block-start: 0.32rem;
|
|
29
29
|
inline-size: 0.5rem;
|
|
30
|
+
|
|
31
|
+
/* Keep the tone dot when printing (matches the legend swatch). */
|
|
32
|
+
print-color-adjust: exact;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
.ui-alert > * {
|
|
@@ -135,6 +138,14 @@
|
|
|
135
138
|
.ui-toast {
|
|
136
139
|
align-items: flex-start;
|
|
137
140
|
animation: uiToastIn var(--duration-base) var(--ease-spring) both;
|
|
141
|
+
|
|
142
|
+
/* Exit is a transition (not a keyframe): the behavior adds `.is-leaving`
|
|
143
|
+
and removes the node when this transition ends. Entrance stays the
|
|
144
|
+
keyframe above — the transition only fires on the `.is-leaving`
|
|
145
|
+
property change, never on insert. */
|
|
146
|
+
transition:
|
|
147
|
+
opacity var(--duration-base) var(--ease-out),
|
|
148
|
+
transform var(--duration-base) var(--ease-out);
|
|
138
149
|
background: var(--panel-strong);
|
|
139
150
|
border: 1px solid var(--line-strong);
|
|
140
151
|
border-radius: var(--radius-md);
|
|
@@ -149,6 +160,15 @@
|
|
|
149
160
|
inline-size: 100%;
|
|
150
161
|
}
|
|
151
162
|
|
|
163
|
+
/* Leaving — fade + drop out. `animation: none` releases the entrance
|
|
164
|
+
keyframe's `both` fill (a filling animation outranks normal property
|
|
165
|
+
declarations, so without this the exit values would be ignored). */
|
|
166
|
+
.ui-toast.is-leaving {
|
|
167
|
+
animation: none;
|
|
168
|
+
opacity: 0;
|
|
169
|
+
transform: translateY(6px) scale(0.98);
|
|
170
|
+
}
|
|
171
|
+
|
|
152
172
|
.ui-toast::before {
|
|
153
173
|
background: var(--text-dim);
|
|
154
174
|
border-radius: 50%;
|
|
@@ -157,6 +177,9 @@
|
|
|
157
177
|
block-size: 0.5rem;
|
|
158
178
|
margin-block-start: 0.3rem;
|
|
159
179
|
inline-size: 0.5rem;
|
|
180
|
+
|
|
181
|
+
/* Keep the tone dot when printing (matches the legend swatch). */
|
|
182
|
+
print-color-adjust: exact;
|
|
160
183
|
}
|
|
161
184
|
|
|
162
185
|
.ui-toast__title {
|
|
@@ -213,6 +236,51 @@
|
|
|
213
236
|
background: var(--info);
|
|
214
237
|
}
|
|
215
238
|
|
|
239
|
+
/* Forced-colors (Windows HCM): system colours override the rationed tone
|
|
240
|
+
colour on the dot + border, so all tones would collapse to one appearance
|
|
241
|
+
(WCAG 1.4.1 — colour as the sole channel). Carry the tone as a distinct
|
|
242
|
+
glyph instead; rendered as text it survives HCM as CanvasText. The glyph is
|
|
243
|
+
inherited via --tone-glyph so one rule covers both alert and toast. */
|
|
244
|
+
@media (forced-colors: active) {
|
|
245
|
+
.ui-alert::before,
|
|
246
|
+
.ui-toast::before {
|
|
247
|
+
background: none;
|
|
248
|
+
border-radius: 0;
|
|
249
|
+
content: var(--tone-glyph, '\2022'); /* • neutral default */
|
|
250
|
+
block-size: auto;
|
|
251
|
+
inline-size: auto;
|
|
252
|
+
margin-block-start: 0;
|
|
253
|
+
font-family: var(--mono);
|
|
254
|
+
font-weight: 700;
|
|
255
|
+
line-height: 1.1;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.ui-alert--accent,
|
|
259
|
+
.ui-toast--accent {
|
|
260
|
+
--tone-glyph: '\25C6'; /* ◆ */
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.ui-alert--success,
|
|
264
|
+
.ui-toast--success {
|
|
265
|
+
--tone-glyph: '\2713'; /* ✓ */
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.ui-alert--warning,
|
|
269
|
+
.ui-toast--warning {
|
|
270
|
+
--tone-glyph: '\0021'; /* ! */
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.ui-alert--danger,
|
|
274
|
+
.ui-toast--danger {
|
|
275
|
+
--tone-glyph: '\2715'; /* ✕ */
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.ui-alert--info,
|
|
279
|
+
.ui-toast--info {
|
|
280
|
+
--tone-glyph: '\69'; /* i */
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
216
284
|
/* --- Tooltip — CSS-only, hover/focus, no JS --- */
|
|
217
285
|
|
|
218
286
|
.ui-tooltip {
|
|
@@ -302,6 +370,41 @@
|
|
|
302
370
|
display: none;
|
|
303
371
|
}
|
|
304
372
|
|
|
373
|
+
/* Enter AND exit motion — zero JS, the same `@starting-style` +
|
|
374
|
+
`transition-behavior: allow-discrete` recipe as the modal (overlay.css).
|
|
375
|
+
It covers BOTH paths initPopover can take: the native `[popover]` top
|
|
376
|
+
layer (where the `overlay` transition keeps the panel painted while it
|
|
377
|
+
animates out before leaving the layer) and the `.is-open` fallback (a
|
|
378
|
+
regular element, so `display allow-discrete` alone carries the exit).
|
|
379
|
+
Gated on `prefers-reduced-motion: no-preference`, so reduced-motion users
|
|
380
|
+
keep the instant open/close they had before. JS positions the panel via
|
|
381
|
+
`top`/`left`, so the entrance `transform` is free to animate. */
|
|
382
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
383
|
+
.ui-popover {
|
|
384
|
+
opacity: 0;
|
|
385
|
+
transform: translateY(-4px) scale(0.98);
|
|
386
|
+
transition:
|
|
387
|
+
opacity var(--duration-fast) var(--ease-out),
|
|
388
|
+
transform var(--duration-fast) var(--ease-out),
|
|
389
|
+
overlay var(--duration-fast) allow-discrete,
|
|
390
|
+
display var(--duration-fast) allow-discrete;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.ui-popover.is-open,
|
|
394
|
+
.ui-popover[popover]:popover-open {
|
|
395
|
+
opacity: 1;
|
|
396
|
+
transform: none;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
@starting-style {
|
|
400
|
+
.ui-popover.is-open,
|
|
401
|
+
.ui-popover[popover]:popover-open {
|
|
402
|
+
opacity: 0;
|
|
403
|
+
transform: translateY(-4px) scale(0.98);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
305
408
|
/* --- Progress — linear, determinate or indeterminate --- */
|
|
306
409
|
|
|
307
410
|
.ui-progress {
|
|
@@ -336,6 +439,7 @@
|
|
|
336
439
|
|
|
337
440
|
.ui-toast {
|
|
338
441
|
animation: none;
|
|
442
|
+
transition: none;
|
|
339
443
|
}
|
|
340
444
|
}
|
|
341
445
|
|
package/css/fonts.css
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
@ponchia/ui — Doto webfont (dot-matrix display face)
|
|
3
3
|
|
|
4
4
|
URLs are relative to this file. When the package is consumed through a
|
|
5
|
-
bundler (Vite/astro/webpack) the `../fonts/*.
|
|
5
|
+
bundler (Vite/astro/webpack) the `../fonts/*.woff2` references are rewritten
|
|
6
6
|
and the files emitted automatically. When served statically, ship the
|
|
7
7
|
package's `fonts/` directory next to `css/` and it resolves as-is.
|
|
8
8
|
|
|
9
|
+
Shipped as woff2 only (Brotli-compressed) — ~5.7 kB per weight vs ~137 kB
|
|
10
|
+
uncompressed TTF. woff2 is supported by the whole browser floor (ADR-0002:
|
|
11
|
+
Chrome 125 / Safari 18 / Firefox 129), so no TTF fallback is carried.
|
|
12
|
+
|
|
9
13
|
This file is optional: it is bundled into core.css/index.css, but a
|
|
10
14
|
consumer that hosts Doto itself (or overrides `--display` / `--dot-font`)
|
|
11
15
|
can import the rest of the framework without it.
|
|
@@ -16,7 +20,7 @@
|
|
|
16
20
|
font-style: normal;
|
|
17
21
|
font-weight: 400;
|
|
18
22
|
font-display: swap;
|
|
19
|
-
src: url('../fonts/doto-400.
|
|
23
|
+
src: url('../fonts/doto-400.woff2') format('woff2');
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
@font-face {
|
|
@@ -24,7 +28,7 @@
|
|
|
24
28
|
font-style: normal;
|
|
25
29
|
font-weight: 500;
|
|
26
30
|
font-display: swap;
|
|
27
|
-
src: url('../fonts/doto-500.
|
|
31
|
+
src: url('../fonts/doto-500.woff2') format('woff2');
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
@font-face {
|
|
@@ -32,7 +36,7 @@
|
|
|
32
36
|
font-style: normal;
|
|
33
37
|
font-weight: 600;
|
|
34
38
|
font-display: swap;
|
|
35
|
-
src: url('../fonts/doto-600.
|
|
39
|
+
src: url('../fonts/doto-600.woff2') format('woff2');
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
@font-face {
|
|
@@ -40,7 +44,7 @@
|
|
|
40
44
|
font-style: normal;
|
|
41
45
|
font-weight: 700;
|
|
42
46
|
font-display: swap;
|
|
43
|
-
src: url('../fonts/doto-700.
|
|
47
|
+
src: url('../fonts/doto-700.woff2') format('woff2');
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
@font-face {
|
|
@@ -48,7 +52,7 @@
|
|
|
48
52
|
font-style: normal;
|
|
49
53
|
font-weight: 800;
|
|
50
54
|
font-display: swap;
|
|
51
|
-
src: url('../fonts/doto-800.
|
|
55
|
+
src: url('../fonts/doto-800.woff2') format('woff2');
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
@font-face {
|
|
@@ -56,7 +60,7 @@
|
|
|
56
60
|
font-style: normal;
|
|
57
61
|
font-weight: 900;
|
|
58
62
|
font-display: swap;
|
|
59
|
-
src: url('../fonts/doto-900.
|
|
63
|
+
src: url('../fonts/doto-900.woff2') format('woff2');
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
/* Data-saver: never *use* Doto, so the browser never fetches it. The
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
generated — opt-in trust surfaces for AI / system-generated content.
|
|
3
|
+
|
|
4
|
+
AI interfaces are becoming common, but most UI systems ship chat bubbles or
|
|
5
|
+
nothing. Bronto is not a chat framework — it owns the *trust* surfaces around
|
|
6
|
+
generated content: a marked region, an origin label, and quiet collapsible
|
|
7
|
+
reasoning / tool-call logs. Pairs with the source/citation layer
|
|
8
|
+
(css/sources.css). The host owns model metadata, reasoning-visibility policy,
|
|
9
|
+
tool execution, traces, redaction, and safety. Not imported by core.css.
|
|
10
|
+
========================================================================== */
|
|
11
|
+
|
|
12
|
+
/* --- Generated region — a marked wrapper for machine-authored content. --- */
|
|
13
|
+
.ui-generated {
|
|
14
|
+
background: color-mix(in srgb, var(--accent) 4%, transparent);
|
|
15
|
+
border: 1px solid var(--line);
|
|
16
|
+
border-inline-start: 2px solid var(--accent);
|
|
17
|
+
border-radius: var(--radius-md);
|
|
18
|
+
display: grid;
|
|
19
|
+
gap: var(--space-xs);
|
|
20
|
+
padding: 0.85rem 1rem;
|
|
21
|
+
print-color-adjust: exact;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ui-generated__label {
|
|
25
|
+
align-items: center;
|
|
26
|
+
color: var(--text-dim);
|
|
27
|
+
display: inline-flex;
|
|
28
|
+
font-family: var(--mono);
|
|
29
|
+
font-size: var(--text-2xs);
|
|
30
|
+
gap: 0.4rem;
|
|
31
|
+
letter-spacing: var(--tracking-wide);
|
|
32
|
+
text-transform: uppercase;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* --- Origin label — "AI assisted" / "model output" / "human reviewed". --- */
|
|
36
|
+
.ui-origin-label {
|
|
37
|
+
align-items: center;
|
|
38
|
+
border: 1px solid var(--line);
|
|
39
|
+
border-radius: var(--radius-pill);
|
|
40
|
+
color: var(--text-soft);
|
|
41
|
+
display: inline-flex;
|
|
42
|
+
font-family: var(--mono);
|
|
43
|
+
font-size: var(--text-2xs);
|
|
44
|
+
gap: 0.35rem;
|
|
45
|
+
letter-spacing: var(--tracking-wide);
|
|
46
|
+
padding: 0.08rem 0.55rem;
|
|
47
|
+
text-transform: uppercase;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ui-origin-label--ai {
|
|
51
|
+
border-color: var(--accent);
|
|
52
|
+
color: var(--accent-text);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* --- Reasoning — a quiet, collapsible "how this was produced" block. --- */
|
|
56
|
+
.ui-reasoning {
|
|
57
|
+
color: var(--text-dim);
|
|
58
|
+
font-size: var(--text-sm);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.ui-reasoning > summary {
|
|
62
|
+
color: var(--text-soft);
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
font-family: var(--mono);
|
|
65
|
+
font-size: var(--text-2xs);
|
|
66
|
+
letter-spacing: var(--tracking-wide);
|
|
67
|
+
text-transform: uppercase;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.ui-reasoning__body {
|
|
71
|
+
margin-block-start: var(--space-xs);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* --- Tool log — a quiet, document-grade record of tool invocations. --- */
|
|
75
|
+
.ui-tool-log {
|
|
76
|
+
display: grid;
|
|
77
|
+
gap: var(--space-2xs);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.ui-tool-call {
|
|
81
|
+
border: 1px solid var(--line);
|
|
82
|
+
border-radius: var(--radius-sm);
|
|
83
|
+
font-family: var(--mono);
|
|
84
|
+
font-size: var(--text-2xs);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ui-tool-call > summary {
|
|
88
|
+
align-items: center;
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
display: flex;
|
|
91
|
+
gap: 0.5rem;
|
|
92
|
+
padding: 0.4rem 0.6rem;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.ui-tool-call__name {
|
|
96
|
+
color: var(--text);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ui-tool-call__status {
|
|
100
|
+
color: var(--text-dim);
|
|
101
|
+
margin-inline-start: auto;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.ui-tool-call__body {
|
|
105
|
+
border-block-start: 1px solid var(--line);
|
|
106
|
+
color: var(--text-soft);
|
|
107
|
+
margin: 0;
|
|
108
|
+
overflow-x: auto;
|
|
109
|
+
padding: 0.5rem 0.6rem;
|
|
110
|
+
white-space: pre-wrap;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@media (forced-colors: active) {
|
|
114
|
+
.ui-generated {
|
|
115
|
+
border-inline-start-color: CanvasText;
|
|
116
|
+
}
|
|
117
|
+
}
|