@ponchia/ui 0.4.1 → 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 +230 -8
- package/MIGRATIONS.json +92 -0
- package/README.md +9 -6
- 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 +79 -0
- package/behaviors/index.js +18 -1409
- 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 +280 -2
- package/classes/index.js +313 -2
- 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/feedback.css +51 -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/primitives.css +18 -0
- package/css/report.css +12 -31
- 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 +25 -37
- 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/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/primitives.css +1 -1
- package/dist/css/report.css +1 -1
- 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/workbench.css +1 -0
- package/docs/adr/0003-theme-model.md +7 -4
- 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/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 +309 -3
- package/docs/reporting.md +49 -14
- package/docs/selection.md +40 -0
- package/docs/sources.md +110 -0
- package/docs/spotlight.md +78 -0
- package/docs/stability.md +16 -1
- package/docs/state.md +85 -0
- package/docs/usage.md +22 -0
- 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 +229 -6
- package/package.json +69 -4
- package/qwik/index.d.ts +5 -0
- package/qwik/index.js +20 -0
- package/react/index.d.ts +5 -0
- package/react/index.js +10 -0
- package/solid/index.d.ts +5 -0
- package/solid/index.js +10 -0
- package/tokens/index.js +9 -5
- 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
package/css/sources.css
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
sources — opt-in source, citation & provenance grammar (the trust layer).
|
|
3
|
+
|
|
4
|
+
For generated reports, AI output, audits and docs that must answer "where
|
|
5
|
+
did this come from?". Bronto owns the visual grammar + the trust states; the
|
|
6
|
+
host owns fetching, citation numbering, and whether a source is trustworthy.
|
|
7
|
+
The state is carried by a rationed tone dot/border AND an author-written
|
|
8
|
+
label, so it never relies on colour alone (WCAG 1.4.1). Not imported by
|
|
9
|
+
core.css.
|
|
10
|
+
|
|
11
|
+
States (cross-cutting `.ui-src--*`, set the tone): verified · reviewed ·
|
|
12
|
+
generated · unverified · stale · conflict.
|
|
13
|
+
========================================================================== */
|
|
14
|
+
|
|
15
|
+
/* One tone, shared by citation / source-card / provenance via `--src-tone`. */
|
|
16
|
+
.ui-citation,
|
|
17
|
+
.ui-source-card,
|
|
18
|
+
.ui-provenance {
|
|
19
|
+
--src-tone: var(--text-dim);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ui-src--verified {
|
|
23
|
+
--src-tone: var(--success);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.ui-src--reviewed {
|
|
27
|
+
--src-tone: var(--accent);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.ui-src--generated {
|
|
31
|
+
--src-tone: var(--info);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.ui-src--unverified {
|
|
35
|
+
--src-tone: var(--text-dim);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.ui-src--stale {
|
|
39
|
+
--src-tone: var(--warning);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.ui-src--conflict {
|
|
43
|
+
--src-tone: var(--danger);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* --- Inline citation — a reference marker on an <a> or <button>. --- */
|
|
47
|
+
.ui-citation {
|
|
48
|
+
color: var(--accent-text);
|
|
49
|
+
font-family: var(--mono);
|
|
50
|
+
font-size: 0.72em;
|
|
51
|
+
font-weight: 600;
|
|
52
|
+
text-decoration: none;
|
|
53
|
+
vertical-align: super;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.ui-citation:hover {
|
|
57
|
+
text-decoration: underline;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Named-source pill — full size, with a leading tone dot. */
|
|
61
|
+
.ui-citation--chip {
|
|
62
|
+
align-items: center;
|
|
63
|
+
background: var(--panel-soft);
|
|
64
|
+
border: 1px solid var(--line);
|
|
65
|
+
border-radius: var(--radius-pill);
|
|
66
|
+
color: var(--text-soft);
|
|
67
|
+
display: inline-flex;
|
|
68
|
+
font-size: var(--text-2xs);
|
|
69
|
+
gap: 0.35rem;
|
|
70
|
+
padding: 0.08rem 0.55rem;
|
|
71
|
+
vertical-align: baseline;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ui-citation--chip::before {
|
|
75
|
+
background: var(--src-tone);
|
|
76
|
+
border-radius: 50%;
|
|
77
|
+
block-size: 0.45rem;
|
|
78
|
+
content: '';
|
|
79
|
+
inline-size: 0.45rem;
|
|
80
|
+
print-color-adjust: exact;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* --- Source list — a references section. --- */
|
|
84
|
+
.ui-source-list {
|
|
85
|
+
display: grid;
|
|
86
|
+
gap: var(--space-sm);
|
|
87
|
+
list-style: none;
|
|
88
|
+
margin: 0;
|
|
89
|
+
padding: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.ui-source-list__item {
|
|
93
|
+
margin: 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* --- Source card — a single source preview. --- */
|
|
97
|
+
.ui-source-card {
|
|
98
|
+
background: var(--panel-soft);
|
|
99
|
+
border: 1px solid var(--line);
|
|
100
|
+
border-inline-start: 2px solid var(--src-tone);
|
|
101
|
+
border-radius: var(--radius-md);
|
|
102
|
+
display: grid;
|
|
103
|
+
gap: 0.3rem;
|
|
104
|
+
padding: 0.75rem 0.9rem;
|
|
105
|
+
print-color-adjust: exact;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.ui-source-card__title {
|
|
109
|
+
color: var(--text);
|
|
110
|
+
font-size: var(--text-sm);
|
|
111
|
+
font-weight: 600;
|
|
112
|
+
margin: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.ui-source-card__origin {
|
|
116
|
+
color: var(--text-soft);
|
|
117
|
+
font-family: var(--mono);
|
|
118
|
+
font-size: var(--text-2xs);
|
|
119
|
+
letter-spacing: var(--tracking-wide);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.ui-source-card__time {
|
|
123
|
+
color: var(--text-dim);
|
|
124
|
+
font-family: var(--mono);
|
|
125
|
+
font-size: var(--text-2xs);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.ui-source-card__excerpt {
|
|
129
|
+
color: var(--text-soft);
|
|
130
|
+
margin: 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.ui-source-card__actions {
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-wrap: wrap;
|
|
136
|
+
gap: 0.5rem;
|
|
137
|
+
margin-block-start: 0.2rem;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* --- Provenance — compact metadata beside generated content. --- */
|
|
141
|
+
.ui-provenance {
|
|
142
|
+
align-items: center;
|
|
143
|
+
color: var(--text-dim);
|
|
144
|
+
display: inline-flex;
|
|
145
|
+
flex-wrap: wrap;
|
|
146
|
+
font-family: var(--mono);
|
|
147
|
+
font-size: var(--text-2xs);
|
|
148
|
+
gap: 0.3rem 0.75rem;
|
|
149
|
+
letter-spacing: var(--tracking-wide);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.ui-provenance__item {
|
|
153
|
+
align-items: center;
|
|
154
|
+
display: inline-flex;
|
|
155
|
+
gap: 0.35rem;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.ui-provenance__item::before {
|
|
159
|
+
background: var(--src-tone);
|
|
160
|
+
border-radius: 50%;
|
|
161
|
+
block-size: 0.45rem;
|
|
162
|
+
content: '';
|
|
163
|
+
inline-size: 0.45rem;
|
|
164
|
+
print-color-adjust: exact;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Forced colours: the tone dot/border collapses to a system colour, so the
|
|
168
|
+
author-written label is the surviving state channel (it already must be —
|
|
169
|
+
1.4.1). Keep the marks visible as CanvasText rather than letting them vanish. */
|
|
170
|
+
@media (forced-colors: active) {
|
|
171
|
+
.ui-citation--chip::before,
|
|
172
|
+
.ui-provenance__item::before {
|
|
173
|
+
background: CanvasText;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.ui-source-card {
|
|
177
|
+
border-inline-start-color: CanvasText;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
spotlight — opt-in guided-focus overlay (the visual language of a tour).
|
|
3
|
+
|
|
4
|
+
A dimming overlay with a cutout over a target element, an optional target
|
|
5
|
+
ring, and a callout note. Bronto owns the *look* and (via `initSpotlight`)
|
|
6
|
+
positions the cutout over a target; it is NOT a tour engine — step order,
|
|
7
|
+
advancing, and persistence are the host's. Not imported by core.css.
|
|
8
|
+
|
|
9
|
+
The cutout is a single box-shadow hole driven by JS-set custom properties
|
|
10
|
+
(`--spot-x/y/w/h`, viewport coordinates). The overlay is non-blocking
|
|
11
|
+
(`pointer-events: none`) — a visual highlight, not a modal trap.
|
|
12
|
+
========================================================================== */
|
|
13
|
+
|
|
14
|
+
.ui-spotlight {
|
|
15
|
+
--spot-x: 50%;
|
|
16
|
+
--spot-y: 50%;
|
|
17
|
+
--spot-w: 0px;
|
|
18
|
+
--spot-h: 0px;
|
|
19
|
+
--spot-pad: 8px;
|
|
20
|
+
--spot-radius: var(--radius-md);
|
|
21
|
+
--spot-backdrop: color-mix(in srgb, #000 55%, transparent);
|
|
22
|
+
|
|
23
|
+
inset: 0;
|
|
24
|
+
pointer-events: none;
|
|
25
|
+
position: fixed;
|
|
26
|
+
z-index: var(--z-overlay, 1000);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ui-spotlight__hole {
|
|
30
|
+
background: transparent;
|
|
31
|
+
block-size: calc(var(--spot-h) + var(--spot-pad) * 2);
|
|
32
|
+
border-radius: var(--spot-radius);
|
|
33
|
+
box-shadow: 0 0 0 100vmax var(--spot-backdrop);
|
|
34
|
+
inline-size: calc(var(--spot-w) + var(--spot-pad) * 2);
|
|
35
|
+
inset-block-start: 0;
|
|
36
|
+
inset-inline-start: 0;
|
|
37
|
+
position: absolute;
|
|
38
|
+
transform: translate(
|
|
39
|
+
calc(var(--spot-x) - var(--spot-pad)),
|
|
40
|
+
calc(var(--spot-y) - var(--spot-pad))
|
|
41
|
+
);
|
|
42
|
+
transition:
|
|
43
|
+
transform 0.2s ease,
|
|
44
|
+
inline-size 0.2s ease,
|
|
45
|
+
block-size 0.2s ease;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@media (prefers-reduced-motion: reduce) {
|
|
49
|
+
.ui-spotlight__hole {
|
|
50
|
+
transition: none;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.ui-spotlight--ring .ui-spotlight__hole {
|
|
55
|
+
outline: 2px solid var(--accent);
|
|
56
|
+
outline-offset: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* The callout. Place it near the target (the host positions it); it re-enables
|
|
60
|
+
pointer events so its controls work inside the non-interactive overlay. */
|
|
61
|
+
.ui-tour-note {
|
|
62
|
+
background: var(--panel);
|
|
63
|
+
border: 1px solid var(--line);
|
|
64
|
+
border-radius: var(--radius-md);
|
|
65
|
+
box-shadow: var(--shadow-raised);
|
|
66
|
+
color: var(--text);
|
|
67
|
+
display: grid;
|
|
68
|
+
gap: var(--space-sm);
|
|
69
|
+
max-inline-size: 22rem;
|
|
70
|
+
padding: var(--space-md);
|
|
71
|
+
pointer-events: auto;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ui-tour-note__step {
|
|
75
|
+
color: var(--text-dim);
|
|
76
|
+
font-family: var(--mono);
|
|
77
|
+
font-size: var(--text-2xs);
|
|
78
|
+
letter-spacing: 0;
|
|
79
|
+
text-transform: uppercase;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.ui-tour-note__title {
|
|
83
|
+
color: var(--text);
|
|
84
|
+
font-size: var(--text-lg);
|
|
85
|
+
font-weight: 600;
|
|
86
|
+
margin: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.ui-tour-note__body {
|
|
90
|
+
color: var(--text-soft);
|
|
91
|
+
margin: 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.ui-tour-note__actions {
|
|
95
|
+
display: flex;
|
|
96
|
+
gap: var(--space-sm);
|
|
97
|
+
justify-content: flex-end;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@media (forced-colors: active) {
|
|
101
|
+
.ui-spotlight__hole {
|
|
102
|
+
outline: 2px solid CanvasText;
|
|
103
|
+
}
|
|
104
|
+
}
|
package/css/state.css
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
state — opt-in lifecycle / system-state vocabulary.
|
|
3
|
+
|
|
4
|
+
Serious apps spend a lot of time in states like saving, saved, queued,
|
|
5
|
+
offline, stale, conflicted, locked, and reviewed — usually improvised per
|
|
6
|
+
product, so even good apps feel inconsistent. This is the canonical set:
|
|
7
|
+
a labelled state object with a rationed tone, plus a page/document sync bar.
|
|
8
|
+
|
|
9
|
+
The state is carried by a tone dot AND an author-written label, never colour
|
|
10
|
+
alone (WCAG 1.4.1) — the label is the canonical wording (see docs/state.md).
|
|
11
|
+
Bronto ships the visual states; the host owns the state machine, retry
|
|
12
|
+
policy, persistence, and announcements. Persistent state gets persistent UI;
|
|
13
|
+
toasts are secondary. Not imported by core.css.
|
|
14
|
+
========================================================================== */
|
|
15
|
+
|
|
16
|
+
.ui-state {
|
|
17
|
+
--state-tone: var(--text-dim);
|
|
18
|
+
|
|
19
|
+
align-items: center;
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
font-size: var(--text-sm);
|
|
22
|
+
gap: 0.4rem;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Leading state indicator — a tone dot. `--busy` makes it pulse. */
|
|
26
|
+
.ui-state::before {
|
|
27
|
+
background: var(--state-tone);
|
|
28
|
+
border-radius: 50%;
|
|
29
|
+
block-size: 0.5rem;
|
|
30
|
+
content: '';
|
|
31
|
+
flex: none;
|
|
32
|
+
inline-size: 0.5rem;
|
|
33
|
+
print-color-adjust: exact;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.ui-state__label {
|
|
37
|
+
color: var(--text);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.ui-state__detail {
|
|
41
|
+
color: var(--text-dim);
|
|
42
|
+
font-size: var(--text-2xs);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* In-progress states (saving / syncing / retrying): a pulsing indicator. */
|
|
46
|
+
.ui-state--busy::before {
|
|
47
|
+
animation: uiStatePulse 1.1s ease-in-out infinite;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@keyframes uiStatePulse {
|
|
51
|
+
50% {
|
|
52
|
+
opacity: 0.3;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@media (prefers-reduced-motion: reduce) {
|
|
57
|
+
.ui-state--busy::before {
|
|
58
|
+
animation: none;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Canonical states — each bakes in the right rationed tone. */
|
|
63
|
+
.ui-state--saving {
|
|
64
|
+
--state-tone: var(--accent);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.ui-state--saved {
|
|
68
|
+
--state-tone: var(--success);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.ui-state--queued {
|
|
72
|
+
--state-tone: var(--text-dim);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.ui-state--offline {
|
|
76
|
+
--state-tone: var(--warning);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.ui-state--stale {
|
|
80
|
+
--state-tone: var(--warning);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.ui-state--conflict {
|
|
84
|
+
--state-tone: var(--danger);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ui-state--error {
|
|
88
|
+
--state-tone: var(--danger);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.ui-state--locked {
|
|
92
|
+
--state-tone: var(--text-dim);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.ui-state--reviewed {
|
|
96
|
+
--state-tone: var(--success);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ui-state--needs-review {
|
|
100
|
+
--state-tone: var(--warning);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Sync bar — a page/document-level save/sync status strip: a state on one side,
|
|
104
|
+
optional actions on the other. */
|
|
105
|
+
.ui-syncbar {
|
|
106
|
+
align-items: center;
|
|
107
|
+
border-block-end: 1px solid var(--line);
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-wrap: wrap;
|
|
110
|
+
gap: var(--space-sm) var(--space-md);
|
|
111
|
+
justify-content: space-between;
|
|
112
|
+
padding-block: var(--space-xs);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Forced colours: the tone dot collapses to a system colour, so the
|
|
116
|
+
author-written label remains the state channel (it already must be). */
|
|
117
|
+
@media (forced-colors: active) {
|
|
118
|
+
.ui-state::before {
|
|
119
|
+
background: CanvasText;
|
|
120
|
+
}
|
|
121
|
+
}
|
package/css/tokens.css
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/* ==========================================================================
|
|
2
|
-
@ponchia/ui — design tokens
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
@ponchia/ui — design tokens ⟨generated⟩
|
|
3
|
+
Single source of truth: tokens/index.js (`cssVars`). Edit token VALUES
|
|
4
|
+
there, then run `npm run tokens:css:build`. The four :root blocks below are
|
|
5
|
+
emitted from cssVars — the dark palette is authored ONCE (not the former two
|
|
6
|
+
CSS blocks + the JS mirror). check-tokens.mjs gates this file against cssVars.
|
|
7
|
+
The Doto @font-face lives in fonts.css; override --display / --dot-font to
|
|
8
|
+
self-host. CSS-only presets (density / contrast / OLED) are hand-authored
|
|
9
|
+
below the marker — they are intentionally not part of the JS token model.
|
|
9
10
|
========================================================================== */
|
|
10
11
|
|
|
11
12
|
:root {
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
--radius-sm: 1px;
|
|
17
18
|
--radius-pill: 999px;
|
|
18
19
|
|
|
19
|
-
/* Spacing scale */
|
|
20
|
+
/* Spacing scale. */
|
|
20
21
|
--space-2xs: 0.25rem;
|
|
21
22
|
--space-xs: 0.5rem;
|
|
22
23
|
--space-sm: 0.75rem;
|
|
@@ -27,8 +28,7 @@
|
|
|
27
28
|
|
|
28
29
|
/* Type — Doto is the dot-matrix display face; body stays mono-grotesque. */
|
|
29
30
|
--mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'SF Mono', ui-monospace, monospace;
|
|
30
|
-
--sans:
|
|
31
|
-
'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
|
31
|
+
--sans: 'Inter', 'SF Pro Text', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
|
32
32
|
--dot-font: 'Doto', var(--mono);
|
|
33
33
|
--display: var(--dot-font);
|
|
34
34
|
--text-2xs: 0.68rem;
|
|
@@ -48,14 +48,11 @@
|
|
|
48
48
|
--duration-base: 200ms;
|
|
49
49
|
--duration-slow: 360ms;
|
|
50
50
|
|
|
51
|
-
/* Dot-matrix motif sizing */
|
|
51
|
+
/* Dot-matrix motif sizing. */
|
|
52
52
|
--dot-size: 2px;
|
|
53
53
|
--dot-gap: 14px;
|
|
54
54
|
|
|
55
|
-
/* Stacking-context scale
|
|
56
|
-
consumers can reason about (and override) layering coherently.
|
|
57
|
-
Values match the prior literals — purely a refactor, no visual
|
|
58
|
-
change. */
|
|
55
|
+
/* Stacking-context scale (values match the prior literals — pure refactor). */
|
|
59
56
|
--z-base: 0;
|
|
60
57
|
--z-raised: 10;
|
|
61
58
|
--z-sticky: 20;
|
|
@@ -63,11 +60,7 @@
|
|
|
63
60
|
--z-popover: 50;
|
|
64
61
|
--z-toast: 60;
|
|
65
62
|
|
|
66
|
-
/* Accent ramp — a stepped family for charts / data-viz /
|
|
67
|
-
surfaces (the use case tokens/index.js advertises). Derived from the
|
|
68
|
-
single --accent knob via OKLCH color-mix against a per-theme white/black
|
|
69
|
-
endpoint. Using an explicit neutral endpoint avoids low-chroma background
|
|
70
|
-
hue differences between browser engines. */
|
|
63
|
+
/* Accent ramp — a stepped family for charts / data-viz, derived from the single --accent knob via OKLCH color-mix against a per-theme white/black endpoint. */
|
|
71
64
|
--accent-1: color-mix(in oklch, var(--accent) 8%, var(--accent-ramp-end));
|
|
72
65
|
--accent-2: color-mix(in oklch, var(--accent) 16%, var(--accent-ramp-end));
|
|
73
66
|
--accent-3: color-mix(in oklch, var(--accent) 32%, var(--accent-ramp-end));
|
|
@@ -83,10 +76,7 @@
|
|
|
83
76
|
--surface-5: var(--line);
|
|
84
77
|
--surface-6: var(--line-strong);
|
|
85
78
|
|
|
86
|
-
/* Semantic tier — stable, prefixed aliases over the
|
|
87
|
-
legacy) primitive names. New consumer code should target these:
|
|
88
|
-
re-skinning one role no longer means chasing component internals.
|
|
89
|
-
The short names below stay as permanent back-compat aliases. */
|
|
79
|
+
/* Semantic --bronto-color-* tier — stable, prefixed aliases over the primitives. */
|
|
90
80
|
--bronto-color-bg: var(--bg);
|
|
91
81
|
--bronto-color-surface: var(--panel);
|
|
92
82
|
--bronto-color-surface-raised: var(--panel-strong);
|
|
@@ -102,7 +92,7 @@
|
|
|
102
92
|
--bronto-color-danger: var(--danger);
|
|
103
93
|
--bronto-color-info: var(--info);
|
|
104
94
|
|
|
105
|
-
/* Aliases kept for back-compat with existing semantic classes */
|
|
95
|
+
/* Aliases kept for back-compat with existing semantic classes. */
|
|
106
96
|
--surface: var(--panel);
|
|
107
97
|
--surface-raised: var(--panel-strong);
|
|
108
98
|
--surface-muted: var(--panel-soft);
|
|
@@ -146,24 +136,15 @@
|
|
|
146
136
|
--field-dot: rgb(10, 10, 10, 0.16);
|
|
147
137
|
--field-dot-hot: rgb(10, 10, 10, 0.4);
|
|
148
138
|
--field-dot-accent: color-mix(in srgb, var(--accent) 78%, transparent);
|
|
149
|
-
|
|
150
|
-
/* Solid by default: this token drives every focus outline, so it must
|
|
151
|
-
clear the 3:1 non-text contrast minimum. Override per theme/subtree
|
|
152
|
-
to tune the ring without touching --accent. */
|
|
153
139
|
--focus-ring: var(--accent);
|
|
154
140
|
--shadow: none;
|
|
155
141
|
--shadow-raised: 0 0 0 1px var(--line-strong);
|
|
156
142
|
}
|
|
157
143
|
|
|
158
144
|
/* --------------------------------------------------------------------------
|
|
159
|
-
Dark —
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
`prefers-color-scheme: dark` (system default, unless overridden to light)
|
|
163
|
-
and once under `[data-theme='dark']` (explicit opt-in). Vanilla CSS can't
|
|
164
|
-
share one declaration block between a media query and a top-level selector
|
|
165
|
-
without a build step or nesting, neither of which this zero-dep package
|
|
166
|
-
has. Keep the two blocks in sync when editing dark tokens.
|
|
145
|
+
Dark — emitted from cssVars.dark under BOTH the system preference and the
|
|
146
|
+
explicit [data-theme='dark'] opt-in. Authored once in tokens/index.js, so
|
|
147
|
+
the two blocks below can no longer drift from each other.
|
|
167
148
|
-------------------------------------------------------------------------- */
|
|
168
149
|
@media (prefers-color-scheme: dark) {
|
|
169
150
|
:root:not([data-theme='light']) {
|
|
@@ -241,6 +222,13 @@
|
|
|
241
222
|
--shadow-raised: 0 0 0 1px var(--line-strong);
|
|
242
223
|
}
|
|
243
224
|
|
|
225
|
+
/* ==========================================================================
|
|
226
|
+
HAND-AUTHORED BELOW — CSS-only presets (density / contrast / OLED) and the
|
|
227
|
+
theming-contract notes. These are intentionally NOT in the JS token model
|
|
228
|
+
(tokens/index.js), so they are preserved verbatim when the palette above is
|
|
229
|
+
regenerated by scripts/gen-tokens-css.mjs.
|
|
230
|
+
========================================================================== */
|
|
231
|
+
|
|
244
232
|
/* --------------------------------------------------------------------------
|
|
245
233
|
Theming contract — the public override surface.
|
|
246
234
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
workbench — opt-in inspector / property / selection-bar primitives.
|
|
3
|
+
|
|
4
|
+
Real tools need inspectors, property rows, and a bar of actions on the
|
|
5
|
+
current selection. Generic kits stop at cards/tables/forms, so every app
|
|
6
|
+
builds its own half-consistent workbench. This is the low-risk CSS core:
|
|
7
|
+
layout and affordances only. Resizable split panes (a focusable ARIA
|
|
8
|
+
window-splitter behavior) and drag handles are deliberately deferred until a
|
|
9
|
+
consumer needs them. Not imported by core.css.
|
|
10
|
+
========================================================================== */
|
|
11
|
+
|
|
12
|
+
/* --- Inspector — a panel of details for the selected object. --- */
|
|
13
|
+
.ui-inspector {
|
|
14
|
+
background: var(--panel);
|
|
15
|
+
border: 1px solid var(--line);
|
|
16
|
+
border-radius: var(--radius-md);
|
|
17
|
+
display: grid;
|
|
18
|
+
gap: var(--space-sm);
|
|
19
|
+
padding: var(--space-md);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ui-inspector__header {
|
|
23
|
+
align-items: baseline;
|
|
24
|
+
border-block-end: 1px solid var(--line);
|
|
25
|
+
display: flex;
|
|
26
|
+
gap: var(--space-sm);
|
|
27
|
+
justify-content: space-between;
|
|
28
|
+
padding-block-end: var(--space-xs);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ui-inspector__body {
|
|
32
|
+
display: grid;
|
|
33
|
+
gap: var(--space-2xs);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* --- Property row — a label/value pair, denser than ui-key-value and tuned
|
|
37
|
+
for an inspector (the value can hold an input or a static read-out). --- */
|
|
38
|
+
.ui-property {
|
|
39
|
+
align-items: baseline;
|
|
40
|
+
display: grid;
|
|
41
|
+
gap: var(--space-sm);
|
|
42
|
+
grid-template-columns: minmax(6rem, 38%) 1fr;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.ui-property__label {
|
|
46
|
+
color: var(--text-dim);
|
|
47
|
+
font-family: var(--mono);
|
|
48
|
+
font-size: var(--text-2xs);
|
|
49
|
+
letter-spacing: var(--tracking-wide);
|
|
50
|
+
text-transform: uppercase;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.ui-property__value {
|
|
54
|
+
color: var(--text);
|
|
55
|
+
font-size: var(--text-sm);
|
|
56
|
+
min-inline-size: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* --- Selection bar — actions on the current selection ("3 selected"). --- */
|
|
60
|
+
.ui-selectionbar {
|
|
61
|
+
align-items: center;
|
|
62
|
+
background: var(--panel-strong);
|
|
63
|
+
border: 1px solid var(--line-strong);
|
|
64
|
+
border-radius: var(--radius-md);
|
|
65
|
+
box-shadow: var(--shadow-raised);
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-wrap: wrap;
|
|
68
|
+
gap: var(--space-sm) var(--space-md);
|
|
69
|
+
justify-content: space-between;
|
|
70
|
+
padding: 0.5rem 0.85rem;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.ui-selectionbar__count {
|
|
74
|
+
color: var(--text);
|
|
75
|
+
font-family: var(--mono);
|
|
76
|
+
font-size: var(--text-sm);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.ui-selectionbar__actions {
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-wrap: wrap;
|
|
82
|
+
gap: var(--space-xs);
|
|
83
|
+
}
|