@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.
Files changed (123) hide show
  1. package/CHANGELOG.md +352 -12
  2. package/MIGRATIONS.json +92 -0
  3. package/README.md +27 -17
  4. package/annotations/index.d.ts +280 -0
  5. package/annotations/index.js +522 -0
  6. package/behaviors/carousel.js +197 -0
  7. package/behaviors/combobox.js +195 -0
  8. package/behaviors/command.js +187 -0
  9. package/behaviors/connectors.js +96 -0
  10. package/behaviors/crosshair.js +58 -0
  11. package/behaviors/dialog.js +73 -0
  12. package/behaviors/disclosure.js +25 -0
  13. package/behaviors/dismissible.js +24 -0
  14. package/behaviors/forms.js +158 -0
  15. package/behaviors/glyph.js +109 -0
  16. package/behaviors/index.d.ts +82 -1
  17. package/behaviors/index.js +18 -1336
  18. package/behaviors/internal.js +50 -0
  19. package/behaviors/legend.js +46 -0
  20. package/behaviors/menu.js +46 -0
  21. package/behaviors/popover.js +108 -0
  22. package/behaviors/spotlight.js +53 -0
  23. package/behaviors/table.js +109 -0
  24. package/behaviors/tabs.js +103 -0
  25. package/behaviors/theme.js +82 -0
  26. package/behaviors/toast.js +152 -0
  27. package/classes/index.d.ts +318 -0
  28. package/classes/index.js +352 -0
  29. package/classes/vscode.css-custom-data.json +18 -14
  30. package/connectors/index.d.ts +71 -0
  31. package/connectors/index.js +179 -0
  32. package/css/analytical.css +21 -0
  33. package/css/annotations.css +292 -0
  34. package/css/command.css +97 -0
  35. package/css/connectors.css +93 -0
  36. package/css/crosshair.css +100 -0
  37. package/css/disclosure.css +29 -0
  38. package/css/dots.css +2 -0
  39. package/css/feedback.css +104 -0
  40. package/css/fonts.css +11 -7
  41. package/css/generated.css +117 -0
  42. package/css/legend.css +268 -0
  43. package/css/marks.css +144 -0
  44. package/css/motion.css +88 -0
  45. package/css/overlay.css +52 -1
  46. package/css/primitives.css +18 -0
  47. package/css/report.css +363 -0
  48. package/css/selection.css +46 -0
  49. package/css/sources.css +179 -0
  50. package/css/spotlight.css +104 -0
  51. package/css/state.css +121 -0
  52. package/css/tokens.css +78 -60
  53. package/css/workbench.css +83 -0
  54. package/dist/bronto.css +1 -1
  55. package/dist/css/analytical.css +1 -0
  56. package/dist/css/annotations.css +1 -0
  57. package/dist/css/command.css +1 -0
  58. package/dist/css/connectors.css +1 -0
  59. package/dist/css/crosshair.css +1 -0
  60. package/dist/css/disclosure.css +1 -1
  61. package/dist/css/dots.css +1 -1
  62. package/dist/css/feedback.css +1 -1
  63. package/dist/css/fonts.css +1 -1
  64. package/dist/css/generated.css +1 -0
  65. package/dist/css/legend.css +1 -0
  66. package/dist/css/marks.css +1 -0
  67. package/dist/css/motion.css +1 -1
  68. package/dist/css/overlay.css +1 -1
  69. package/dist/css/primitives.css +1 -1
  70. package/dist/css/report.css +1 -0
  71. package/dist/css/selection.css +1 -0
  72. package/dist/css/sources.css +1 -0
  73. package/dist/css/spotlight.css +1 -0
  74. package/dist/css/state.css +1 -0
  75. package/dist/css/tokens.css +1 -1
  76. package/dist/css/workbench.css +1 -0
  77. package/docs/adr/0001-color-system.md +26 -27
  78. package/docs/adr/0002-scope-and-2026-baseline.md +104 -0
  79. package/docs/adr/0003-theme-model.md +97 -0
  80. package/docs/annotations.md +345 -0
  81. package/docs/architecture.md +202 -0
  82. package/docs/command.md +95 -0
  83. package/docs/connectors.md +91 -0
  84. package/docs/contrast.md +42 -42
  85. package/docs/crosshair.md +63 -0
  86. package/docs/generated.md +91 -0
  87. package/docs/legends.md +168 -0
  88. package/docs/marks.md +86 -0
  89. package/docs/reference.md +418 -15
  90. package/docs/reporting.md +305 -0
  91. package/docs/selection.md +40 -0
  92. package/docs/sources.md +110 -0
  93. package/docs/spotlight.md +78 -0
  94. package/docs/stability.md +52 -0
  95. package/docs/state.md +85 -0
  96. package/docs/theming.md +18 -6
  97. package/docs/usage.md +43 -3
  98. package/docs/workbench.md +72 -0
  99. package/fonts/doto-400.woff2 +0 -0
  100. package/fonts/doto-500.woff2 +0 -0
  101. package/fonts/doto-600.woff2 +0 -0
  102. package/fonts/doto-700.woff2 +0 -0
  103. package/fonts/doto-800.woff2 +0 -0
  104. package/fonts/doto-900.woff2 +0 -0
  105. package/llms.txt +288 -8
  106. package/package.json +95 -5
  107. package/qwik/index.d.ts +60 -0
  108. package/qwik/index.js +149 -0
  109. package/react/index.d.ts +40 -14
  110. package/react/index.js +32 -5
  111. package/solid/index.d.ts +40 -14
  112. package/solid/index.js +31 -3
  113. package/tokens/index.d.ts +3 -3
  114. package/tokens/index.js +25 -19
  115. package/tokens/index.json +32 -28
  116. package/tokens/resolved.json +34 -32
  117. package/tokens/tokens.dtcg.json +22 -14
  118. package/fonts/doto-400.ttf +0 -0
  119. package/fonts/doto-500.ttf +0 -0
  120. package/fonts/doto-600.ttf +0 -0
  121. package/fonts/doto-700.ttf +0 -0
  122. package/fonts/doto-800.ttf +0 -0
  123. package/fonts/doto-900.ttf +0 -0
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
- Nothing-inspired: monochrome surfaces, single red accent, dot-matrix type.
4
- Dual light/dark. Variable names are stable so semantic classes inherit.
5
- The Doto @font-face declarations live in fonts.css (bundled by
6
- core.css/index.css) so font hosting is decoupled from these tokens
7
- a consumer can self-host Doto and still use the token layer by
8
- overriding --display / --dot-font.
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. Replaces scattered magic z-indexes so
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,14 +60,11 @@
63
60
  --z-popover: 50;
64
61
  --z-toast: 60;
65
62
 
66
- /* Accent ramp — a stepped family for charts / data-viz / multi-state
67
- surfaces (the use case tokens/index.js advertises). Derived from the
68
- single --accent knob via color-mix against the theme bg, so it
69
- re-brands and theme-adapts automatically; no per-theme duplication. */
70
- --accent-1: color-mix(in oklch, var(--accent) 8%, var(--bg));
71
- --accent-2: color-mix(in oklch, var(--accent) 16%, var(--bg));
72
- --accent-3: color-mix(in oklch, var(--accent) 32%, var(--bg));
73
- --accent-4: color-mix(in oklch, var(--accent) 60%, var(--bg));
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. */
64
+ --accent-1: color-mix(in oklch, var(--accent) 8%, var(--accent-ramp-end));
65
+ --accent-2: color-mix(in oklch, var(--accent) 16%, var(--accent-ramp-end));
66
+ --accent-3: color-mix(in oklch, var(--accent) 32%, var(--accent-ramp-end));
67
+ --accent-4: color-mix(in oklch, var(--accent) 60%, var(--accent-ramp-end));
74
68
  --accent-5: var(--accent);
75
69
  --accent-6: var(--accent-strong);
76
70
 
@@ -82,10 +76,7 @@
82
76
  --surface-5: var(--line);
83
77
  --surface-6: var(--line-strong);
84
78
 
85
- /* Semantic tier — stable, prefixed aliases over the (shorter,
86
- legacy) primitive names. New consumer code should target these:
87
- re-skinning one role no longer means chasing component internals.
88
- The short names below stay as permanent back-compat aliases. */
79
+ /* Semantic --bronto-color-* tier — stable, prefixed aliases over the primitives. */
89
80
  --bronto-color-bg: var(--bg);
90
81
  --bronto-color-surface: var(--panel);
91
82
  --bronto-color-surface-raised: var(--panel-strong);
@@ -101,7 +92,7 @@
101
92
  --bronto-color-danger: var(--danger);
102
93
  --bronto-color-info: var(--info);
103
94
 
104
- /* Aliases kept for back-compat with existing semantic classes */
95
+ /* Aliases kept for back-compat with existing semantic classes. */
105
96
  --surface: var(--panel);
106
97
  --surface-raised: var(--panel-strong);
107
98
  --surface-muted: var(--panel-soft);
@@ -128,6 +119,7 @@
128
119
  --text-soft: #353533;
129
120
  --text-dim: #686863;
130
121
  --accent: #d71921;
122
+ --accent-ramp-end: #ffffff;
131
123
  --accent-strong: color-mix(in srgb, var(--accent) 83%, #000);
132
124
  --accent-text: var(--accent-strong);
133
125
  --accent-soft: color-mix(in srgb, var(--accent) 10%, transparent);
@@ -144,41 +136,33 @@
144
136
  --field-dot: rgb(10, 10, 10, 0.16);
145
137
  --field-dot-hot: rgb(10, 10, 10, 0.4);
146
138
  --field-dot-accent: color-mix(in srgb, var(--accent) 78%, transparent);
147
-
148
- /* Solid by default: this token drives every focus outline, so it must
149
- clear the 3:1 non-text contrast minimum. Override per theme/subtree
150
- to tune the ring without touching --accent. */
151
139
  --focus-ring: var(--accent);
152
140
  --shadow: none;
153
141
  --shadow-raised: 0 0 0 1px var(--line-strong);
154
142
  }
155
143
 
156
144
  /* --------------------------------------------------------------------------
157
- Dark — true black. The Nothing default.
158
-
159
- The palette below is intentionally written twice: once under
160
- `prefers-color-scheme: dark` (system default, unless overridden to light)
161
- and once under `[data-theme='dark']` (explicit opt-in). Vanilla CSS can't
162
- share one declaration block between a media query and a top-level selector
163
- without a build step or nesting, neither of which this zero-dep package
164
- 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.
165
148
  -------------------------------------------------------------------------- */
166
149
  @media (prefers-color-scheme: dark) {
167
150
  :root:not([data-theme='light']) {
168
151
  color-scheme: dark;
169
152
 
170
- --bg: #000000;
171
- --bg-elevated: #0a0a0a;
153
+ --bg: #121212;
154
+ --bg-elevated: #181818;
172
155
  --bg-accent: color-mix(in srgb, var(--accent) 8%, transparent);
173
- --panel: #0c0c0c;
174
- --panel-strong: #141414;
175
- --panel-soft: #1a1a1a;
176
- --line: #2a2a2a;
177
- --line-strong: #444444;
178
- --text: #f2f2f2;
179
- --text-soft: #c4c4c4;
180
- --text-dim: #858585;
156
+ --panel: #1c1c1c;
157
+ --panel-strong: #222222;
158
+ --panel-soft: #242424;
159
+ --line: #383838;
160
+ --line-strong: #555555;
161
+ --text: #e6e6e6;
162
+ --text-soft: #c8c8c8;
163
+ --text-dim: #a0a0a0;
181
164
  --accent: #ff3b41;
165
+ --accent-ramp-end: #000000;
182
166
  --accent-strong: color-mix(in srgb, var(--accent) 84%, #fff);
183
167
  --accent-text: var(--accent-strong);
184
168
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
@@ -204,18 +188,19 @@
204
188
  :root[data-theme='dark'] {
205
189
  color-scheme: dark;
206
190
 
207
- --bg: #000000;
208
- --bg-elevated: #0a0a0a;
191
+ --bg: #121212;
192
+ --bg-elevated: #181818;
209
193
  --bg-accent: color-mix(in srgb, var(--accent) 8%, transparent);
210
- --panel: #0c0c0c;
211
- --panel-strong: #141414;
212
- --panel-soft: #1a1a1a;
213
- --line: #2a2a2a;
214
- --line-strong: #444444;
215
- --text: #f2f2f2;
216
- --text-soft: #c4c4c4;
217
- --text-dim: #858585;
194
+ --panel: #1c1c1c;
195
+ --panel-strong: #222222;
196
+ --panel-soft: #242424;
197
+ --line: #383838;
198
+ --line-strong: #555555;
199
+ --text: #e6e6e6;
200
+ --text-soft: #c8c8c8;
201
+ --text-dim: #a0a0a0;
218
202
  --accent: #ff3b41;
203
+ --accent-ramp-end: #000000;
219
204
  --accent-strong: color-mix(in srgb, var(--accent) 84%, #fff);
220
205
  --accent-text: var(--accent-strong);
221
206
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
@@ -237,6 +222,13 @@
237
222
  --shadow-raised: 0 0 0 1px var(--line-strong);
238
223
  }
239
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
+
240
232
  /* --------------------------------------------------------------------------
241
233
  Theming contract — the public override surface.
242
234
 
@@ -293,3 +285,29 @@
293
285
  --shadow-raised: 0 0 0 1px var(--text);
294
286
  }
295
287
  }
288
+
289
+ /* OLED / true-black surface — opt-in brand variant for the dark theme.
290
+ The default dark base is a deliberately elevated near-black (#121212) for
291
+ readability: pure black + bright text causes halation, and #000→#0c0c0c
292
+ surface steps are imperceptible (so cards melt into the page). This preset
293
+ restores pure black for OLED power-saving and the original "Nothing" look.
294
+ CSS-only (not in the JS token model, like [data-density] / [data-contrast]),
295
+ and scoped to the dark theme so it never blacks out the light theme. Text
296
+ stays the re-tuned --text, which clears WCAG AA on #000 too. */
297
+ :root[data-theme='dark'][data-surface='oled'] {
298
+ --bg: #000000;
299
+ --bg-elevated: #0a0a0a;
300
+ --panel: #101010;
301
+ --panel-strong: #161616;
302
+ --panel-soft: #1a1a1a;
303
+ }
304
+
305
+ @media (prefers-color-scheme: dark) {
306
+ :root:not([data-theme='light'])[data-surface='oled'] {
307
+ --bg: #000000;
308
+ --bg-elevated: #0a0a0a;
309
+ --panel: #101010;
310
+ --panel-strong: #161616;
311
+ --panel-soft: #1a1a1a;
312
+ }
313
+ }
@@ -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
+ }