@adia-ai/web-components 0.6.8 → 0.6.9

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog — @adia-ai/web-components
2
2
 
3
+ ## [0.6.9] — 2026-05-21
4
+
5
+ ### Fixed
6
+ - **9 component CSS files — `@scope` blocks no longer use bare-combinator descendants (F-002, P1).** Pre-fix: 92 selector clauses across `action-list.css`, `card.css`, `chart.css`, `chat-thread.css`, `code.css`, `command.css`, `grid.css`, `pane.css`, `stack.css` used the `@scope { > X { } }` shape (bare `>` combinator with no left-hand selector inside `@scope`). Chromium/Firefox tolerate this; LightningCSS rejects it as "Invalid empty selector" (matches the CSS Nesting + `@scope` spec strictly). Symptom: consumers on Vite 7 (default `cssMinify: 'lightningcss'`) saw build-time failures at `card.css:152`; Vite 6 + earlier Vite 7 (esbuild minify) silently swallowed the same source. Fix: codemod-driven rewrite of all 92 clauses from `> X` to `& > X` (explicit `&` reference matches the modern CSS Nesting idiom; semantically identical; LightningCSS-clean). All 120 CSS files now pass LightningCSS minify against Vite 8 default targets (Chromium 125+, Safari 18+, Firefox 129+). Codemod source: `scripts/build/codemod-scope-bare-descendants.mjs` (committed for future audits; idempotent + `--verify` mode). Paired CI gate `check:scope-bare-descendants` blocks regression at PR time; companion `check:lightningcss-build` smoke-minifies every CSS file end-to-end against Vite 8 targets. Closes claims-ui FEEDBACK-02.
7
+
8
+ ### Documentation
9
+ - **`USAGE.md` — new "Looking up a component's API" subsection.** Three discovery paths now documented in one place: `npx adia-ai-doc <component>` CLI (machine-readable + offline-safe), `<component>.examples.html` per-component live demo + Properties table, and `<component>.yaml` source-of-truth schema. Closes claims-ui FEEDBACK-09 (per-component opt-out attributes are documented; this subsection makes the doc-path discoverable from the top-level USAGE entrypoint).
10
+
3
11
  ## [0.6.8] — 2026-05-20
4
12
 
5
13
  ### Fixed
package/USAGE.md CHANGED
@@ -59,6 +59,35 @@ import { signal, computed, effect, html, UIElement, UIFormElement } from '@adia-
59
59
  import '@adia-ai/web-components/traits';
60
60
  ```
61
61
 
62
+ ### Looking up a component's API
63
+
64
+ Three reliable surfaces, in order of immediacy:
65
+
66
+ ```bash
67
+ # 1. CLI (since v0.6.7) — prints yaml summary + live demo URL + first example
68
+ npx adia-ui-doc table-toolbar # full prop / slot / event surface
69
+ npx adia-ui-doc # bare invocation lists all 96 components
70
+ ```
71
+
72
+ ```bash
73
+ # 2. Per-component examples (ship in npm tarball since v0.6.7)
74
+ cat node_modules/@adia-ai/web-components/components/table-toolbar/table-toolbar.examples.md
75
+
76
+ # Or the richer .examples.html for Properties tables + multi-section walks
77
+ open node_modules/@adia-ai/web-components/components/table-toolbar/table-toolbar.examples.html
78
+ ```
79
+
80
+ ```bash
81
+ # 3. The component's yaml (authoritative — all props, defaults, descriptions)
82
+ cat node_modules/@adia-ai/web-components/components/table-toolbar/table-toolbar.yaml
83
+ ```
84
+
85
+ The yaml is the source of truth for every property, slot, event, and token.
86
+ The CLI reads it. The `.d.ts` files are generated from it. When this USAGE
87
+ guide and the yaml disagree, the yaml wins — file a doc-bug FEEDBACK.
88
+
89
+ For the live demo of every component: <https://ui-kit.exe.xyz/site/components/>.
90
+
62
91
  ---
63
92
 
64
93
  ## The mental model
@@ -99,7 +99,7 @@ action-item-ui:hover [slot="icon"] {
99
99
  }
100
100
 
101
101
  /* Default slot (trailing content: kbd, badge, chevron) pushed to far right */
102
- > :not([slot="icon"]):not([slot="text"]) {
102
+ & > :not([slot="icon"]):not([slot="text"]) {
103
103
  flex-shrink: 0;
104
104
  margin-inline-start: auto;
105
105
  color: var(--action-item-icon-fg);
@@ -149,7 +149,7 @@
149
149
  [padding] switches to padding mode with background.
150
150
  Grid layout: optional icon | heading+description | optional action */
151
151
 
152
- > header {
152
+ & > header {
153
153
  display: block;
154
154
  margin: var(--card-inset);
155
155
  }
@@ -157,24 +157,24 @@
157
157
  /* Activate grid layout only when a DIRECT slotted child is present.
158
158
  Constraining to `:has(> [slot])` prevents deeply nested slots (e.g. an
159
159
  [slot="icon"] inside an <avatar-ui>) from falsely activating the grid. */
160
- > header:has(> [slot]) {
160
+ & > header:has(> [slot]) {
161
161
  display: grid;
162
162
  gap: var(--card-header-gap);
163
163
  align-items: center;
164
164
  }
165
165
 
166
- > header[padding] {
166
+ & > header[padding] {
167
167
  margin: 0;
168
168
  padding: var(--card-inset);
169
169
  background: var(--card-bg-padded);
170
170
  }
171
171
 
172
- > header[divider] {
172
+ & > header[divider] {
173
173
  padding-bottom: var(--card-inset);
174
174
  border-bottom: 1px solid var(--card-divider);
175
175
  }
176
176
 
177
- > header[center] {
177
+ & > header[center] {
178
178
  text-align: center;
179
179
  justify-items: center;
180
180
  }
@@ -182,16 +182,16 @@
182
182
  /* Column templates — match gen-ui-kit pattern. Direct-child `:has(> …)` so
183
183
  nested [slot="icon"] inside a composite (e.g. <avatar-ui>) can't trigger
184
184
  the icon column by accident. */
185
- > header:has(> [slot="icon"]):has(> [slot="action"]) { grid-template-columns: max-content 1fr max-content; }
186
- > header:has(> [slot="icon"]):not(:has(> [slot="action"])) { grid-template-columns: max-content 1fr; }
187
- > header:not(:has(> [slot="icon"])):has(> [slot="action"]) { grid-template-columns: 1fr max-content; }
188
- > header:not(:has(> [slot="icon"])):not(:has(> [slot="action"])) { grid-template-columns: 1fr; }
185
+ & > header:has(> [slot="icon"]):has(> [slot="action"]) { grid-template-columns: max-content 1fr max-content; }
186
+ & > header:has(> [slot="icon"]):not(:has(> [slot="action"])) { grid-template-columns: max-content 1fr; }
187
+ & > header:not(:has(> [slot="icon"])):has(> [slot="action"]) { grid-template-columns: 1fr max-content; }
188
+ & > header:not(:has(> [slot="icon"])):not(:has(> [slot="action"])) { grid-template-columns: 1fr; }
189
189
 
190
190
  /* Unslotted children (zettel fragment injection, etc.) — each on its own row,
191
191
  spanning the full width, stacked ABOVE the heading/description/action grid.
192
192
  This lets compositions inject logos, banners, etc. into a header without
193
193
  having to know the slot vocabulary. */
194
- > header > *:not([slot]):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(p):not(small) {
194
+ & > header > *:not([slot]):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6):not(p):not(small) {
195
195
  grid-column: 1 / -1;
196
196
  justify-self: center;
197
197
  }
@@ -200,7 +200,7 @@
200
200
  Default: single row, center-aligned with heading/action.
201
201
  When a description row exists, spans both rows and anchors to the
202
202
  start so the icon visually aligns with the heading. */
203
- > header > [slot="icon"] {
203
+ & > header > [slot="icon"] {
204
204
  grid-column: 1;
205
205
  grid-row: 1;
206
206
  align-self: center;
@@ -209,39 +209,39 @@
209
209
  justify-content: center;
210
210
  }
211
211
 
212
- > header:has(> :is([slot="description"], p, small)) > [slot="icon"] {
212
+ & > header:has(> :is([slot="description"], p, small)) > [slot="icon"] {
213
213
  grid-row: 1 / span 2;
214
214
  align-self: start;
215
215
  }
216
216
 
217
217
  /* Heading — row 1 */
218
- > header > :is([slot="heading"], h1, h2, h3, h4, h5, h6),
219
- > header > [slot="heading"] :is(h1, h2, h3, h4, h5, h6) {
218
+ & > header > :is([slot="heading"], h1, h2, h3, h4, h5, h6),
219
+ & > header > [slot="heading"] :is(h1, h2, h3, h4, h5, h6) {
220
220
  grid-row: 1;
221
221
  line-height: 1.3;
222
222
  margin: 0;
223
223
  }
224
224
  /* Heading slot is a flex container — can hold title + inline badges/metadata */
225
- > header > [slot="heading"] {
225
+ & > header > [slot="heading"] {
226
226
  display: flex;
227
227
  align-items: center;
228
228
  gap: var(--card-header-gap);
229
229
  }
230
- > header:has(> [slot="icon"]) > :is([slot="heading"], h1, h2, h3, h4, h5, h6) { grid-column: 2; }
231
- > header:not(:has(> [slot="icon"])) > :is([slot="heading"], h1, h2, h3, h4, h5, h6) { grid-column: 1; }
230
+ & > header:has(> [slot="icon"]) > :is([slot="heading"], h1, h2, h3, h4, h5, h6) { grid-column: 2; }
231
+ & > header:not(:has(> [slot="icon"])) > :is([slot="heading"], h1, h2, h3, h4, h5, h6) { grid-column: 1; }
232
232
 
233
233
  /* Description — row 2 */
234
- > header > :is([slot="description"], p, small) {
234
+ & > header > :is([slot="description"], p, small) {
235
235
  grid-row: 2;
236
236
  grid-column: 1 / -1;
237
237
  line-height: 1.4;
238
238
  margin: 0;
239
239
  }
240
- > header:has(> [slot="icon"]) > :is([slot="description"], p, small) { grid-column: 2 / -1; }
240
+ & > header:has(> [slot="icon"]) > :is([slot="description"], p, small) { grid-column: 2 / -1; }
241
241
 
242
242
  /* Action — row 1, last column.
243
243
  Flex container so it can hold badge + button + anything inline. */
244
- > header [slot="action"] {
244
+ & > header [slot="action"] {
245
245
  justify-self: end;
246
246
  align-self: center;
247
247
  grid-row: 1;
@@ -256,17 +256,17 @@
256
256
  [padding] switches to padding with background.
257
257
  [bleed] removes all spacing for edge-to-edge content. */
258
258
 
259
- > section {
259
+ & > section {
260
260
  margin: var(--card-inset);
261
261
  }
262
262
 
263
- > section[padding] {
263
+ & > section[padding] {
264
264
  margin: 0;
265
265
  padding: var(--card-inset);
266
266
  background: var(--card-bg-padded);
267
267
  }
268
268
 
269
- > section[bleed] {
269
+ & > section[bleed] {
270
270
  margin: 0;
271
271
  padding: 0;
272
272
  }
@@ -276,7 +276,7 @@
276
276
  [divider] adds top border.
277
277
  [padding] switches to padded mode. */
278
278
 
279
- > footer {
279
+ & > footer {
280
280
  display: block;
281
281
  margin: var(--card-inset);
282
282
  }
@@ -284,8 +284,8 @@
284
284
  /* Activate flex layout when a direct slotted child or multiple children are
285
285
  present. `:has(> [slot])` so nested [slot="…"] inside composites can't
286
286
  trigger the flex row. */
287
- > footer:has(> [slot]),
288
- > footer:has(> :nth-child(2)) {
287
+ & > footer:has(> [slot]),
288
+ & > footer:has(> :nth-child(2)) {
289
289
  display: flex;
290
290
  flex-wrap: wrap;
291
291
  align-items: center;
@@ -293,30 +293,30 @@
293
293
  }
294
294
 
295
295
  /* col-ui in footer takes full width (common for stacked footer: button + divider + social) */
296
- > footer > col-ui { width: 100%; }
296
+ & > footer > col-ui { width: 100%; }
297
297
 
298
- > footer[justify="end"] {
298
+ & > footer[justify="end"] {
299
299
  justify-content: flex-end;
300
300
  }
301
301
 
302
- > footer[divider] {
302
+ & > footer[divider] {
303
303
  margin-top: var(--card-inset);
304
304
  padding-top: var(--card-inset);
305
305
  border-top: 1px solid var(--card-divider);
306
306
  }
307
307
 
308
- > footer[padding] {
308
+ & > footer[padding] {
309
309
  margin: 0;
310
310
  padding: var(--card-inset);
311
311
  background: var(--card-bg-padded);
312
312
  }
313
313
 
314
314
  /* Footer with direct-child description + action = space-between */
315
- > footer:has(> :is([slot="description"], p, small)):has(> [slot="action"]) {
315
+ & > footer:has(> :is([slot="description"], p, small)):has(> [slot="action"]) {
316
316
  justify-content: space-between;
317
317
  }
318
318
 
319
- > footer :is([slot="description"], p, small) {
319
+ & > footer :is([slot="description"], p, small) {
320
320
  font-size: var(--card-description-size);
321
321
  color: var(--card-description-fg);
322
322
  flex: 1;
@@ -327,7 +327,7 @@
327
327
  /* Footer heading — trend-stat line (symmetric with header's [slot="heading"]).
328
328
  Used for chart trend-footer patterns like "Trending up by 5.2% this month".
329
329
  Paired with [slot="description"] for a "Jan – Mar 2024" period caption. */
330
- > footer > [slot="heading"] {
330
+ & > footer > [slot="heading"] {
331
331
  font-size: var(--card-font-size);
332
332
  font-weight: var(--a-weight-medium);
333
333
  color: var(--card-heading-fg);
@@ -339,21 +339,21 @@
339
339
  /* Footer with heading + description = column stack, heading on top. The
340
340
  existing flex-row layout becomes a flex-column when a heading is present,
341
341
  so the trend line and period caption stack naturally. */
342
- > footer:has(> [slot="heading"]) {
342
+ & > footer:has(> [slot="heading"]) {
343
343
  flex-direction: column;
344
344
  align-items: flex-start;
345
345
  gap: var(--a-space-0-5);
346
346
  }
347
347
 
348
- > footer:has(> [slot="heading"])[justify="end"] {
348
+ & > footer:has(> [slot="heading"])[justify="end"] {
349
349
  align-items: flex-end;
350
350
  }
351
351
 
352
- > footer:has(> [slot="heading"])[justify="center"] {
352
+ & > footer:has(> [slot="heading"])[justify="center"] {
353
353
  align-items: center;
354
354
  }
355
355
 
356
- > footer [slot="action"] {
356
+ & > footer [slot="action"] {
357
357
  margin-inline-start: auto;
358
358
  display: flex;
359
359
  gap: var(--card-footer-gap);
@@ -361,14 +361,14 @@
361
361
 
362
362
  /* Multiple direct action-slotted children (A2UI pattern):
363
363
  only the first pushes the group right; subsequent ones flow with gap */
364
- > footer > [slot="action"] ~ [slot="action"] {
364
+ & > footer > [slot="action"] ~ [slot="action"] {
365
365
  margin-inline-start: 0;
366
366
  }
367
367
 
368
368
  /* Dual-cluster footer: leading action (e.g. Delete) on the inline-start
369
369
  edge, trailing action cluster on the inline-end. margin-inline-end:
370
370
  auto fills the gap between the two groups. */
371
- > footer > [slot="action-leading"] {
371
+ & > footer > [slot="action-leading"] {
372
372
  margin-inline-end: auto;
373
373
  display: flex;
374
374
  gap: var(--card-footer-gap);
@@ -376,15 +376,15 @@
376
376
 
377
377
  /* ═══════ Images ═══════ */
378
378
 
379
- > img,
380
- > [slot="media"] {
379
+ & > img,
380
+ & > [slot="media"] {
381
381
  display: block;
382
382
  width: 100%;
383
383
  object-fit: cover;
384
384
  }
385
385
 
386
- > img:first-child,
387
- > [slot="media"]:first-child {
386
+ & > img:first-child,
387
+ & > [slot="media"]:first-child {
388
388
  border-radius: var(--card-radius) var(--card-radius) 0 0;
389
389
  }
390
390
 
@@ -112,7 +112,7 @@
112
112
  /* Empty-state slot — author places <empty-state-ui slot="empty"> inside
113
113
  chart-ui. CSS toggles visibility on [data-has-data] (set by chart.js
114
114
  when .data is non-empty). No data ⇒ empty-state visible; data ⇒ hidden. */
115
- > [slot="empty"] { display: none; }
115
+ & > [slot="empty"] { display: none; }
116
116
  :scope:not([data-has-data]) > [slot="empty"] {
117
117
  display: flex;
118
118
  flex: 1 1 auto;
@@ -65,7 +65,7 @@
65
65
  }
66
66
 
67
67
  /* -- Header -- */
68
- > header {
68
+ & > header {
69
69
  display: flex;
70
70
  align-items: center;
71
71
  gap: var(--chat-gap);
@@ -73,7 +73,7 @@
73
73
  border-bottom: 1px solid var(--chat-border-color);
74
74
  }
75
75
 
76
- > header [slot="avatar"] {
76
+ & > header [slot="avatar"] {
77
77
  width: var(--chat-header-avatar-size);
78
78
  height: var(--chat-header-avatar-size);
79
79
  border-radius: var(--chat-header-avatar-radius);
@@ -87,19 +87,19 @@
87
87
  flex-shrink: 0;
88
88
  }
89
89
 
90
- > header [slot="name"] {
90
+ & > header [slot="name"] {
91
91
  font-weight: var(--chat-header-name-weight);
92
92
  font-size: var(--chat-header-name-size);
93
93
  }
94
94
 
95
- > header [slot="status"] {
95
+ & > header [slot="status"] {
96
96
  font-size: var(--chat-header-status-size);
97
97
  color: var(--chat-header-status-fg);
98
98
  margin-inline-start: auto;
99
99
  }
100
100
 
101
101
  /* -- Messages -- */
102
- > section {
102
+ & > section {
103
103
  flex: 1;
104
104
  overflow-y: auto;
105
105
  padding: var(--chat-messages-padding);
@@ -175,7 +175,7 @@
175
175
  }
176
176
 
177
177
  /* -- Footer -- */
178
- > footer {
178
+ & > footer {
179
179
  min-height: var(--chat-footer-min-height);
180
180
  display: flex;
181
181
  align-items: center;
@@ -90,7 +90,7 @@
90
90
  }
91
91
 
92
92
  /* Header — chrome band above the code block */
93
- > header {
93
+ & > header {
94
94
  display: flex;
95
95
  flex-direction: row;
96
96
  align-items: center;
@@ -103,14 +103,14 @@
103
103
  color: var(--code-header-fg);
104
104
  }
105
105
 
106
- > header [slot="label"] {
106
+ & > header [slot="label"] {
107
107
  font-weight: 500;
108
108
  text-transform: uppercase;
109
109
  letter-spacing: 0.05em;
110
110
  }
111
111
 
112
112
  /* Copy button — ghost style */
113
- > header [slot="copy"] {
113
+ & > header [slot="copy"] {
114
114
  all: unset;
115
115
  cursor: pointer;
116
116
  font-size: var(--code-header-font);
@@ -121,7 +121,7 @@
121
121
  background var(--code-duration) var(--code-easing),
122
122
  color var(--code-duration) var(--code-easing);
123
123
  }
124
- > header [slot="copy"]:hover {
124
+ & > header [slot="copy"]:hover {
125
125
  background: var(--code-copy-hover-bg);
126
126
  color: var(--code-copy-hover-fg);
127
127
  }
@@ -129,7 +129,7 @@
129
129
  /* Pre > Code — reset any ambient page styling (margins, borders,
130
130
  radii, backgrounds) so the <code-ui> chrome is the single source
131
131
  of visual framing. */
132
- > pre {
132
+ & > pre {
133
133
  margin: 0;
134
134
  border: none;
135
135
  border-radius: 0;
@@ -141,11 +141,11 @@
141
141
  line-height: 1.5;
142
142
  scrollbar-width: none;
143
143
  }
144
- > pre::-webkit-scrollbar {
144
+ & > pre::-webkit-scrollbar {
145
145
  display: none;
146
146
  }
147
147
 
148
- > pre > code {
148
+ & > pre > code {
149
149
  margin: 0;
150
150
  padding: 0;
151
151
  border: none;
@@ -162,10 +162,10 @@
162
162
  a `[data-line-state]` row whose bg picks up the state token. The
163
163
  CodeMirror path doesn't use these markers; line decorations there go
164
164
  through CM extensions instead. */
165
- > pre > code[data-line-state-mode] {
165
+ & > pre > code[data-line-state-mode] {
166
166
  display: block;
167
167
  }
168
- > pre > code[data-line-state-mode] > [data-line-state] {
168
+ & > pre > code[data-line-state-mode] > [data-line-state] {
169
169
  display: grid;
170
170
  grid-template-columns: 1fr;
171
171
  /* Bleed the row tint to the pre's padding edges so it reads as a
@@ -173,33 +173,33 @@
173
173
  margin-inline: calc(-1 * var(--code-px));
174
174
  padding-inline: var(--code-px);
175
175
  }
176
- > pre > code[data-line-numbers] > [data-line-state] {
176
+ & > pre > code[data-line-numbers] > [data-line-state] {
177
177
  grid-template-columns: auto 1fr;
178
178
  column-gap: var(--a-space-3);
179
179
  }
180
- > pre > code[data-line-state-mode] [data-line-num] {
180
+ & > pre > code[data-line-state-mode] [data-line-num] {
181
181
  color: var(--a-fg-subtle);
182
182
  text-align: end;
183
183
  user-select: none;
184
184
  min-width: 1.5ch;
185
185
  }
186
- > pre > code[data-line-state-mode] [data-line-body] {
186
+ & > pre > code[data-line-state-mode] [data-line-body] {
187
187
  white-space: pre;
188
188
  }
189
189
  /* Empty lines still need height so the diff column counts line up. */
190
- > pre > code[data-line-state-mode] [data-line-body]:empty::before {
190
+ & > pre > code[data-line-state-mode] [data-line-body]:empty::before {
191
191
  content: " ";
192
192
  }
193
- > pre > code [data-line-state="added"] {
193
+ & > pre > code [data-line-state="added"] {
194
194
  background: var(--a-success-muted);
195
195
  }
196
- > pre > code [data-line-state="removed"] {
196
+ & > pre > code [data-line-state="removed"] {
197
197
  background: var(--a-danger-muted);
198
198
  }
199
199
 
200
200
  /* Footer — optional chrome band below the code block
201
201
  (line counts, byte size, language family, etc.) */
202
- > footer {
202
+ & > footer {
203
203
  display: flex;
204
204
  flex-direction: row;
205
205
  align-items: center;
@@ -288,7 +288,7 @@
288
288
  CM's CSS-in-JS stylesheets load first + at lower specificity, so
289
289
  these rules override without !important. */
290
290
 
291
- > [data-cm-mount] {
291
+ & > [data-cm-mount] {
292
292
  display: block;
293
293
  overflow: hidden;
294
294
  }
@@ -87,7 +87,7 @@
87
87
  }
88
88
 
89
89
  /* ── Search header ── */
90
- > header {
90
+ & > header {
91
91
  display: flex;
92
92
  align-items: center;
93
93
  gap: var(--command-gap);
@@ -96,13 +96,13 @@
96
96
  flex-shrink: 0;
97
97
  }
98
98
 
99
- > header icon-ui {
99
+ & > header icon-ui {
100
100
  flex-shrink: 0;
101
101
  color: var(--command-fg-muted);
102
102
  --a-icon-size: 1rem;
103
103
  }
104
104
 
105
- > header input {
105
+ & > header input {
106
106
  flex: 1;
107
107
  min-width: 0;
108
108
  border: none;
@@ -115,16 +115,16 @@
115
115
  padding: 0;
116
116
  }
117
117
 
118
- > header input::placeholder {
118
+ & > header input::placeholder {
119
119
  color: var(--command-fg-muted);
120
120
  }
121
121
 
122
122
  /* Suppress focus ring on the input — the palette itself is the focused surface */
123
- > header input:focus-visible {
123
+ & > header input:focus-visible {
124
124
  outline: none;
125
125
  box-shadow: none;
126
126
  }
127
- > header:focus-within {
127
+ & > header:focus-within {
128
128
  outline: none;
129
129
  box-shadow: none;
130
130
  }
@@ -217,7 +217,7 @@
217
217
  }
218
218
 
219
219
  /* ── Footer ── */
220
- > footer {
220
+ & > footer {
221
221
  display: flex;
222
222
  align-items: center;
223
223
  gap: var(--command-px);
@@ -33,10 +33,10 @@
33
33
  :scope[columns="auto-fit"] { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
34
34
 
35
35
  /* Column span — children can span multiple columns */
36
- > [span="2"] { grid-column: span 2; }
37
- > [span="3"] { grid-column: span 3; }
38
- > [span="4"] { grid-column: span 4; }
39
- > [span="5"] { grid-column: span 5; }
40
- > [span="6"] { grid-column: span 6; }
41
- > [span="full"] { grid-column: 1 / -1; }
36
+ & > [span="2"] { grid-column: span 2; }
37
+ & > [span="3"] { grid-column: span 3; }
38
+ & > [span="4"] { grid-column: span 4; }
39
+ & > [span="5"] { grid-column: span 5; }
40
+ & > [span="6"] { grid-column: span 6; }
41
+ & > [span="full"] { grid-column: 1 / -1; }
42
42
  }
@@ -81,7 +81,7 @@
81
81
  }
82
82
 
83
83
  /* ── Pane header ── */
84
- > header {
84
+ & > header {
85
85
  box-sizing: border-box;
86
86
  display: flex;
87
87
  align-items: center;
@@ -98,17 +98,17 @@
98
98
  transition: background var(--pane-duration) var(--pane-easing);
99
99
  }
100
100
 
101
- > header:hover {
101
+ & > header:hover {
102
102
  background: var(--pane-header-bg-hover);
103
103
  }
104
104
 
105
- > header:focus-visible {
105
+ & > header:focus-visible {
106
106
  outline: none;
107
107
  box-shadow: var(--a-focus-ring) inset;
108
108
  }
109
109
 
110
110
  /* Collapse indicator — stamped by JS as icon-ui */
111
- > header > [slot="chevron"] {
111
+ & > header > [slot="chevron"] {
112
112
  --a-icon-size: var(--a-caret-size);
113
113
  flex-shrink: 0;
114
114
  margin-inline-start: auto;
@@ -122,7 +122,7 @@
122
122
  }
123
123
 
124
124
  /* ── Sections ── */
125
- > section {
125
+ & > section {
126
126
  flex: 1;
127
127
  min-height: 0;
128
128
  overflow-y: auto;
@@ -130,13 +130,13 @@
130
130
  padding: var(--pane-section-py) var(--pane-section-px);
131
131
  }
132
132
 
133
- > section::-webkit-scrollbar {
133
+ & > section::-webkit-scrollbar {
134
134
  display: none;
135
135
  }
136
136
 
137
137
  /* Section header — section's padding is the single source of horizontal inset;
138
138
  content inside the section must not add its own padding. */
139
- > section > header {
139
+ & > section > header {
140
140
  font-size: var(--pane-section-header-size);
141
141
  color: var(--pane-section-header-fg);
142
142
  padding-bottom: var(--pane-col-gap);
@@ -147,12 +147,12 @@
147
147
 
148
148
  /* Defensive: a data-col directly under a section inherits the section's inset;
149
149
  adding its own padding would compound and misalign with the section header. */
150
- > section > [data-col] {
150
+ & > section > [data-col] {
151
151
  padding: 0;
152
152
  }
153
153
 
154
154
  /* Section divider between sections */
155
- > section + section {
155
+ & > section + section {
156
156
  border-top: 1px solid var(--pane-border);
157
157
  }
158
158
 
@@ -165,7 +165,7 @@
165
165
  }
166
166
 
167
167
  /* ── Footer ── */
168
- > footer {
168
+ & > footer {
169
169
  min-height: var(--pane-bar-height);
170
170
  display: flex;
171
171
  align-items: center;
@@ -14,7 +14,7 @@
14
14
  text-align: inherit;
15
15
  }
16
16
 
17
- > * {
17
+ & > * {
18
18
  grid-area: 1 / 1;
19
19
  }
20
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-components",
3
- "version": "0.6.8",
3
+ "version": "0.6.9",
4
4
  "description": "AdiaUI web components \u2014 vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-runtime.",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",