@xenosystem/components 0.7.1 → 0.8.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.
@@ -0,0 +1,1917 @@
1
+ // src/chrome/classes.ts
2
+ var CLS_PANEL = "xeno-panel";
3
+ var CLS_PANEL_HEADER = "xeno-panel-header";
4
+ var CLS_PANEL_TITLE = "xeno-panel-title";
5
+ var CLS_PANEL_CONTENT = "xeno-panel-content";
6
+ var CLS_PANEL_CONTENT_NO_HEADER = "xeno-panel-content--no-header";
7
+ var CLS_TOOLBAR = "xeno-toolbar";
8
+ var CLS_TOOLBAR_GROUP = "xeno-toolbar-group";
9
+ var CLS_STATUSBAR = "xeno-statusbar";
10
+ var CLS_DIVIDER = "xeno-divider";
11
+ var CLS_SECTION = "xeno-section";
12
+ var CLS_SECTION_HEADER = "xeno-section-header";
13
+ var CLS_SECTION_TRIGGER = "xeno-section-trigger";
14
+ var CLS_SECTION_CHEVRON = "xeno-section-chevron";
15
+ var CLS_SECTION_TITLE = "xeno-section-title";
16
+ var CLS_SECTION_ACTIONS = "xeno-section-actions";
17
+ var CLS_SECTION_BODY = "xeno-section-body";
18
+ var CLS_ROWLIST = "xeno-rowlist";
19
+ var CLS_ROW = "xeno-row";
20
+ var CLS_ROW_ICON = "xeno-row-icon";
21
+ var CLS_ROW_LABEL = "xeno-row-label";
22
+ var CLS_ROW_META = "xeno-row-meta";
23
+ var CLS_ROW_TRAILING = "xeno-row-trailing";
24
+ var CLS_ICON_BUTTON = "xeno-iconbtn";
25
+ var CLS_TEXT_BUTTON = "xeno-textbtn";
26
+ var CLS_SEARCH = "xeno-search";
27
+ var CLS_SEARCH_INPUT = "xeno-search-input";
28
+ var CLS_SEGMENTED = "xeno-segmented";
29
+ var CLS_SEGMENT = "xeno-segment";
30
+ var CLS_TOGGLE = "xeno-toggle";
31
+ var CLS_TOGGLE_KNOB = "xeno-toggle-knob";
32
+ var CLS_FIELD_GROUP = "xeno-fieldgroup";
33
+ var CLS_FIELD = "xeno-field";
34
+ var CLS_FIELD_LABEL = "xeno-field-label";
35
+ var CLS_FIELD_CONTROL = "xeno-field-control";
36
+ var CLS_FIELD_HINT = "xeno-field-hint";
37
+ var CLS_EMPTY = "xeno-empty";
38
+ var CLS_LOADING = "xeno-loading";
39
+ var CLS_ERROR = "xeno-error";
40
+ var CLS_STATE = "xeno-state";
41
+ var CLS_STATE_ICON = "xeno-state-icon";
42
+ var CLS_STATE_TITLE = "xeno-state-title";
43
+ var CLS_STATE_HINT = "xeno-state-hint";
44
+ var CLS_STATE_PROGRESS = "xeno-state-progress";
45
+ var CLS_BADGE = "xeno-badge";
46
+ var CLS_DOT = "xeno-dot";
47
+ var CLS_ICON_FRAME = "xeno-iconframe";
48
+ var CLS_STAT = "xeno-stat";
49
+ var CLS_STAT_LABEL = "xeno-stat-label";
50
+ var CLS_STAT_VALUE = "xeno-stat-value";
51
+ var CLS_STAT_SUB = "xeno-stat-sub";
52
+ var CLS_BAR = "xeno-bar";
53
+ var CLS_BAR_SEGMENT = "xeno-bar-segment";
54
+ var CLS_SCROLL = "xeno-scroll";
55
+ var PANEL_TONES = Object.freeze([
56
+ "neutral",
57
+ "info",
58
+ "success",
59
+ "warning",
60
+ "error"
61
+ ]);
62
+ function cx(...parts) {
63
+ let out = "";
64
+ for (const p of parts) {
65
+ if (!p) continue;
66
+ out = out === "" ? p : `${out} ${p}`;
67
+ }
68
+ return out;
69
+ }
70
+ function rowClass(state = {}, extra) {
71
+ return cx(
72
+ CLS_ROW,
73
+ state.interactive !== false && `${CLS_ROW}--interactive`,
74
+ state.selected && `${CLS_ROW}--selected`,
75
+ state.active && `${CLS_ROW}--active`,
76
+ state.disabled && `${CLS_ROW}--disabled`,
77
+ extra
78
+ );
79
+ }
80
+ function badgeClass(tone = "neutral", extra) {
81
+ return cx(CLS_BADGE, tone !== "neutral" && `${CLS_BADGE}--${tone}`, extra);
82
+ }
83
+ function dotClass(tone = "neutral", extra) {
84
+ return cx(CLS_DOT, tone !== "neutral" && `${CLS_DOT}--${tone}`, extra);
85
+ }
86
+ function sectionClass(collapsed = false, extra) {
87
+ return cx(CLS_SECTION, collapsed && `${CLS_SECTION}--collapsed`, extra);
88
+ }
89
+ function iconButtonClass(state = {}, extra) {
90
+ return cx(
91
+ CLS_ICON_BUTTON,
92
+ state.active && `${CLS_ICON_BUTTON}--active`,
93
+ state.disabled && `${CLS_ICON_BUTTON}--disabled`,
94
+ extra
95
+ );
96
+ }
97
+
98
+ // src/chrome/useInject.ts
99
+ import { useState } from "react";
100
+
101
+ // src/chrome/tokens.ts
102
+ var PANEL_METRICS = Object.freeze({
103
+ /**
104
+ * Dense list row height.
105
+ *
106
+ * Census: history 22, layers 24, inspector 20 (as `min-height`). 22 is the median and the value
107
+ * of the densest *scrolling* list. Override per-list with `--xeno-row-h` — layers can keep 24
108
+ * without forking the primitive.
109
+ */
110
+ rowHeight: 22,
111
+ /** Indent per tree depth level. Census: layers 10 (the only implementation). */
112
+ rowIndent: 10,
113
+ /** Gap between a row's slots. Census: layers 4, inspector 4, history 5. */
114
+ rowGap: 4,
115
+ /** Fixed width of a row's leading icon slot — this is what keeps labels in ONE column. */
116
+ rowIconSlot: 14,
117
+ /** Horizontal padding inside panel chrome. Census: `0 6px` / `4px 6px`, 6px in 5/5 packages. */
118
+ gutter: 6,
119
+ /** Vertical padding of a header/toolbar strip. Census: `4px 6px` in 4/5 packages. */
120
+ stripPadY: 4,
121
+ /**
122
+ * Minimum height of a toolbar strip. Not set by any panel today (all are content-sized); 26 is
123
+ * what `4 + 18 + 4` already produces, pinned so toolbars align across panels.
124
+ */
125
+ toolbarMinHeight: 26,
126
+ /** Footer / status strip padding-y. Census: `2px 6px`, identical in layers + history. */
127
+ footerPadY: 2,
128
+ /** Section header height. Census: inspector 20 (the only real section header in the catalog). */
129
+ sectionHeaderHeight: 20,
130
+ /**
131
+ * Dense control height (inputs, segmented control, toolbar buttons).
132
+ *
133
+ * Census: inspector 18, history 18, transport 18, layers 20. **This is BELOW `DESIGN_SYSTEM.md`
134
+ * §3.1's 24px "compact" floor** — see {@link PANEL_METRICS.controlHeight}. 20 is the largest value
135
+ * any shipped panel uses, so adopting the primitives never makes a panel denser than it is today.
136
+ */
137
+ controlHeightSm: 20,
138
+ /** Standard control height — the DESIGN_SYSTEM §3.1 "compact controls" value. Use in panel bodies. */
139
+ controlHeight: 24,
140
+ /** In-row icon button. Census: inspector 14, layers 14, history 16. 14 is below a usable hit target. */
141
+ iconButtonSm: 16,
142
+ /** Toolbar icon button. Census: transport 20×18, color 22. */
143
+ iconButton: 20,
144
+ /** Icon glyph inside a `sm` button. Census: 11 is the most common glyph size across four packages. */
145
+ iconGlyphSm: 11,
146
+ /** Icon glyph inside an `md` button. Census: layers + transport primary use 12. */
147
+ iconGlyph: 12,
148
+ /** Badge height. Census: inspector + history byte-identical at 12. */
149
+ badgeHeight: 12,
150
+ /** Standard badge height — the `DESIGN_SYSTEM.md` §7 "Status Badges / Pills" value. */
151
+ badgeHeightMd: 18,
152
+ /** Square status dot edge. Never a circle (DESIGN_SYSTEM §3). */
153
+ dotSize: 6,
154
+ /** Shared label-column width in a `FieldGroup`. Census: inspector's configurable default is 56. */
155
+ fieldLabelWidth: 56,
156
+ /** Base corner radius. Census: `border-radius: 2` appears 38 times across 5/5 packages. */
157
+ radius: 2,
158
+ /** Outer-container radius (frames, cards). DESIGN_SYSTEM §7 "small radius". */
159
+ radiusMd: 6,
160
+ /** Micro text — badges, units. */
161
+ fontMicro: 8,
162
+ /** Label text — uppercase section/panel labels, footers. */
163
+ fontLabel: 9,
164
+ /** Secondary text — metadata, empty-state titles. */
165
+ fontMeta: 10,
166
+ /** Body text — the default panel size. */
167
+ fontBody: 11
168
+ });
169
+ var PANEL_COLORS = Object.freeze({
170
+ /** Row hover fill. DESIGN_SYSTEM §2 `rowHover`. **No shipped panel has a hover state at all.** */
171
+ rowHover: "rgba(255,255,255,0.05)",
172
+ /** Row selected fill. Census: byte-identical in layers + history. */
173
+ rowSelected: "rgba(255,255,255,0.10)",
174
+ /** Active/focus ring. Census: byte-identical `inset 0 0 0 1px` in layers + history. */
175
+ ring: "rgba(255,255,255,0.15)",
176
+ /** Keyboard focus outline. DESIGN_SYSTEM §11. **No shipped panel has one.** */
177
+ focus: "rgba(255,255,255,0.25)",
178
+ /** Recessed well fill for inputs. Census: 4/5 packages. */
179
+ well: "rgba(0,0,0,0.3)",
180
+ /** Hairline border. */
181
+ border: "rgba(255,255,255,0.08)",
182
+ /** Soft raised fill — chips, ghost buttons. Census: 5/5 packages. */
183
+ soft: "rgba(255,255,255,0.06)",
184
+ /** Section-header wash. Census: inspector. */
185
+ wash: "rgba(255,255,255,0.03)",
186
+ /** Solid status red (indicators). DESIGN_SYSTEM §2 `error`. */
187
+ error: "#ef4444",
188
+ /** Status red for TEXT. DESIGN_SYSTEM §2 `error.text`. */
189
+ errorText: "rgba(239,68,68,0.65)",
190
+ /** Status amber for text. */
191
+ warningText: "rgba(245,158,11,0.65)",
192
+ /** Status green for text. */
193
+ successText: "#5a9a6a",
194
+ /** Info blue-gray for text (the dimmest permitted chroma). */
195
+ infoText: "#7aa2c4"
196
+ });
197
+ var PANEL_DISABLED_OPACITY = 0.35;
198
+
199
+ // src/chrome/css.ts
200
+ var FG = "var(--panel-fg, var(--xeno-text-body, #e5e5e9))";
201
+ var MUTED = "var(--panel-muted, var(--xeno-text-muted, #79797f))";
202
+ var DIM = "var(--panel-dim, var(--xeno-text-dim, #57575e))";
203
+ var BG = "var(--panel-bg, var(--xeno-canvas-bg, #111111))";
204
+ var HEADER = "var(--panel-header, var(--xeno-panel-header, #1a1a1a))";
205
+ var BORDER = `var(--panel-border, var(--xeno-border, ${PANEL_COLORS.border}))`;
206
+ var PAGE = "var(--xeno-page-bg, #08080a)";
207
+ var GAP = "var(--xeno-panel-gap, 3px)";
208
+ var RADIUS = `var(--xeno-panel-radius, ${PANEL_METRICS.radiusMd}px)`;
209
+ var ROW_H = `var(--xeno-row-h, ${PANEL_METRICS.rowHeight}px)`;
210
+ var CTRL_H = `var(--xeno-control-h, ${PANEL_METRICS.controlHeightSm}px)`;
211
+ var LABEL_W = `var(--xeno-field-label-w, ${PANEL_METRICS.fieldLabelWidth}px)`;
212
+ var PANEL_PRIMITIVES_CSS = `
213
+ /* ================================================================== */
214
+ /* @xenosystem/workbench/primitives \u2014 canonical panel chrome */
215
+ /* Lifted from xeno-workflow (frame contract) + xeno-post (kit). */
216
+ /* Aligned to DESIGN_SYSTEM.md. Generated from PANEL_METRICS. */
217
+ /* ================================================================== */
218
+
219
+ /* \u2500\u2500\u2500 1. Frame \u2014 xeno-workflow's contract, class names verbatim \u2500\u2500\u2500 */
220
+
221
+ .xeno-panel {
222
+ position: relative;
223
+ display: flex;
224
+ flex-direction: column;
225
+ min-height: 0;
226
+ border-radius: ${RADIUS};
227
+ overflow: hidden;
228
+ background: transparent;
229
+ isolation: isolate;
230
+ color: ${FG};
231
+ font-size: ${PANEL_METRICS.fontBody}px;
232
+ }
233
+ .xeno-panel::before {
234
+ content: '';
235
+ position: absolute;
236
+ inset: 0;
237
+ pointer-events: none;
238
+ background: ${PAGE};
239
+ z-index: 0;
240
+ border-radius: ${RADIUS};
241
+ }
242
+ .xeno-panel-header {
243
+ position: relative;
244
+ z-index: 2;
245
+ display: flex;
246
+ align-items: center;
247
+ gap: ${PANEL_METRICS.gutter}px;
248
+ height: ${PANEL_METRICS.toolbarMinHeight - 2}px;
249
+ flex-shrink: 0;
250
+ padding: 0 ${PANEL_METRICS.gutter}px;
251
+ background: var(--xeno-tab-bar, #272727);
252
+ border-radius: calc(${RADIUS} - 2px) calc(${RADIUS} - 2px) 0 0;
253
+ margin: ${GAP} ${GAP} 0;
254
+ overflow: hidden;
255
+ }
256
+ .xeno-panel-title {
257
+ font-size: ${PANEL_METRICS.fontLabel}px;
258
+ font-weight: 500;
259
+ text-transform: uppercase;
260
+ letter-spacing: 0.08em;
261
+ color: ${FG};
262
+ white-space: nowrap;
263
+ overflow: hidden;
264
+ text-overflow: ellipsis;
265
+ flex: 1 1 auto;
266
+ min-width: 0;
267
+ }
268
+ .xeno-panel-content {
269
+ position: relative;
270
+ z-index: 1;
271
+ display: flex;
272
+ flex-direction: column;
273
+ flex: 1 1 auto;
274
+ min-height: 0;
275
+ background: ${BG};
276
+ margin: 2px ${GAP} ${GAP};
277
+ border-radius: 0 0 calc(${RADIUS} - 2px) calc(${RADIUS} - 2px);
278
+ overflow: hidden;
279
+ }
280
+ .xeno-panel-content--no-header {
281
+ margin-top: ${GAP};
282
+ border-radius: calc(${RADIUS} - 2px);
283
+ }
284
+
285
+ /* \u2500\u2500\u2500 2. Strips: toolbar, status bar, divider, scroll \u2500\u2500\u2500 */
286
+
287
+ .xeno-toolbar {
288
+ display: flex;
289
+ align-items: center;
290
+ gap: ${PANEL_METRICS.gutter}px;
291
+ flex: 0 0 auto;
292
+ min-height: ${PANEL_METRICS.toolbarMinHeight}px;
293
+ padding: ${PANEL_METRICS.stripPadY}px ${PANEL_METRICS.gutter}px;
294
+ box-sizing: border-box;
295
+ background: ${HEADER};
296
+ border-bottom: 1px solid ${BORDER};
297
+ color: ${FG};
298
+ font-size: ${PANEL_METRICS.fontBody}px;
299
+ user-select: none;
300
+ }
301
+ .xeno-toolbar--flush {
302
+ border-bottom: none;
303
+ }
304
+ .xeno-toolbar-group {
305
+ display: flex;
306
+ align-items: center;
307
+ gap: ${PANEL_METRICS.rowGap}px;
308
+ min-width: 0;
309
+ }
310
+ .xeno-toolbar-group--end {
311
+ margin-left: auto;
312
+ flex: 0 0 auto;
313
+ }
314
+
315
+ .xeno-statusbar {
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: space-between;
319
+ gap: 8px;
320
+ flex: 0 0 auto;
321
+ padding: ${PANEL_METRICS.footerPadY}px ${PANEL_METRICS.gutter}px;
322
+ background: ${HEADER};
323
+ color: ${MUTED};
324
+ font-size: ${PANEL_METRICS.fontLabel}px;
325
+ font-variant-numeric: tabular-nums;
326
+ user-select: none;
327
+ }
328
+
329
+ .xeno-divider {
330
+ flex: 0 0 auto;
331
+ background: ${BORDER};
332
+ height: 1px;
333
+ width: 100%;
334
+ }
335
+ .xeno-divider--vertical {
336
+ width: 1px;
337
+ height: 12px;
338
+ align-self: center;
339
+ }
340
+
341
+ .xeno-scroll {
342
+ flex: 1 1 auto;
343
+ min-height: 0;
344
+ overflow-y: auto;
345
+ overflow-x: hidden;
346
+ outline: none;
347
+ }
348
+ .xeno-scroll::-webkit-scrollbar {
349
+ width: 10px;
350
+ height: 10px;
351
+ }
352
+ .xeno-scroll::-webkit-scrollbar-track {
353
+ background: transparent;
354
+ }
355
+ .xeno-scroll::-webkit-scrollbar-thumb {
356
+ background: #3a3a3d;
357
+ border: 3px solid transparent;
358
+ background-clip: padding-box;
359
+ border-radius: ${PANEL_METRICS.radius}px;
360
+ }
361
+ .xeno-scroll::-webkit-scrollbar-thumb:hover {
362
+ background: #555555;
363
+ border: 3px solid transparent;
364
+ background-clip: padding-box;
365
+ }
366
+
367
+ /* \u2500\u2500\u2500 3. Section \u2500\u2500\u2500 */
368
+
369
+ .xeno-section {
370
+ display: flex;
371
+ flex-direction: column;
372
+ flex: 0 0 auto;
373
+ min-width: 0;
374
+ }
375
+ .xeno-section-header {
376
+ display: flex;
377
+ align-items: center;
378
+ gap: ${PANEL_METRICS.rowGap}px;
379
+ height: ${PANEL_METRICS.sectionHeaderHeight}px;
380
+ flex: 0 0 auto;
381
+ padding: 0 ${PANEL_METRICS.gutter}px;
382
+ background: ${PANEL_COLORS.wash};
383
+ user-select: none;
384
+ }
385
+ .xeno-section-trigger {
386
+ display: flex;
387
+ align-items: center;
388
+ gap: ${PANEL_METRICS.rowGap}px;
389
+ flex: 1 1 auto;
390
+ min-width: 0;
391
+ height: 100%;
392
+ padding: 0;
393
+ border: none;
394
+ background: transparent;
395
+ color: inherit;
396
+ font: inherit;
397
+ text-align: left;
398
+ cursor: pointer;
399
+ }
400
+ /* A non-collapsible header renders a <div> with this class, not a disabled button. */
401
+ div.xeno-section-trigger {
402
+ cursor: default;
403
+ }
404
+ .xeno-section-chevron {
405
+ display: flex;
406
+ align-items: center;
407
+ justify-content: center;
408
+ width: 10px;
409
+ height: 10px;
410
+ flex: 0 0 auto;
411
+ color: ${MUTED};
412
+ transform: rotate(90deg);
413
+ transition: transform 80ms ease;
414
+ }
415
+ .xeno-section--collapsed .xeno-section-chevron {
416
+ transform: rotate(0deg);
417
+ }
418
+ .xeno-section-title {
419
+ flex: 1 1 auto;
420
+ min-width: 0;
421
+ overflow: hidden;
422
+ text-overflow: ellipsis;
423
+ white-space: nowrap;
424
+ font-size: ${PANEL_METRICS.fontLabel}px;
425
+ font-weight: 600;
426
+ letter-spacing: 0.06em;
427
+ text-transform: uppercase;
428
+ color: ${MUTED};
429
+ }
430
+ .xeno-section-actions {
431
+ display: flex;
432
+ align-items: center;
433
+ gap: ${PANEL_METRICS.rowGap}px;
434
+ flex: 0 0 auto;
435
+ }
436
+ .xeno-section-body {
437
+ padding: 3px 0;
438
+ min-width: 0;
439
+ }
440
+ .xeno-section-body--off {
441
+ opacity: ${PANEL_DISABLED_OPACITY};
442
+ pointer-events: none;
443
+ }
444
+ .xeno-section-body--flush {
445
+ padding: 0;
446
+ }
447
+ .xeno-section--collapsed .xeno-section-body {
448
+ display: none;
449
+ }
450
+
451
+ /* \u2500\u2500\u2500 4. Rows \u2500\u2500\u2500 */
452
+
453
+ .xeno-rowlist {
454
+ display: flex;
455
+ flex-direction: column;
456
+ min-width: 0;
457
+ }
458
+ .xeno-rowlist--divided .xeno-row {
459
+ border-bottom: 1px solid ${BORDER};
460
+ }
461
+
462
+ .xeno-row {
463
+ display: flex;
464
+ align-items: center;
465
+ gap: ${PANEL_METRICS.rowGap}px;
466
+ height: ${ROW_H};
467
+ flex: 0 0 auto;
468
+ padding: 0 ${PANEL_METRICS.gutter}px;
469
+ box-sizing: border-box;
470
+ min-width: 0;
471
+ overflow: hidden;
472
+ color: ${FG};
473
+ font-size: ${PANEL_METRICS.fontBody}px;
474
+ background: transparent;
475
+ user-select: none;
476
+ transition: background-color 80ms ease;
477
+ }
478
+ .xeno-row--interactive {
479
+ cursor: pointer;
480
+ }
481
+ .xeno-row--interactive:hover {
482
+ background: ${PANEL_COLORS.rowHover};
483
+ }
484
+ .xeno-row--selected {
485
+ background: ${PANEL_COLORS.rowSelected};
486
+ }
487
+ .xeno-row--selected:hover {
488
+ background: ${PANEL_COLORS.rowSelected};
489
+ }
490
+ .xeno-row--active {
491
+ box-shadow: inset 0 0 0 1px ${PANEL_COLORS.ring};
492
+ }
493
+ .xeno-row--disabled {
494
+ opacity: ${PANEL_DISABLED_OPACITY};
495
+ cursor: not-allowed;
496
+ }
497
+ .xeno-row--disabled:hover {
498
+ background: transparent;
499
+ }
500
+ .xeno-row:focus-visible {
501
+ outline: 1px solid ${PANEL_COLORS.focus};
502
+ outline-offset: -1px;
503
+ }
504
+ .xeno-row-icon {
505
+ display: flex;
506
+ align-items: center;
507
+ justify-content: center;
508
+ width: ${PANEL_METRICS.rowIconSlot}px;
509
+ height: ${PANEL_METRICS.rowIconSlot}px;
510
+ flex: 0 0 auto;
511
+ opacity: 0.8;
512
+ }
513
+ .xeno-row-label {
514
+ flex: 1 1 auto;
515
+ min-width: 0;
516
+ overflow: hidden;
517
+ text-overflow: ellipsis;
518
+ white-space: nowrap;
519
+ }
520
+ .xeno-row-meta {
521
+ flex: 0 0 auto;
522
+ font-size: ${PANEL_METRICS.fontLabel}px;
523
+ color: ${MUTED};
524
+ font-variant-numeric: tabular-nums;
525
+ }
526
+ .xeno-row-trailing {
527
+ display: flex;
528
+ align-items: center;
529
+ gap: ${PANEL_METRICS.rowGap}px;
530
+ flex: 0 0 auto;
531
+ margin-left: auto;
532
+ }
533
+
534
+ /* \u2500\u2500\u2500 5. Controls \u2500\u2500\u2500 */
535
+
536
+ .xeno-iconbtn {
537
+ display: flex;
538
+ align-items: center;
539
+ justify-content: center;
540
+ flex: 0 0 auto;
541
+ padding: 0;
542
+ border: none;
543
+ border-radius: ${PANEL_METRICS.radius}px;
544
+ background: transparent;
545
+ color: inherit;
546
+ cursor: pointer;
547
+ opacity: 0.8;
548
+ transition: background-color 80ms ease, opacity 80ms ease;
549
+ }
550
+ .xeno-iconbtn--sm {
551
+ width: ${PANEL_METRICS.iconButtonSm}px;
552
+ height: ${PANEL_METRICS.iconButtonSm}px;
553
+ }
554
+ .xeno-iconbtn--md {
555
+ width: ${PANEL_METRICS.iconButton}px;
556
+ height: ${PANEL_METRICS.iconButton}px;
557
+ }
558
+ .xeno-iconbtn--sm svg {
559
+ width: ${PANEL_METRICS.iconGlyphSm}px;
560
+ height: ${PANEL_METRICS.iconGlyphSm}px;
561
+ }
562
+ .xeno-iconbtn--md svg {
563
+ width: ${PANEL_METRICS.iconGlyph}px;
564
+ height: ${PANEL_METRICS.iconGlyph}px;
565
+ }
566
+ .xeno-iconbtn:hover {
567
+ background: ${PANEL_COLORS.soft};
568
+ opacity: 1;
569
+ }
570
+ .xeno-iconbtn--active {
571
+ background: ${PANEL_COLORS.rowSelected};
572
+ opacity: 1;
573
+ }
574
+ .xeno-iconbtn:focus-visible {
575
+ outline: 1px solid ${PANEL_COLORS.focus};
576
+ outline-offset: 1px;
577
+ }
578
+ .xeno-iconbtn[disabled] {
579
+ opacity: ${PANEL_DISABLED_OPACITY};
580
+ cursor: not-allowed;
581
+ background: transparent;
582
+ }
583
+
584
+ .xeno-textbtn {
585
+ flex: 0 0 auto;
586
+ padding: 0;
587
+ border: none;
588
+ background: transparent;
589
+ color: ${MUTED};
590
+ font: inherit;
591
+ font-size: ${PANEL_METRICS.fontMeta}px;
592
+ text-align: left;
593
+ cursor: pointer;
594
+ transition: color 80ms ease;
595
+ }
596
+ .xeno-textbtn:hover {
597
+ color: ${FG};
598
+ }
599
+ .xeno-textbtn--strong {
600
+ color: ${FG};
601
+ }
602
+ .xeno-textbtn:focus-visible {
603
+ outline: 1px solid ${PANEL_COLORS.focus};
604
+ outline-offset: 1px;
605
+ }
606
+ .xeno-textbtn[disabled] {
607
+ opacity: ${PANEL_DISABLED_OPACITY};
608
+ cursor: not-allowed;
609
+ color: ${MUTED};
610
+ }
611
+
612
+ .xeno-search {
613
+ display: flex;
614
+ align-items: center;
615
+ gap: ${PANEL_METRICS.rowGap}px;
616
+ flex: 1 1 auto;
617
+ min-width: 0;
618
+ height: ${CTRL_H};
619
+ box-sizing: border-box;
620
+ padding: 0 ${PANEL_METRICS.gutter}px;
621
+ background: ${PANEL_COLORS.well};
622
+ border: 1px solid ${BORDER};
623
+ border-radius: ${PANEL_METRICS.radius}px;
624
+ color: ${FG};
625
+ transition: border-color 80ms ease;
626
+ }
627
+ .xeno-search:focus-within {
628
+ border-color: ${PANEL_COLORS.ring};
629
+ }
630
+ .xeno-search--disabled {
631
+ opacity: ${PANEL_DISABLED_OPACITY};
632
+ }
633
+ .xeno-search-glyph {
634
+ display: flex;
635
+ align-items: center;
636
+ justify-content: center;
637
+ flex: 0 0 auto;
638
+ color: ${MUTED};
639
+ }
640
+ .xeno-search-input {
641
+ flex: 1 1 auto;
642
+ min-width: 0;
643
+ height: 100%;
644
+ padding: 0;
645
+ border: none;
646
+ background: transparent;
647
+ color: inherit;
648
+ font: inherit;
649
+ font-size: ${PANEL_METRICS.fontBody}px;
650
+ outline: none;
651
+ cursor: text;
652
+ }
653
+ .xeno-search-input::placeholder {
654
+ color: ${DIM};
655
+ }
656
+ .xeno-search-clear {
657
+ display: flex;
658
+ align-items: center;
659
+ justify-content: center;
660
+ flex: 0 0 auto;
661
+ width: 14px;
662
+ height: 14px;
663
+ padding: 0;
664
+ border: none;
665
+ border-radius: ${PANEL_METRICS.radius}px;
666
+ background: transparent;
667
+ color: ${MUTED};
668
+ cursor: pointer;
669
+ }
670
+ .xeno-search-clear:hover {
671
+ color: ${FG};
672
+ background: ${PANEL_COLORS.soft};
673
+ }
674
+
675
+ .xeno-segmented {
676
+ display: inline-flex;
677
+ align-items: stretch;
678
+ flex: 0 0 auto;
679
+ gap: 1px;
680
+ padding: 1px;
681
+ background: ${PANEL_COLORS.soft};
682
+ border-radius: ${PANEL_METRICS.radius}px;
683
+ box-sizing: border-box;
684
+ }
685
+ .xeno-segmented--sm {
686
+ height: ${PANEL_METRICS.iconButtonSm + 2}px;
687
+ }
688
+ .xeno-segmented--md {
689
+ height: ${CTRL_H};
690
+ }
691
+ .xeno-segmented--stretch {
692
+ display: flex;
693
+ width: 100%;
694
+ }
695
+ .xeno-segmented--stretch .xeno-segment {
696
+ flex: 1 1 0;
697
+ }
698
+ .xeno-segment {
699
+ display: flex;
700
+ align-items: center;
701
+ justify-content: center;
702
+ padding: 0 6px;
703
+ border: none;
704
+ border-radius: 1px;
705
+ background: transparent;
706
+ color: ${MUTED};
707
+ font: inherit;
708
+ font-size: ${PANEL_METRICS.fontLabel}px;
709
+ letter-spacing: 0.04em;
710
+ text-transform: uppercase;
711
+ cursor: pointer;
712
+ transition: background-color 80ms ease, color 80ms ease;
713
+ white-space: nowrap;
714
+ }
715
+ .xeno-segment:hover {
716
+ color: ${FG};
717
+ }
718
+ .xeno-segment--checked {
719
+ background: ${PANEL_COLORS.rowSelected};
720
+ color: ${FG};
721
+ }
722
+ .xeno-segment:focus-visible {
723
+ outline: 1px solid ${PANEL_COLORS.focus};
724
+ outline-offset: -1px;
725
+ }
726
+ .xeno-segment[disabled] {
727
+ opacity: ${PANEL_DISABLED_OPACITY};
728
+ cursor: not-allowed;
729
+ }
730
+
731
+ .xeno-toggle {
732
+ position: relative;
733
+ display: inline-flex;
734
+ align-items: center;
735
+ flex: 0 0 auto;
736
+ padding: 0;
737
+ border: none;
738
+ border-radius: ${PANEL_METRICS.radius}px;
739
+ background: ${PANEL_COLORS.soft};
740
+ cursor: pointer;
741
+ transition: background-color 80ms ease;
742
+ }
743
+ .xeno-toggle--sm {
744
+ width: 16px;
745
+ height: 10px;
746
+ }
747
+ .xeno-toggle--md {
748
+ width: 22px;
749
+ height: 12px;
750
+ }
751
+ .xeno-toggle--on {
752
+ background: rgba(255, 255, 255, 0.25);
753
+ }
754
+ .xeno-toggle-knob {
755
+ position: absolute;
756
+ top: 2px;
757
+ left: 2px;
758
+ background: ${MUTED};
759
+ border-radius: 1px;
760
+ transition: transform 80ms ease, border-radius 80ms ease, background-color 80ms ease;
761
+ }
762
+ .xeno-toggle--sm .xeno-toggle-knob {
763
+ width: 6px;
764
+ height: 6px;
765
+ }
766
+ .xeno-toggle--md .xeno-toggle-knob {
767
+ width: 8px;
768
+ height: 8px;
769
+ }
770
+ .xeno-toggle--on .xeno-toggle-knob {
771
+ background: ${FG};
772
+ border-radius: ${PANEL_METRICS.radius}px;
773
+ }
774
+ .xeno-toggle--sm.xeno-toggle--on .xeno-toggle-knob {
775
+ transform: translateX(6px);
776
+ }
777
+ .xeno-toggle--md.xeno-toggle--on .xeno-toggle-knob {
778
+ transform: translateX(10px);
779
+ }
780
+ .xeno-toggle:focus-visible {
781
+ outline: 1px solid ${PANEL_COLORS.focus};
782
+ outline-offset: 1px;
783
+ }
784
+ /* Both layers, per DESIGN_SYSTEM \xA73.1 "Cursors \u2014 two layers, both required": the modifier class
785
+ for callers that style a wrapper, and the attribute selector for the real disabled control. */
786
+ .xeno-toggle--disabled,
787
+ .xeno-toggle[disabled] {
788
+ opacity: ${PANEL_DISABLED_OPACITY};
789
+ cursor: not-allowed;
790
+ }
791
+
792
+ /* \u2500\u2500\u2500 6. Fields \u2500\u2500\u2500 */
793
+
794
+ .xeno-fieldgroup {
795
+ display: flex;
796
+ flex-direction: column;
797
+ gap: 2px;
798
+ min-width: 0;
799
+ }
800
+ .xeno-field {
801
+ display: flex;
802
+ align-items: center;
803
+ gap: ${PANEL_METRICS.rowGap}px;
804
+ flex-wrap: wrap;
805
+ min-height: ${PANEL_METRICS.sectionHeaderHeight}px;
806
+ padding: 1px ${PANEL_METRICS.gutter}px;
807
+ box-sizing: border-box;
808
+ min-width: 0;
809
+ }
810
+ .xeno-field-label {
811
+ flex: 0 0 auto;
812
+ width: ${LABEL_W};
813
+ overflow: hidden;
814
+ text-overflow: ellipsis;
815
+ white-space: nowrap;
816
+ font-size: ${PANEL_METRICS.fontMeta}px;
817
+ color: ${MUTED};
818
+ user-select: none;
819
+ cursor: default;
820
+ }
821
+ .xeno-field-control {
822
+ display: flex;
823
+ align-items: center;
824
+ gap: ${PANEL_METRICS.rowGap}px;
825
+ flex: 1 1 auto;
826
+ min-width: 0;
827
+ justify-content: flex-end;
828
+ }
829
+ .xeno-field-hint {
830
+ flex: 1 1 100%;
831
+ padding-left: ${LABEL_W};
832
+ font-size: ${PANEL_METRICS.fontLabel}px;
833
+ color: ${DIM};
834
+ }
835
+ .xeno-field--stacked {
836
+ flex-direction: column;
837
+ align-items: stretch;
838
+ }
839
+ .xeno-field--stacked .xeno-field-label {
840
+ width: auto;
841
+ }
842
+ .xeno-field--stacked .xeno-field-control {
843
+ justify-content: flex-start;
844
+ }
845
+ .xeno-field--stacked .xeno-field-hint {
846
+ padding-left: 0;
847
+ }
848
+
849
+ /* \u2500\u2500\u2500 7. States \u2500\u2500\u2500 */
850
+
851
+ .xeno-state {
852
+ display: flex;
853
+ flex-direction: column;
854
+ align-items: center;
855
+ justify-content: center;
856
+ gap: 6px;
857
+ padding: 12px;
858
+ text-align: center;
859
+ min-width: 0;
860
+ }
861
+ .xeno-state-icon {
862
+ display: flex;
863
+ align-items: center;
864
+ justify-content: center;
865
+ width: 24px;
866
+ height: 24px;
867
+ border: 1px solid ${BORDER};
868
+ border-radius: ${PANEL_METRICS.radius}px;
869
+ color: ${MUTED};
870
+ }
871
+ .xeno-empty,
872
+ .xeno-loading {
873
+ user-select: none;
874
+ }
875
+ .xeno-state-title {
876
+ font-size: ${PANEL_METRICS.fontMeta}px;
877
+ text-transform: uppercase;
878
+ letter-spacing: 0.08em;
879
+ opacity: 0.4;
880
+ color: ${FG};
881
+ }
882
+ .xeno-state-hint {
883
+ max-width: 28ch;
884
+ font-size: ${PANEL_METRICS.fontMeta}px;
885
+ line-height: 1.45;
886
+ color: ${MUTED};
887
+ }
888
+ .xeno-error .xeno-state-title {
889
+ opacity: 1;
890
+ color: ${PANEL_COLORS.errorText};
891
+ }
892
+ .xeno-state-progress {
893
+ position: relative;
894
+ width: 64px;
895
+ height: 2px;
896
+ border-radius: 1px;
897
+ background: ${PANEL_COLORS.soft};
898
+ overflow: hidden;
899
+ }
900
+ .xeno-state-progress::after {
901
+ content: '';
902
+ position: absolute;
903
+ top: 0;
904
+ left: 0;
905
+ width: 40%;
906
+ height: 100%;
907
+ background: rgba(255, 255, 255, 0.35);
908
+ border-radius: 1px;
909
+ animation: xeno-indeterminate 1100ms ease-in-out infinite;
910
+ }
911
+ @keyframes xeno-indeterminate {
912
+ 0% { transform: translateX(-100%); }
913
+ 100% { transform: translateX(250%); }
914
+ }
915
+ @keyframes xeno-spin {
916
+ to { transform: rotate(360deg); }
917
+ }
918
+ .xeno-spin {
919
+ animation: xeno-spin 900ms linear infinite;
920
+ }
921
+
922
+ /* \u2500\u2500\u2500 8. Indicators \u2500\u2500\u2500 */
923
+
924
+ .xeno-badge {
925
+ display: inline-flex;
926
+ align-items: center;
927
+ gap: 3px;
928
+ flex: 0 0 auto;
929
+ height: ${PANEL_METRICS.badgeHeight}px;
930
+ line-height: ${PANEL_METRICS.badgeHeight}px;
931
+ padding: 0 3px;
932
+ border-radius: ${PANEL_METRICS.radius}px;
933
+ background: ${BORDER};
934
+ color: ${MUTED};
935
+ font-size: ${PANEL_METRICS.fontMicro}px;
936
+ letter-spacing: 0.03em;
937
+ white-space: nowrap;
938
+ user-select: none;
939
+ }
940
+ .xeno-badge--md {
941
+ height: ${PANEL_METRICS.badgeHeightMd}px;
942
+ line-height: ${PANEL_METRICS.badgeHeightMd}px;
943
+ padding: 0 5px;
944
+ font-size: ${PANEL_METRICS.fontMeta}px;
945
+ }
946
+ .xeno-badge--info { color: ${PANEL_COLORS.infoText}; }
947
+ .xeno-badge--success { color: ${PANEL_COLORS.successText}; }
948
+ .xeno-badge--warning { color: ${PANEL_COLORS.warningText}; }
949
+ .xeno-badge--error { color: ${PANEL_COLORS.errorText}; }
950
+
951
+ .xeno-dot {
952
+ display: inline-block;
953
+ flex: 0 0 auto;
954
+ width: ${PANEL_METRICS.dotSize}px;
955
+ height: ${PANEL_METRICS.dotSize}px;
956
+ border-radius: 1px;
957
+ background: ${MUTED};
958
+ }
959
+ .xeno-dot--info { background: ${PANEL_COLORS.infoText}; }
960
+ .xeno-dot--success { background: ${PANEL_COLORS.successText}; }
961
+ .xeno-dot--warning { background: ${PANEL_COLORS.warningText}; }
962
+ .xeno-dot--error { background: ${PANEL_COLORS.error}; }
963
+
964
+ .xeno-iconframe {
965
+ display: flex;
966
+ align-items: center;
967
+ justify-content: center;
968
+ flex: 0 0 auto;
969
+ border: 1px solid ${BORDER};
970
+ border-radius: ${PANEL_METRICS.radius}px;
971
+ background: rgba(255, 255, 255, 0.02);
972
+ color: ${FG};
973
+ }
974
+
975
+ /* \u2500\u2500\u2500 9. Data tiles \u2500\u2500\u2500 */
976
+
977
+ .xeno-stat {
978
+ display: flex;
979
+ flex-direction: column;
980
+ gap: 3px;
981
+ min-width: 0;
982
+ padding: ${PANEL_METRICS.gutter}px;
983
+ border: 1px solid ${BORDER};
984
+ border-radius: ${PANEL_METRICS.radius}px;
985
+ background: rgba(0, 0, 0, 0.2);
986
+ }
987
+ .xeno-stat-label {
988
+ display: flex;
989
+ align-items: center;
990
+ justify-content: space-between;
991
+ gap: ${PANEL_METRICS.rowGap}px;
992
+ font-size: ${PANEL_METRICS.fontLabel}px;
993
+ text-transform: uppercase;
994
+ letter-spacing: 0.06em;
995
+ color: ${MUTED};
996
+ }
997
+ .xeno-stat-value {
998
+ font-size: 16px;
999
+ font-weight: 600;
1000
+ line-height: 1.1;
1001
+ color: ${FG};
1002
+ font-variant-numeric: tabular-nums;
1003
+ overflow: hidden;
1004
+ text-overflow: ellipsis;
1005
+ white-space: nowrap;
1006
+ }
1007
+ .xeno-stat-sub {
1008
+ font-size: ${PANEL_METRICS.fontLabel}px;
1009
+ color: ${DIM};
1010
+ font-variant-numeric: tabular-nums;
1011
+ }
1012
+
1013
+ .xeno-bar {
1014
+ display: flex;
1015
+ width: 100%;
1016
+ height: 6px;
1017
+ border-radius: 1px;
1018
+ background: rgba(255, 255, 255, 0.04);
1019
+ overflow: hidden;
1020
+ }
1021
+ .xeno-bar-segment {
1022
+ height: 100%;
1023
+ min-width: 0;
1024
+ }
1025
+
1026
+ /* \u2500\u2500\u2500 10. Reduced motion (DESIGN_SYSTEM \xA711) \u2500\u2500\u2500 */
1027
+
1028
+ @media (prefers-reduced-motion: reduce) {
1029
+ .xeno-row,
1030
+ .xeno-iconbtn,
1031
+ .xeno-segment,
1032
+ .xeno-toggle,
1033
+ .xeno-toggle-knob,
1034
+ .xeno-search,
1035
+ .xeno-section-chevron {
1036
+ transition: none;
1037
+ }
1038
+ .xeno-state-progress::after,
1039
+ .xeno-spin {
1040
+ animation: none;
1041
+ }
1042
+ }
1043
+ `;
1044
+
1045
+ // src/chrome/inject.ts
1046
+ var PANEL_PRIMITIVES_STYLE_ID = "xeno-panel-primitives";
1047
+ function ensurePanelPrimitivesInjected(target) {
1048
+ const doc = target ?? globalThis.document ?? void 0;
1049
+ if (!doc || !doc.head) return false;
1050
+ if (doc.getElementById(PANEL_PRIMITIVES_STYLE_ID)) return false;
1051
+ const style = doc.createElement("style");
1052
+ style.id = PANEL_PRIMITIVES_STYLE_ID;
1053
+ style.textContent = PANEL_PRIMITIVES_CSS;
1054
+ doc.head.appendChild(style);
1055
+ return true;
1056
+ }
1057
+
1058
+ // src/chrome/useInject.ts
1059
+ function usePanelPrimitives() {
1060
+ useState(() => {
1061
+ ensurePanelPrimitivesInjected();
1062
+ return null;
1063
+ });
1064
+ }
1065
+
1066
+ // src/chrome/frame.tsx
1067
+ import { jsx, jsxs } from "react/jsx-runtime";
1068
+ function PanelFrame({
1069
+ title,
1070
+ actions,
1071
+ showHeader,
1072
+ children,
1073
+ className,
1074
+ contentClassName
1075
+ }) {
1076
+ usePanelPrimitives();
1077
+ const header = showHeader ?? (title != null || actions != null);
1078
+ return /* @__PURE__ */ jsxs("div", { className: cx(CLS_PANEL, className), children: [
1079
+ header ? /* @__PURE__ */ jsxs("div", { className: CLS_PANEL_HEADER, children: [
1080
+ title != null ? /* @__PURE__ */ jsx("span", { className: CLS_PANEL_TITLE, children: title }) : null,
1081
+ actions != null ? /* @__PURE__ */ jsx("div", { className: CLS_TOOLBAR_GROUP, children: actions }) : null
1082
+ ] }) : null,
1083
+ /* @__PURE__ */ jsx(
1084
+ "div",
1085
+ {
1086
+ className: cx(CLS_PANEL_CONTENT, !header && CLS_PANEL_CONTENT_NO_HEADER, contentClassName),
1087
+ children
1088
+ }
1089
+ )
1090
+ ] });
1091
+ }
1092
+ function Toolbar({
1093
+ left,
1094
+ right,
1095
+ children,
1096
+ divided = true,
1097
+ className
1098
+ }) {
1099
+ usePanelPrimitives();
1100
+ return /* @__PURE__ */ jsxs("div", { className: cx(CLS_TOOLBAR, !divided && `${CLS_TOOLBAR}--flush`, className), children: [
1101
+ left != null ? /* @__PURE__ */ jsx("div", { className: CLS_TOOLBAR_GROUP, children: left }) : null,
1102
+ children,
1103
+ right != null ? /* @__PURE__ */ jsx("div", { className: cx(CLS_TOOLBAR_GROUP, `${CLS_TOOLBAR_GROUP}--end`), children: right }) : null
1104
+ ] });
1105
+ }
1106
+ function ToolbarGroup({ children, end, className }) {
1107
+ return /* @__PURE__ */ jsx("div", { className: cx(CLS_TOOLBAR_GROUP, end && `${CLS_TOOLBAR_GROUP}--end`, className), children });
1108
+ }
1109
+ function Divider({ vertical, className }) {
1110
+ usePanelPrimitives();
1111
+ return /* @__PURE__ */ jsx(
1112
+ "div",
1113
+ {
1114
+ role: "separator",
1115
+ "aria-orientation": vertical ? "vertical" : "horizontal",
1116
+ className: cx(CLS_DIVIDER, vertical && `${CLS_DIVIDER}--vertical`, className)
1117
+ }
1118
+ );
1119
+ }
1120
+ function ScrollArea({ children, className }) {
1121
+ usePanelPrimitives();
1122
+ return /* @__PURE__ */ jsx("div", { className: cx(CLS_SCROLL, className), children });
1123
+ }
1124
+
1125
+ // src/chrome/section.tsx
1126
+ import { useState as useState3 } from "react";
1127
+
1128
+ // src/chrome/controls.tsx
1129
+ import { useId } from "react";
1130
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1131
+ function SearchGlyph() {
1132
+ return /* @__PURE__ */ jsxs2(
1133
+ "svg",
1134
+ {
1135
+ width: "12",
1136
+ height: "12",
1137
+ viewBox: "0 0 24 24",
1138
+ fill: "none",
1139
+ stroke: "currentColor",
1140
+ strokeWidth: "1.5",
1141
+ strokeLinecap: "round",
1142
+ strokeLinejoin: "round",
1143
+ "aria-hidden": "true",
1144
+ children: [
1145
+ /* @__PURE__ */ jsx2("path", { d: "m21 21-4.34-4.34" }),
1146
+ /* @__PURE__ */ jsx2("path", { d: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16Z" })
1147
+ ]
1148
+ }
1149
+ );
1150
+ }
1151
+ function ClearGlyph() {
1152
+ return /* @__PURE__ */ jsxs2(
1153
+ "svg",
1154
+ {
1155
+ width: "12",
1156
+ height: "12",
1157
+ viewBox: "0 0 24 24",
1158
+ fill: "none",
1159
+ stroke: "currentColor",
1160
+ strokeWidth: "1.5",
1161
+ strokeLinecap: "round",
1162
+ strokeLinejoin: "round",
1163
+ "aria-hidden": "true",
1164
+ children: [
1165
+ /* @__PURE__ */ jsx2("path", { d: "M18 6 6 18" }),
1166
+ /* @__PURE__ */ jsx2("path", { d: "m6 6 12 12" })
1167
+ ]
1168
+ }
1169
+ );
1170
+ }
1171
+ function ChevronGlyph() {
1172
+ return /* @__PURE__ */ jsx2(
1173
+ "svg",
1174
+ {
1175
+ width: "10",
1176
+ height: "10",
1177
+ viewBox: "0 0 24 24",
1178
+ fill: "none",
1179
+ stroke: "currentColor",
1180
+ strokeWidth: "1.5",
1181
+ strokeLinecap: "round",
1182
+ strokeLinejoin: "round",
1183
+ "aria-hidden": "true",
1184
+ children: /* @__PURE__ */ jsx2("path", { d: "m9 18 6-6-6-6" })
1185
+ }
1186
+ );
1187
+ }
1188
+ function IconButton({
1189
+ icon,
1190
+ label,
1191
+ onClick,
1192
+ active,
1193
+ disabled,
1194
+ size = "md",
1195
+ className
1196
+ }) {
1197
+ usePanelPrimitives();
1198
+ return /* @__PURE__ */ jsx2(
1199
+ "button",
1200
+ {
1201
+ type: "button",
1202
+ title: label,
1203
+ "aria-label": label,
1204
+ "aria-pressed": active,
1205
+ disabled,
1206
+ onClick,
1207
+ className: iconButtonClass({ active, disabled }, cx(`${"xeno-iconbtn"}--${size}`, className)),
1208
+ children: icon
1209
+ }
1210
+ );
1211
+ }
1212
+ function TextButton({
1213
+ children,
1214
+ onClick,
1215
+ disabled,
1216
+ strong,
1217
+ className
1218
+ }) {
1219
+ usePanelPrimitives();
1220
+ return /* @__PURE__ */ jsx2(
1221
+ "button",
1222
+ {
1223
+ type: "button",
1224
+ disabled,
1225
+ onClick,
1226
+ className: cx(CLS_TEXT_BUTTON, strong && `${CLS_TEXT_BUTTON}--strong`, className),
1227
+ children
1228
+ }
1229
+ );
1230
+ }
1231
+ function SearchField({
1232
+ value,
1233
+ onChange,
1234
+ placeholder = "Search\u2026",
1235
+ label,
1236
+ onClear,
1237
+ disabled,
1238
+ autoFocus,
1239
+ className
1240
+ }) {
1241
+ usePanelPrimitives();
1242
+ const clear = () => onClear ? onClear() : onChange("");
1243
+ const handleKeyDown = (e) => {
1244
+ if (e.key === "Escape" && value !== "") {
1245
+ e.preventDefault();
1246
+ e.stopPropagation();
1247
+ clear();
1248
+ }
1249
+ };
1250
+ return /* @__PURE__ */ jsxs2("div", { className: cx(CLS_SEARCH, disabled && `${CLS_SEARCH}--disabled`, className), children: [
1251
+ /* @__PURE__ */ jsx2("span", { className: `${CLS_SEARCH}-glyph`, children: /* @__PURE__ */ jsx2(SearchGlyph, {}) }),
1252
+ /* @__PURE__ */ jsx2(
1253
+ "input",
1254
+ {
1255
+ type: "text",
1256
+ className: CLS_SEARCH_INPUT,
1257
+ value,
1258
+ placeholder,
1259
+ "aria-label": label ?? placeholder,
1260
+ disabled,
1261
+ autoFocus,
1262
+ spellCheck: false,
1263
+ autoComplete: "off",
1264
+ onChange: (e) => onChange(e.target.value),
1265
+ onKeyDown: handleKeyDown
1266
+ }
1267
+ ),
1268
+ value !== "" && !disabled ? /* @__PURE__ */ jsx2("button", { type: "button", className: `${CLS_SEARCH}-clear`, "aria-label": "Clear", onClick: clear, children: /* @__PURE__ */ jsx2(ClearGlyph, {}) }) : null
1269
+ ] });
1270
+ }
1271
+ function nextSegmentValue(options, value, delta) {
1272
+ const enabled = options.filter((o) => !o.disabled);
1273
+ if (enabled.length === 0) return value;
1274
+ const at = enabled.findIndex((o) => o.value === value);
1275
+ const from = at < 0 ? 0 : at;
1276
+ const index = ((from + delta) % enabled.length + enabled.length) % enabled.length;
1277
+ return enabled[index]?.value ?? value;
1278
+ }
1279
+ function SegmentedControl({
1280
+ options,
1281
+ value,
1282
+ onChange,
1283
+ label,
1284
+ size = "md",
1285
+ stretch,
1286
+ className
1287
+ }) {
1288
+ usePanelPrimitives();
1289
+ const move = (delta) => {
1290
+ const next = nextSegmentValue(options, value, delta);
1291
+ if (next !== value) onChange(next);
1292
+ };
1293
+ return /* @__PURE__ */ jsx2(
1294
+ "div",
1295
+ {
1296
+ role: "radiogroup",
1297
+ "aria-label": label,
1298
+ className: cx(
1299
+ CLS_SEGMENTED,
1300
+ `${CLS_SEGMENTED}--${size}`,
1301
+ stretch && `${CLS_SEGMENTED}--stretch`,
1302
+ className
1303
+ ),
1304
+ onKeyDown: (e) => {
1305
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") {
1306
+ e.preventDefault();
1307
+ move(1);
1308
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
1309
+ e.preventDefault();
1310
+ move(-1);
1311
+ }
1312
+ },
1313
+ children: options.map((o) => {
1314
+ const checked = o.value === value;
1315
+ return /* @__PURE__ */ jsx2(
1316
+ "button",
1317
+ {
1318
+ type: "button",
1319
+ role: "radio",
1320
+ "aria-checked": checked,
1321
+ title: o.title,
1322
+ "aria-label": o.title,
1323
+ disabled: o.disabled,
1324
+ tabIndex: checked ? 0 : -1,
1325
+ className: cx(CLS_SEGMENT, checked && `${CLS_SEGMENT}--checked`),
1326
+ onClick: () => {
1327
+ if (!checked) onChange(o.value);
1328
+ },
1329
+ children: o.label
1330
+ },
1331
+ o.value
1332
+ );
1333
+ })
1334
+ }
1335
+ );
1336
+ }
1337
+ function Toggle({
1338
+ checked,
1339
+ onChange,
1340
+ label,
1341
+ disabled,
1342
+ size = "md",
1343
+ className
1344
+ }) {
1345
+ usePanelPrimitives();
1346
+ return /* @__PURE__ */ jsx2(
1347
+ "button",
1348
+ {
1349
+ type: "button",
1350
+ role: "switch",
1351
+ "aria-checked": checked,
1352
+ "aria-label": label,
1353
+ title: label,
1354
+ disabled,
1355
+ onClick: () => onChange(!checked),
1356
+ className: cx(
1357
+ CLS_TOGGLE,
1358
+ `${CLS_TOGGLE}--${size}`,
1359
+ checked && `${CLS_TOGGLE}--on`,
1360
+ disabled && `${CLS_TOGGLE}--disabled`,
1361
+ className
1362
+ ),
1363
+ children: /* @__PURE__ */ jsx2("span", { className: CLS_TOGGLE_KNOB })
1364
+ }
1365
+ );
1366
+ }
1367
+ function FieldGroup({ children, labelWidth, className }) {
1368
+ usePanelPrimitives();
1369
+ return /* @__PURE__ */ jsx2(
1370
+ "div",
1371
+ {
1372
+ className: cx(CLS_FIELD_GROUP, className),
1373
+ style: labelWidth ? { "--xeno-field-label-w": `${labelWidth}px` } : void 0,
1374
+ children
1375
+ }
1376
+ );
1377
+ }
1378
+ function Field({
1379
+ label,
1380
+ children,
1381
+ hint,
1382
+ htmlFor,
1383
+ stacked,
1384
+ className
1385
+ }) {
1386
+ usePanelPrimitives();
1387
+ const fallbackId = useId();
1388
+ const hintId = hint != null ? `${fallbackId}-hint` : void 0;
1389
+ return /* @__PURE__ */ jsxs2("div", { className: cx(CLS_FIELD, stacked && `${CLS_FIELD}--stacked`, className), children: [
1390
+ /* @__PURE__ */ jsx2("label", { className: CLS_FIELD_LABEL, htmlFor, children: label }),
1391
+ /* @__PURE__ */ jsx2("div", { className: CLS_FIELD_CONTROL, "aria-describedby": hintId, children }),
1392
+ hint != null ? /* @__PURE__ */ jsx2("div", { className: CLS_FIELD_HINT, id: hintId, children: hint }) : null
1393
+ ] });
1394
+ }
1395
+
1396
+ // src/chrome/section.tsx
1397
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1398
+ function Section({
1399
+ title,
1400
+ children,
1401
+ badge,
1402
+ actions,
1403
+ collapsible = true,
1404
+ collapsed,
1405
+ defaultCollapsed = false,
1406
+ onCollapsedChange,
1407
+ enabled,
1408
+ onEnabledChange,
1409
+ flush,
1410
+ className,
1411
+ bodyClassName
1412
+ }) {
1413
+ usePanelPrimitives();
1414
+ const [uncontrolled, setUncontrolled] = useState3(defaultCollapsed);
1415
+ const isCollapsed = collapsible ? collapsed ?? uncontrolled : false;
1416
+ const toggleCollapsed = () => {
1417
+ if (!collapsible) return;
1418
+ const next = !isCollapsed;
1419
+ if (collapsed === void 0) setUncontrolled(next);
1420
+ onCollapsedChange?.(next);
1421
+ };
1422
+ const off = enabled === false;
1423
+ return /* @__PURE__ */ jsxs3("div", { className: sectionClass(isCollapsed, className), children: [
1424
+ /* @__PURE__ */ jsxs3("div", { className: CLS_SECTION_HEADER, children: [
1425
+ collapsible ? /* @__PURE__ */ jsxs3(
1426
+ "button",
1427
+ {
1428
+ type: "button",
1429
+ className: CLS_SECTION_TRIGGER,
1430
+ "aria-expanded": !isCollapsed,
1431
+ onClick: toggleCollapsed,
1432
+ children: [
1433
+ /* @__PURE__ */ jsx3("span", { className: CLS_SECTION_CHEVRON, children: /* @__PURE__ */ jsx3(ChevronGlyph, {}) }),
1434
+ /* @__PURE__ */ jsx3("span", { className: CLS_SECTION_TITLE, children: title })
1435
+ ]
1436
+ }
1437
+ ) : (
1438
+ // A non-collapsible header is not a DISABLED button — it is not a button at all. A
1439
+ // disabled control in the header would advertise an affordance that does not exist.
1440
+ /* @__PURE__ */ jsx3("div", { className: CLS_SECTION_TRIGGER, children: /* @__PURE__ */ jsx3("span", { className: CLS_SECTION_TITLE, children: title }) })
1441
+ ),
1442
+ badge != null || actions != null || enabled !== void 0 ? /* @__PURE__ */ jsxs3("div", { className: CLS_SECTION_ACTIONS, children: [
1443
+ badge,
1444
+ actions,
1445
+ enabled !== void 0 ? /* @__PURE__ */ jsx3(
1446
+ Toggle,
1447
+ {
1448
+ size: "sm",
1449
+ checked: enabled,
1450
+ onChange: (next) => onEnabledChange?.(next),
1451
+ label: typeof title === "string" ? `Enable ${title}` : "Enable section"
1452
+ }
1453
+ ) : null
1454
+ ] }) : null
1455
+ ] }),
1456
+ /* @__PURE__ */ jsx3(
1457
+ "div",
1458
+ {
1459
+ className: cx(
1460
+ CLS_SECTION_BODY,
1461
+ off && `${CLS_SECTION_BODY}--off`,
1462
+ flush && `${CLS_SECTION_BODY}--flush`,
1463
+ bodyClassName
1464
+ ),
1465
+ "aria-hidden": isCollapsed || void 0,
1466
+ children
1467
+ }
1468
+ )
1469
+ ] });
1470
+ }
1471
+
1472
+ // src/chrome/rows.tsx
1473
+ import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1474
+ function RowList({
1475
+ children,
1476
+ divided = false,
1477
+ role = "list",
1478
+ className,
1479
+ ...rest
1480
+ }) {
1481
+ usePanelPrimitives();
1482
+ return /* @__PURE__ */ jsx4(
1483
+ "div",
1484
+ {
1485
+ role,
1486
+ className: cx(CLS_ROWLIST, divided && `${CLS_ROWLIST}--divided`, className),
1487
+ ...rest,
1488
+ children
1489
+ }
1490
+ );
1491
+ }
1492
+ function Row({
1493
+ icon,
1494
+ label,
1495
+ meta,
1496
+ trailing,
1497
+ children,
1498
+ depth = 0,
1499
+ selected,
1500
+ active,
1501
+ disabled,
1502
+ noIcon,
1503
+ role,
1504
+ className,
1505
+ style,
1506
+ onClick,
1507
+ onKeyDown,
1508
+ ...rest
1509
+ }) {
1510
+ usePanelPrimitives();
1511
+ const interactive = onClick != null && !disabled;
1512
+ const handleKeyDown = (e) => {
1513
+ onKeyDown?.(e);
1514
+ if (!interactive || e.defaultPrevented) return;
1515
+ if (e.key === "Enter" || e.key === " ") {
1516
+ e.preventDefault();
1517
+ onClick?.(e);
1518
+ }
1519
+ };
1520
+ return /* @__PURE__ */ jsxs4(
1521
+ "div",
1522
+ {
1523
+ role: role ?? (selected !== void 0 ? "option" : "listitem"),
1524
+ "aria-selected": selected,
1525
+ "aria-disabled": disabled || void 0,
1526
+ tabIndex: interactive ? 0 : void 0,
1527
+ className: rowClass({ selected, active, disabled, interactive }, className),
1528
+ style: depth > 0 ? { paddingLeft: depth * PANEL_METRICS.rowIndent, ...style } : style,
1529
+ onClick: disabled ? void 0 : onClick,
1530
+ onKeyDown: handleKeyDown,
1531
+ ...rest,
1532
+ children: [
1533
+ noIcon ? null : /* @__PURE__ */ jsx4("span", { className: CLS_ROW_ICON, children: icon }),
1534
+ children ?? /* @__PURE__ */ jsxs4(Fragment, { children: [
1535
+ /* @__PURE__ */ jsx4("span", { className: CLS_ROW_LABEL, children: label }),
1536
+ meta != null ? /* @__PURE__ */ jsx4("span", { className: CLS_ROW_META, children: meta }) : null
1537
+ ] }),
1538
+ trailing != null ? /* @__PURE__ */ jsx4("span", { className: CLS_ROW_TRAILING, children: trailing }) : null
1539
+ ]
1540
+ }
1541
+ );
1542
+ }
1543
+
1544
+ // src/chrome/states.tsx
1545
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1546
+ function EmptyState({ title, hint, icon, action, className }) {
1547
+ usePanelPrimitives();
1548
+ return /* @__PURE__ */ jsxs5("div", { className: cx(CLS_STATE, CLS_EMPTY, className), children: [
1549
+ icon != null ? /* @__PURE__ */ jsx5("span", { className: CLS_STATE_ICON, children: icon }) : null,
1550
+ /* @__PURE__ */ jsx5("div", { className: CLS_STATE_TITLE, children: title }),
1551
+ hint != null ? /* @__PURE__ */ jsx5("div", { className: CLS_STATE_HINT, children: hint }) : null,
1552
+ action
1553
+ ] });
1554
+ }
1555
+ function LoadingState({ label = "Loading\u2026", className }) {
1556
+ usePanelPrimitives();
1557
+ return /* @__PURE__ */ jsxs5("div", { className: cx(CLS_STATE, CLS_LOADING, className), role: "status", "aria-busy": "true", children: [
1558
+ /* @__PURE__ */ jsx5("div", { className: CLS_STATE_PROGRESS }),
1559
+ /* @__PURE__ */ jsx5("div", { className: CLS_STATE_TITLE, children: label })
1560
+ ] });
1561
+ }
1562
+ function ErrorState({
1563
+ title = "Something went wrong",
1564
+ message,
1565
+ onRetry,
1566
+ retryLabel = "Retry",
1567
+ className
1568
+ }) {
1569
+ usePanelPrimitives();
1570
+ return /* @__PURE__ */ jsxs5("div", { className: cx(CLS_STATE, CLS_ERROR, className), role: "alert", children: [
1571
+ /* @__PURE__ */ jsx5("div", { className: CLS_STATE_TITLE, children: title }),
1572
+ message != null ? /* @__PURE__ */ jsx5("div", { className: CLS_STATE_HINT, children: message }) : null,
1573
+ onRetry ? /* @__PURE__ */ jsx5(TextButton, { onClick: onRetry, children: retryLabel }) : null
1574
+ ] });
1575
+ }
1576
+
1577
+ // src/chrome/indicators.tsx
1578
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1579
+ function Badge({
1580
+ children,
1581
+ tone = "neutral",
1582
+ size = "sm",
1583
+ title,
1584
+ className
1585
+ }) {
1586
+ usePanelPrimitives();
1587
+ return /* @__PURE__ */ jsx6("span", { title, className: badgeClass(tone, cx(size === "md" && "xeno-badge--md", className)), children });
1588
+ }
1589
+ function StatusDot({ tone = "neutral", label, className }) {
1590
+ usePanelPrimitives();
1591
+ return /* @__PURE__ */ jsx6(
1592
+ "span",
1593
+ {
1594
+ className: dotClass(tone, className),
1595
+ role: label ? "img" : void 0,
1596
+ "aria-label": label,
1597
+ "aria-hidden": label ? void 0 : true
1598
+ }
1599
+ );
1600
+ }
1601
+ function StatusBadge({ children, tone = "neutral", className }) {
1602
+ usePanelPrimitives();
1603
+ return /* @__PURE__ */ jsxs6("span", { className: badgeClass(tone, className), children: [
1604
+ /* @__PURE__ */ jsx6(StatusDot, { tone }),
1605
+ children
1606
+ ] });
1607
+ }
1608
+ function IconFrame({ icon, size = 20, className }) {
1609
+ usePanelPrimitives();
1610
+ return /* @__PURE__ */ jsx6("span", { className: cx(CLS_ICON_FRAME, className), style: { width: size, height: size }, children: icon });
1611
+ }
1612
+ function StatTile({ label, value, sub, icon, title, className }) {
1613
+ usePanelPrimitives();
1614
+ return /* @__PURE__ */ jsxs6("div", { className: cx(CLS_STAT, className), title, children: [
1615
+ /* @__PURE__ */ jsxs6("div", { className: CLS_STAT_LABEL, children: [
1616
+ /* @__PURE__ */ jsx6("span", { children: label }),
1617
+ icon
1618
+ ] }),
1619
+ /* @__PURE__ */ jsx6("div", { className: CLS_STAT_VALUE, children: value }),
1620
+ sub != null ? /* @__PURE__ */ jsx6("div", { className: CLS_STAT_SUB, children: sub }) : null
1621
+ ] });
1622
+ }
1623
+ function ProportionBar({ segments, label, className }) {
1624
+ usePanelPrimitives();
1625
+ const usable = segments.filter((s) => s.value > 0);
1626
+ const total = usable.reduce((sum, s) => sum + s.value, 0);
1627
+ if (total <= 0) return /* @__PURE__ */ jsx6("div", { className: cx(CLS_BAR, className), role: "img", "aria-label": label });
1628
+ const span = Math.max(1, usable.length - 1);
1629
+ return /* @__PURE__ */ jsx6("div", { className: cx(CLS_BAR, className), role: "img", "aria-label": label, children: usable.map((s, i) => /* @__PURE__ */ jsx6(
1630
+ "span",
1631
+ {
1632
+ className: CLS_BAR_SEGMENT,
1633
+ title: s.label,
1634
+ style: {
1635
+ width: `${s.value / total * 100}%`,
1636
+ background: `rgba(255,255,255,${s.opacity ?? 0.45 - i / span * 0.33})`
1637
+ }
1638
+ },
1639
+ s.key ?? i
1640
+ )) });
1641
+ }
1642
+ function StatusBar({ left, right, children, className }) {
1643
+ usePanelPrimitives();
1644
+ return /* @__PURE__ */ jsx6("div", { className: cx(CLS_STATUSBAR, className), children: children ?? /* @__PURE__ */ jsxs6(Fragment2, { children: [
1645
+ /* @__PURE__ */ jsx6("span", { children: left }),
1646
+ /* @__PURE__ */ jsx6("span", { children: right })
1647
+ ] }) });
1648
+ }
1649
+ function Sparkline({
1650
+ data,
1651
+ width = 56,
1652
+ height = 14,
1653
+ label,
1654
+ title,
1655
+ className
1656
+ }) {
1657
+ usePanelPrimitives();
1658
+ const points = data.filter((n) => Number.isFinite(n));
1659
+ if (points.length < 2) {
1660
+ return /* @__PURE__ */ jsx6(
1661
+ "span",
1662
+ {
1663
+ className: cx(CLS_BAR, className),
1664
+ style: { width, height, background: "rgba(255,255,255,0.04)" },
1665
+ title,
1666
+ "aria-hidden": "true"
1667
+ }
1668
+ );
1669
+ }
1670
+ const max = Math.max(...points);
1671
+ const min = Math.min(...points);
1672
+ const range = max - min || 1;
1673
+ const path = points.map((v, i) => {
1674
+ const x = i / (points.length - 1) * width;
1675
+ const y = height - (v - min) / range * (height - 2) - 1;
1676
+ return `${x.toFixed(2)},${y.toFixed(2)}`;
1677
+ }).join(" ");
1678
+ return /* @__PURE__ */ jsxs6(
1679
+ "svg",
1680
+ {
1681
+ width,
1682
+ height,
1683
+ className,
1684
+ role: label ? "img" : void 0,
1685
+ "aria-label": label,
1686
+ "aria-hidden": label ? void 0 : true,
1687
+ style: { flex: "0 0 auto", overflow: "visible" },
1688
+ children: [
1689
+ title ? /* @__PURE__ */ jsx6("title", { children: title }) : null,
1690
+ /* @__PURE__ */ jsx6(
1691
+ "polyline",
1692
+ {
1693
+ points: path,
1694
+ fill: "none",
1695
+ stroke: "rgba(255,255,255,0.5)",
1696
+ strokeWidth: 1.5,
1697
+ strokeLinejoin: "round",
1698
+ strokeLinecap: "round"
1699
+ }
1700
+ )
1701
+ ]
1702
+ }
1703
+ );
1704
+ }
1705
+
1706
+ // src/chrome/components.ts
1707
+ var COMPONENTS = {
1708
+ "chrome/IconButton": IconButton,
1709
+ "chrome/TextButton": TextButton,
1710
+ "chrome/SearchField": SearchField,
1711
+ "chrome/SegmentedControl": SegmentedControl,
1712
+ "chrome/Toggle": Toggle,
1713
+ "chrome/FieldGroup": FieldGroup,
1714
+ "chrome/Field": Field,
1715
+ "chrome/SearchGlyph": SearchGlyph,
1716
+ "chrome/ClearGlyph": ClearGlyph,
1717
+ "chrome/ChevronGlyph": ChevronGlyph,
1718
+ "chrome/PanelFrame": PanelFrame,
1719
+ "chrome/Toolbar": Toolbar,
1720
+ "chrome/ToolbarGroup": ToolbarGroup,
1721
+ "chrome/Divider": Divider,
1722
+ "chrome/ScrollArea": ScrollArea,
1723
+ "chrome/Badge": Badge,
1724
+ "chrome/StatusDot": StatusDot,
1725
+ "chrome/StatusBadge": StatusBadge,
1726
+ "chrome/IconFrame": IconFrame,
1727
+ "chrome/StatTile": StatTile,
1728
+ "chrome/ProportionBar": ProportionBar,
1729
+ "chrome/StatusBar": StatusBar,
1730
+ "chrome/Sparkline": Sparkline,
1731
+ "chrome/RowList": RowList,
1732
+ "chrome/Row": Row,
1733
+ "chrome/Section": Section,
1734
+ "chrome/EmptyState": EmptyState,
1735
+ "chrome/LoadingState": LoadingState,
1736
+ "chrome/ErrorState": ErrorState
1737
+ };
1738
+
1739
+ // src/chrome/gallery.tsx
1740
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1741
+ var noop = () => void 0;
1742
+ var TONES = ["neutral", "info", "success", "warning", "error"];
1743
+ var SEGMENTS = [{ value: "all", label: "All" }, { value: "errors", label: "Errors" }, { value: "warnings", label: "Warnings" }];
1744
+ function gallery() {
1745
+ const out = [];
1746
+ const form = (unit, state, render) => {
1747
+ out.push({ family: "chrome", unit, state, stage: "form", render });
1748
+ };
1749
+ const door = (unit, state, render) => {
1750
+ out.push({ family: "chrome", unit, state, stage: "door", render });
1751
+ };
1752
+ form("IconButton", "default", () => /* @__PURE__ */ jsx7(IconButton, { icon: /* @__PURE__ */ jsx7(SearchGlyph, {}), label: "Search", onClick: noop }));
1753
+ form("IconButton", "active", () => /* @__PURE__ */ jsx7(IconButton, { icon: /* @__PURE__ */ jsx7(SearchGlyph, {}), label: "Search", onClick: noop, active: true }));
1754
+ form("TextButton", "default", () => /* @__PURE__ */ jsx7(TextButton, { onClick: noop, children: "Clear all" }));
1755
+ form("TextButton", "disabled", () => /* @__PURE__ */ jsx7(TextButton, { onClick: noop, disabled: true, children: "Clear all" }));
1756
+ form("SearchField", "empty", () => /* @__PURE__ */ jsx7(SearchField, { value: "", onChange: noop, placeholder: "Filter rows\u2026", label: "Filter" }));
1757
+ form("SearchField", "filled", () => /* @__PURE__ */ jsx7(SearchField, { value: "render", onChange: noop, placeholder: "Filter rows\u2026", label: "Filter" }));
1758
+ form("SegmentedControl", "first", () => /* @__PURE__ */ jsx7(SegmentedControl, { options: SEGMENTS, value: "all", onChange: noop, label: "Level" }));
1759
+ form("SegmentedControl", "last", () => /* @__PURE__ */ jsx7(SegmentedControl, { options: SEGMENTS, value: "warnings", onChange: noop, label: "Level" }));
1760
+ form("Toggle", "off", () => /* @__PURE__ */ jsx7(Toggle, { checked: false, onChange: noop, label: "Follow output" }));
1761
+ form("Toggle", "on", () => /* @__PURE__ */ jsx7(Toggle, { checked: true, onChange: noop, label: "Follow output" }));
1762
+ form("Toggle", "disabled-on", () => /* @__PURE__ */ jsx7(Toggle, { checked: true, onChange: noop, label: "Follow output", disabled: true }));
1763
+ form("Field", "default", () => /* @__PURE__ */ jsx7(Field, { label: "Name", htmlFor: "chrome-field-name", children: /* @__PURE__ */ jsx7("input", { id: "chrome-field-name", defaultValue: "Untitled" }) }));
1764
+ form("Field", "hint", () => /* @__PURE__ */ jsx7(Field, { label: "Timeout", hint: "Milliseconds; 0 never times out.", htmlFor: "chrome-field-timeout", children: /* @__PURE__ */ jsx7("input", { id: "chrome-field-timeout", defaultValue: "30000" }) }));
1765
+ form("FieldGroup", "default", () => /* @__PURE__ */ jsxs7(FieldGroup, { labelWidth: 96, children: [
1766
+ /* @__PURE__ */ jsx7(Field, { label: "Name", htmlFor: "chrome-fg-name", children: /* @__PURE__ */ jsx7("input", { id: "chrome-fg-name", defaultValue: "Untitled" }) }),
1767
+ /* @__PURE__ */ jsx7(Field, { label: "Kind", htmlFor: "chrome-fg-kind", children: /* @__PURE__ */ jsx7("input", { id: "chrome-fg-kind", defaultValue: "frame" }) })
1768
+ ] }));
1769
+ form("SearchGlyph", "default", () => /* @__PURE__ */ jsx7(SearchGlyph, {}));
1770
+ form("ClearGlyph", "default", () => /* @__PURE__ */ jsx7(ClearGlyph, {}));
1771
+ form("ChevronGlyph", "default", () => /* @__PURE__ */ jsx7(ChevronGlyph, {}));
1772
+ door("PanelFrame", "header", () => /* @__PURE__ */ jsx7(PanelFrame, { title: "Console", actions: /* @__PURE__ */ jsx7(IconButton, { icon: /* @__PURE__ */ jsx7(ClearGlyph, {}), label: "Clear", onClick: noop }), children: /* @__PURE__ */ jsx7("p", { style: { padding: 8 }, children: "Body" }) }));
1773
+ door("PanelFrame", "headless", () => /* @__PURE__ */ jsx7(PanelFrame, { showHeader: false, children: /* @__PURE__ */ jsx7("p", { style: { padding: 8 }, children: "Body" }) }));
1774
+ form("Toolbar", "default", () => /* @__PURE__ */ jsx7(Toolbar, { left: /* @__PURE__ */ jsx7(SegmentedControl, { options: SEGMENTS, value: "all", onChange: noop, label: "Level" }), right: /* @__PURE__ */ jsx7(IconButton, { icon: /* @__PURE__ */ jsx7(ClearGlyph, {}), label: "Clear", onClick: noop }) }));
1775
+ form("ToolbarGroup", "end", () => /* @__PURE__ */ jsx7(Toolbar, { children: /* @__PURE__ */ jsxs7(ToolbarGroup, { end: true, children: [
1776
+ /* @__PURE__ */ jsx7(TextButton, { onClick: noop, children: "Copy" }),
1777
+ /* @__PURE__ */ jsx7(IconButton, { icon: /* @__PURE__ */ jsx7(ClearGlyph, {}), label: "Clear", onClick: noop })
1778
+ ] }) }));
1779
+ form("Divider", "horizontal", () => /* @__PURE__ */ jsx7(Divider, {}));
1780
+ form("Divider", "vertical", () => /* @__PURE__ */ jsxs7("div", { style: { height: 24, display: "flex" }, children: [
1781
+ /* @__PURE__ */ jsx7("span", { children: "a" }),
1782
+ /* @__PURE__ */ jsx7(Divider, { vertical: true }),
1783
+ /* @__PURE__ */ jsx7("span", { children: "b" })
1784
+ ] }));
1785
+ door("ScrollArea", "default", () => /* @__PURE__ */ jsx7(ScrollArea, { children: Array.from({ length: 30 }, (_, i) => /* @__PURE__ */ jsxs7("p", { style: { margin: 4 }, children: [
1786
+ "line ",
1787
+ i + 1
1788
+ ] }, i)) }));
1789
+ form("RowList", "divided", () => /* @__PURE__ */ jsxs7(RowList, { divided: true, children: [
1790
+ /* @__PURE__ */ jsx7(Row, { label: "Background", meta: "raster" }),
1791
+ /* @__PURE__ */ jsx7(Row, { label: "Title", meta: "text", selected: true }),
1792
+ /* @__PURE__ */ jsx7(Row, { label: "Logo", meta: "vector" })
1793
+ ] }));
1794
+ form("Row", "default", () => /* @__PURE__ */ jsx7(Row, { icon: /* @__PURE__ */ jsx7(IconFrame, { icon: /* @__PURE__ */ jsx7(SearchGlyph, {}) }), label: "Layer", meta: "raster", trailing: /* @__PURE__ */ jsx7(Badge, { children: "3" }) }));
1795
+ form("Row", "selected", () => /* @__PURE__ */ jsx7(Row, { label: "Layer", meta: "raster", selected: true }));
1796
+ form("Row", "disabled", () => /* @__PURE__ */ jsx7(Row, { label: "Layer", meta: "raster", disabled: true }));
1797
+ form("Section", "default", () => /* @__PURE__ */ jsx7(Section, { title: "Fill", children: /* @__PURE__ */ jsx7("p", { style: { margin: 0 }, children: "Solid \xB7 white" }) }));
1798
+ form("Section", "badge-actions", () => /* @__PURE__ */ jsx7(Section, { title: "Effects", badge: /* @__PURE__ */ jsx7(Badge, { children: "2" }), actions: /* @__PURE__ */ jsx7(TextButton, { onClick: noop, children: "Add" }), children: /* @__PURE__ */ jsx7("p", { style: { margin: 0 }, children: "Drop shadow" }) }));
1799
+ door("EmptyState", "default", () => /* @__PURE__ */ jsx7(EmptyState, { title: "No runs yet", hint: "Trigger a workflow and its runs appear here." }));
1800
+ door("EmptyState", "title-only", () => /* @__PURE__ */ jsx7(EmptyState, { title: "Nothing selected" }));
1801
+ door("LoadingState", "default", () => /* @__PURE__ */ jsx7(LoadingState, { label: "Loading rows\u2026" }));
1802
+ door("ErrorState", "default", () => /* @__PURE__ */ jsx7(ErrorState, { title: "Couldn't load", message: "The source refused the request.", onRetry: noop }));
1803
+ door("ErrorState", "no-retry", () => /* @__PURE__ */ jsx7(ErrorState, { message: "Read-only source." }));
1804
+ for (const tone of TONES) form("Badge", tone, () => /* @__PURE__ */ jsx7(Badge, { tone, children: tone }));
1805
+ form("Badge", "sm", () => /* @__PURE__ */ jsx7(Badge, { size: "sm", children: "12" }));
1806
+ for (const tone of TONES) form("StatusDot", tone, () => /* @__PURE__ */ jsx7(StatusDot, { tone, label: tone }));
1807
+ for (const tone of TONES) form("StatusBadge", tone, () => /* @__PURE__ */ jsx7(StatusBadge, { tone, children: tone }));
1808
+ form("IconFrame", "default", () => /* @__PURE__ */ jsx7(IconFrame, { icon: /* @__PURE__ */ jsx7(SearchGlyph, {}) }));
1809
+ form("IconFrame", "large", () => /* @__PURE__ */ jsx7(IconFrame, { icon: /* @__PURE__ */ jsx7(SearchGlyph, {}), size: 32 }));
1810
+ form("StatTile", "default", () => /* @__PURE__ */ jsx7(StatTile, { label: "Requests", value: "1,204", sub: "last hour", icon: /* @__PURE__ */ jsx7(SearchGlyph, {}) }));
1811
+ form("ProportionBar", "default", () => /* @__PURE__ */ jsx7(ProportionBar, { label: "Storage", segments: [{ value: 3, opacity: 0.9 }, { value: 2, opacity: 0.5 }, { value: 1, opacity: 0.25 }] }));
1812
+ form("StatusBar", "default", () => /* @__PURE__ */ jsx7(StatusBar, { left: /* @__PURE__ */ jsx7(StatusDot, { tone: "success", label: "connected" }), right: /* @__PURE__ */ jsx7("span", { children: "12 rows" }) }));
1813
+ form("Sparkline", "default", () => /* @__PURE__ */ jsx7(Sparkline, { data: [1, 3, 2, 5, 4, 6, 3, 7], label: "Throughput" }));
1814
+ form("Sparkline", "flat", () => /* @__PURE__ */ jsx7(Sparkline, { data: [2, 2, 2, 2], label: "Idle" }));
1815
+ return out;
1816
+ }
1817
+ export {
1818
+ Badge,
1819
+ CLS_BADGE,
1820
+ CLS_BAR,
1821
+ CLS_BAR_SEGMENT,
1822
+ CLS_DIVIDER,
1823
+ CLS_DOT,
1824
+ CLS_EMPTY,
1825
+ CLS_ERROR,
1826
+ CLS_FIELD,
1827
+ CLS_FIELD_CONTROL,
1828
+ CLS_FIELD_GROUP,
1829
+ CLS_FIELD_HINT,
1830
+ CLS_FIELD_LABEL,
1831
+ CLS_ICON_BUTTON,
1832
+ CLS_ICON_FRAME,
1833
+ CLS_LOADING,
1834
+ CLS_PANEL,
1835
+ CLS_PANEL_CONTENT,
1836
+ CLS_PANEL_CONTENT_NO_HEADER,
1837
+ CLS_PANEL_HEADER,
1838
+ CLS_PANEL_TITLE,
1839
+ CLS_ROW,
1840
+ CLS_ROWLIST,
1841
+ CLS_ROW_ICON,
1842
+ CLS_ROW_LABEL,
1843
+ CLS_ROW_META,
1844
+ CLS_ROW_TRAILING,
1845
+ CLS_SCROLL,
1846
+ CLS_SEARCH,
1847
+ CLS_SEARCH_INPUT,
1848
+ CLS_SECTION,
1849
+ CLS_SECTION_ACTIONS,
1850
+ CLS_SECTION_BODY,
1851
+ CLS_SECTION_CHEVRON,
1852
+ CLS_SECTION_HEADER,
1853
+ CLS_SECTION_TITLE,
1854
+ CLS_SECTION_TRIGGER,
1855
+ CLS_SEGMENT,
1856
+ CLS_SEGMENTED,
1857
+ CLS_STAT,
1858
+ CLS_STATE,
1859
+ CLS_STATE_HINT,
1860
+ CLS_STATE_ICON,
1861
+ CLS_STATE_PROGRESS,
1862
+ CLS_STATE_TITLE,
1863
+ CLS_STATUSBAR,
1864
+ CLS_STAT_LABEL,
1865
+ CLS_STAT_SUB,
1866
+ CLS_STAT_VALUE,
1867
+ CLS_TEXT_BUTTON,
1868
+ CLS_TOGGLE,
1869
+ CLS_TOGGLE_KNOB,
1870
+ CLS_TOOLBAR,
1871
+ CLS_TOOLBAR_GROUP,
1872
+ COMPONENTS,
1873
+ ChevronGlyph,
1874
+ ClearGlyph,
1875
+ Divider,
1876
+ EmptyState,
1877
+ ErrorState,
1878
+ Field,
1879
+ FieldGroup,
1880
+ IconButton,
1881
+ IconFrame,
1882
+ LoadingState,
1883
+ PANEL_COLORS,
1884
+ PANEL_DISABLED_OPACITY,
1885
+ PANEL_METRICS,
1886
+ PANEL_PRIMITIVES_CSS,
1887
+ PANEL_PRIMITIVES_STYLE_ID,
1888
+ PANEL_TONES,
1889
+ PanelFrame,
1890
+ ProportionBar,
1891
+ Row,
1892
+ RowList,
1893
+ ScrollArea,
1894
+ SearchField,
1895
+ SearchGlyph,
1896
+ Section,
1897
+ SegmentedControl,
1898
+ Sparkline,
1899
+ StatTile,
1900
+ StatusBadge,
1901
+ StatusBar,
1902
+ StatusDot,
1903
+ TextButton,
1904
+ Toggle,
1905
+ Toolbar,
1906
+ ToolbarGroup,
1907
+ badgeClass,
1908
+ cx,
1909
+ dotClass,
1910
+ ensurePanelPrimitivesInjected,
1911
+ gallery,
1912
+ iconButtonClass,
1913
+ nextSegmentValue,
1914
+ rowClass,
1915
+ sectionClass,
1916
+ usePanelPrimitives
1917
+ };