@protolabsai/ui 0.18.0 → 0.19.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,2763 @@
1
+ /* @protolabsai/ui — plugin-kit.css (GENERATED by scripts/build-plugin-kit.mjs — do not edit by hand).
2
+ * The no-build DS bundle for protoAgent plugin iframe pages: --pl-* tokens + base + every .pl-* component,
3
+ * flattened to one file with no @import. Link it, then apply the ADR 0026 handshake (plugin-kit.js) so the
4
+ * console's theme drives :root. Regenerate: pnpm --filter @protolabsai/ui build:plugin-kit */
5
+
6
+ /* ── design tokens (--pl-* :root defaults) ─────────────────────────────────── */
7
+ /* GENERATED from src/tokens.js by scripts/build.mjs — do not edit by hand. */
8
+ :root {
9
+ color-scheme: dark;
10
+ --pl-color-brand-lavender: #9b87f2;
11
+ --pl-color-brand-lavender-light: #b8a6f5;
12
+ --pl-color-brand-lavender-deep: #5b3fc9;
13
+ --pl-color-brand-indigo: #6366f1;
14
+ --pl-color-brand-indigo-bright: #818cf8;
15
+ --pl-color-brand-indigo-deep: #4f46e5;
16
+ --pl-color-bg: #0a0a0c;
17
+ --pl-color-bg-raised: #131316;
18
+ --pl-color-bg-subtle: #1c1c22;
19
+ --pl-color-bg-hover: #19191d;
20
+ --pl-color-bg-inset: #060608;
21
+ --pl-color-overlay: rgba(0, 0, 0, 0.6);
22
+ --pl-color-fg: #ededed;
23
+ --pl-color-fg-muted: #a1a1aa;
24
+ --pl-color-fg-subtle: #71717a;
25
+ --pl-color-fg-on-accent: #0a0a0c;
26
+ --pl-color-border: rgba(255, 255, 255, 0.08);
27
+ --pl-color-border-strong: rgba(255, 255, 255, 0.18);
28
+ --pl-color-accent: #9b87f2;
29
+ --pl-color-accent-hover: #b8a6f5;
30
+ --pl-color-accent-fg: #b8a6f5;
31
+ --pl-color-focus: #9b87f2;
32
+ --pl-color-status-success: oklch(0.72 0.13 145);
33
+ --pl-color-status-warning: oklch(0.78 0.12 75);
34
+ --pl-color-status-error: oklch(0.64 0.16 25);
35
+ --pl-color-status-info: oklch(0.68 0.12 230);
36
+ --pl-gradient-brand: linear-gradient(135deg, #9b87f2 0%, #818cf8 50%, #6366f1 100%);
37
+ --pl-gradient-brand-light: linear-gradient(135deg, #7355e8 0%, #6366f1 50%, #4f46e5 100%);
38
+ --pl-shadow-glow: 0 0 80px rgba(155, 135, 242, 0.08);
39
+ --pl-shadow-popover: 0 8px 28px rgba(0, 0, 0, 0.5);
40
+ --pl-font-sans: "Geist", system-ui, -apple-system, sans-serif;
41
+ --pl-font-mono: "Geist Mono", ui-monospace, "SF Mono", monospace;
42
+ --pl-font-base-size: 14px;
43
+ --pl-font-line-height-body: 1.6;
44
+ --pl-font-line-height-heading: 1.2;
45
+ --pl-font-weight-body: 440;
46
+ --pl-font-weight-medium: 500;
47
+ --pl-radius: 4px;
48
+ --pl-space-1: 4px;
49
+ --pl-space-2: 8px;
50
+ --pl-space-3: 12px;
51
+ --pl-space-4: 16px;
52
+ --pl-space-6: 24px;
53
+ --pl-space-8: 32px;
54
+ --pl-space-12: 48px;
55
+ --pl-border-width: 1px;
56
+ --pl-motion-fast: 120ms;
57
+ --pl-motion-base: 200ms;
58
+ --pl-motion-theme: 400ms;
59
+ --pl-motion-loading: 1000ms;
60
+ --pl-motion-status: 2000ms;
61
+ --pl-motion-ease: ease;
62
+ --pl-motion-ease-in-out: ease-in-out;
63
+ --pl-motion-linear: linear;
64
+ }
65
+
66
+ /* Light mode — the user's OS preference drives it. Apps inherit automatically;
67
+ * marketing pins dark with [data-theme="dark"] below (attribute selectors beat
68
+ * this media block on specificity). */
69
+ @media (prefers-color-scheme: light) {
70
+ :root {
71
+ color-scheme: light;
72
+ --pl-color-bg: #f6f7f9;
73
+ --pl-color-bg-raised: #ffffff;
74
+ --pl-color-bg-subtle: #eceef2;
75
+ --pl-color-bg-hover: #e4e7ec;
76
+ --pl-color-bg-inset: #eef0f4;
77
+ --pl-color-overlay: rgba(20, 20, 30, 0.35);
78
+ --pl-color-fg: #18181b;
79
+ --pl-color-fg-muted: #52525b;
80
+ --pl-color-fg-subtle: #8a8a94;
81
+ --pl-color-fg-on-accent: #ffffff;
82
+ --pl-color-border: rgba(0, 0, 0, 0.10);
83
+ --pl-color-border-strong: rgba(0, 0, 0, 0.20);
84
+ --pl-color-accent: #6366f1;
85
+ --pl-color-accent-hover: #4f46e5;
86
+ --pl-color-accent-fg: #4f46e5;
87
+ --pl-color-focus: #6366f1;
88
+ --pl-color-status-success: oklch(0.62 0.15 150);
89
+ --pl-color-status-warning: oklch(0.74 0.16 92);
90
+ --pl-color-status-error: oklch(0.58 0.20 25);
91
+ --pl-color-status-info: oklch(0.58 0.17 255);
92
+ --pl-gradient-brand: linear-gradient(135deg, #7355e8 0%, #6366f1 50%, #4f46e5 100%);
93
+ --pl-shadow-popover: 0 8px 24px rgba(0, 0, 0, 0.12);
94
+ }
95
+ }
96
+
97
+ /* Explicit theme force — wins over the OS preference above. */
98
+ :root[data-theme="light"] {
99
+ color-scheme: light;
100
+ --pl-color-bg: #f6f7f9;
101
+ --pl-color-bg-raised: #ffffff;
102
+ --pl-color-bg-subtle: #eceef2;
103
+ --pl-color-bg-hover: #e4e7ec;
104
+ --pl-color-bg-inset: #eef0f4;
105
+ --pl-color-overlay: rgba(20, 20, 30, 0.35);
106
+ --pl-color-fg: #18181b;
107
+ --pl-color-fg-muted: #52525b;
108
+ --pl-color-fg-subtle: #8a8a94;
109
+ --pl-color-fg-on-accent: #ffffff;
110
+ --pl-color-border: rgba(0, 0, 0, 0.10);
111
+ --pl-color-border-strong: rgba(0, 0, 0, 0.20);
112
+ --pl-color-accent: #6366f1;
113
+ --pl-color-accent-hover: #4f46e5;
114
+ --pl-color-accent-fg: #4f46e5;
115
+ --pl-color-focus: #6366f1;
116
+ --pl-color-status-success: oklch(0.62 0.15 150);
117
+ --pl-color-status-warning: oklch(0.74 0.16 92);
118
+ --pl-color-status-error: oklch(0.58 0.20 25);
119
+ --pl-color-status-info: oklch(0.58 0.17 255);
120
+ --pl-gradient-brand: linear-gradient(135deg, #7355e8 0%, #6366f1 50%, #4f46e5 100%);
121
+ --pl-shadow-popover: 0 8px 24px rgba(0, 0, 0, 0.12);
122
+ }
123
+ :root[data-theme="dark"] {
124
+ color-scheme: dark;
125
+ --pl-color-bg: #0a0a0c;
126
+ --pl-color-bg-raised: #131316;
127
+ --pl-color-bg-subtle: #1c1c22;
128
+ --pl-color-bg-hover: #19191d;
129
+ --pl-color-bg-inset: #060608;
130
+ --pl-color-overlay: rgba(0, 0, 0, 0.6);
131
+ --pl-color-fg: #ededed;
132
+ --pl-color-fg-muted: #a1a1aa;
133
+ --pl-color-fg-subtle: #71717a;
134
+ --pl-color-fg-on-accent: #0a0a0c;
135
+ --pl-color-border: rgba(255, 255, 255, 0.08);
136
+ --pl-color-border-strong: rgba(255, 255, 255, 0.18);
137
+ --pl-color-accent: #9b87f2;
138
+ --pl-color-accent-hover: #b8a6f5;
139
+ --pl-color-accent-fg: #b8a6f5;
140
+ --pl-color-focus: #9b87f2;
141
+ --pl-color-status-success: oklch(0.72 0.13 145);
142
+ --pl-color-status-warning: oklch(0.78 0.12 75);
143
+ --pl-color-status-error: oklch(0.64 0.16 25);
144
+ --pl-color-status-info: oklch(0.68 0.12 230);
145
+ --pl-gradient-brand: linear-gradient(135deg, #9b87f2 0%, #818cf8 50%, #6366f1 100%);
146
+ --pl-shadow-popover: 0 8px 28px rgba(0, 0, 0, 0.5);
147
+ }
148
+
149
+ /* ── design base layer ─────────────────────────────────────────────────────── */
150
+ /* @protolabsai/design — base layer.
151
+ * Element defaults built on the generated tokens (dist/tokens.css).
152
+ * Import the bundle instead of this directly: @import "@protolabsai/design/css";
153
+ * Rule: gray and small. Content is the hero, not the chrome. */
154
+
155
+ *,
156
+ *::before,
157
+ *::after {
158
+ box-sizing: border-box;
159
+ }
160
+
161
+ html {
162
+ scroll-behavior: smooth;
163
+ }
164
+
165
+ body {
166
+ margin: 0;
167
+ background: var(--pl-color-bg);
168
+ color: var(--pl-color-fg);
169
+ font-family: var(--pl-font-sans);
170
+ font-size: var(--pl-font-base-size);
171
+ font-weight: var(--pl-font-weight-body);
172
+ line-height: var(--pl-font-line-height-body);
173
+ -webkit-font-smoothing: antialiased;
174
+ -moz-osx-font-smoothing: grayscale;
175
+ }
176
+
177
+ a {
178
+ color: inherit;
179
+ text-decoration: underline;
180
+ text-underline-offset: 3px;
181
+ text-decoration-color: var(--pl-color-border-strong);
182
+ transition:
183
+ text-decoration-color var(--pl-motion-fast) var(--pl-motion-ease),
184
+ color var(--pl-motion-fast) var(--pl-motion-ease);
185
+ }
186
+
187
+ a:hover {
188
+ text-decoration-color: var(--pl-color-fg);
189
+ }
190
+
191
+ :where(a, button):focus-visible {
192
+ outline: var(--pl-border-width) solid var(--pl-color-fg);
193
+ outline-offset: 2px;
194
+ border-radius: var(--pl-radius);
195
+ }
196
+
197
+ :where(h1, h2, h3, h4) {
198
+ margin: 0;
199
+ font-weight: 500;
200
+ line-height: var(--pl-font-line-height-heading);
201
+ letter-spacing: -0.01em;
202
+ }
203
+
204
+ :where(code, pre) {
205
+ font-family: var(--pl-font-mono);
206
+ font-size: 0.92em;
207
+ }
208
+
209
+ /* The one gradient — tagline / hero word only, never UI chrome. Heavier weight
210
+ * + tighter tracking so the stops render with enough ink. */
211
+ .pl-gradient-text {
212
+ background: var(--pl-gradient-brand);
213
+ -webkit-background-clip: text;
214
+ background-clip: text;
215
+ -webkit-text-fill-color: transparent;
216
+ font-weight: 700;
217
+ letter-spacing: -0.02em;
218
+ }
219
+
220
+ /* Subtle lavender halo — hero containers + brand moments only. Never on dense UI. */
221
+ .pl-glow {
222
+ box-shadow: var(--pl-shadow-glow);
223
+ }
224
+
225
+ /* Professional tools don't bounce. Honor the OS reduce-motion preference. */
226
+ @media (prefers-reduced-motion: reduce) {
227
+ *,
228
+ *::before,
229
+ *::after {
230
+ animation-duration: 0.01ms !important;
231
+ animation-iteration-count: 1 !important;
232
+ transition-duration: 0.01ms !important;
233
+ scroll-behavior: auto !important;
234
+ }
235
+ }
236
+
237
+ /* ── ui component: primitives.css ──────────────────────────────────────────── */
238
+ /* @protolabsai/ui — primitives styles (over @protolabsai/design --pl-* tokens). */
239
+
240
+ .pl-btn {
241
+ display: inline-flex;
242
+ align-items: center;
243
+ gap: 0.4rem;
244
+ padding: 0.5rem 0.9rem;
245
+ font-family: var(--pl-font-sans);
246
+ font-size: 13px;
247
+ font-weight: 400;
248
+ color: var(--pl-color-fg);
249
+ background: transparent;
250
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
251
+ border-radius: var(--pl-radius);
252
+ cursor: pointer;
253
+ text-decoration: none;
254
+ transition:
255
+ border-color var(--pl-motion-fast) var(--pl-motion-ease),
256
+ color var(--pl-motion-fast) var(--pl-motion-ease),
257
+ background var(--pl-motion-fast) var(--pl-motion-ease);
258
+ }
259
+
260
+ .pl-btn:hover {
261
+ border-color: var(--pl-color-fg);
262
+ }
263
+
264
+ /* Primary ships as a stronger border, not a lavender fill — brand restraint. */
265
+ .pl-btn--primary {
266
+ border-color: var(--pl-color-fg);
267
+ }
268
+
269
+ .pl-btn--primary:hover {
270
+ background: var(--pl-color-fg);
271
+ color: var(--pl-color-bg);
272
+ }
273
+
274
+ .pl-btn:disabled {
275
+ opacity: 0.5;
276
+ cursor: not-allowed;
277
+ }
278
+
279
+ .pl-badge {
280
+ display: inline-flex;
281
+ align-items: center;
282
+ gap: 0.35rem;
283
+ padding: 0.15rem 0.5rem;
284
+ font-family: var(--pl-font-mono);
285
+ font-size: 11px;
286
+ line-height: 1.4;
287
+ text-transform: lowercase;
288
+ letter-spacing: 0.02em;
289
+ color: var(--pl-color-fg-muted);
290
+ background: var(--pl-color-bg-raised);
291
+ border: var(--pl-border-width) solid var(--pl-color-border);
292
+ border-radius: var(--pl-radius);
293
+ }
294
+
295
+ .pl-badge--success {
296
+ color: var(--pl-color-status-success);
297
+ border-color: color-mix(in oklch, var(--pl-color-status-success) 35%, transparent);
298
+ }
299
+
300
+ .pl-badge--warning {
301
+ color: var(--pl-color-status-warning);
302
+ border-color: color-mix(in oklch, var(--pl-color-status-warning) 35%, transparent);
303
+ }
304
+
305
+ .pl-badge--error {
306
+ color: var(--pl-color-status-error);
307
+ border-color: color-mix(in oklch, var(--pl-color-status-error) 35%, transparent);
308
+ }
309
+
310
+ .pl-badge--info {
311
+ color: var(--pl-color-status-info);
312
+ border-color: color-mix(in oklch, var(--pl-color-status-info) 35%, transparent);
313
+ }
314
+
315
+ .pl-card {
316
+ background: var(--pl-color-bg-raised);
317
+ border: var(--pl-border-width) solid var(--pl-color-border);
318
+ border-radius: var(--pl-radius);
319
+ padding: var(--pl-space-4);
320
+ }
321
+
322
+ .pl-eyebrow {
323
+ font-family: var(--pl-font-mono);
324
+ font-size: 11px;
325
+ font-weight: var(--pl-font-weight-medium);
326
+ text-transform: uppercase;
327
+ letter-spacing: 0.08em;
328
+ color: var(--pl-color-fg-muted);
329
+ }
330
+
331
+ /* ── empty state ── */
332
+ .pl-empty {
333
+ color: var(--pl-color-fg-muted);
334
+ font-family: var(--pl-font-mono);
335
+ font-size: 13px;
336
+ padding: 1rem 0;
337
+ }
338
+
339
+ /* ── divider ── */
340
+ .pl-divider {
341
+ border: 0;
342
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
343
+ margin: 2rem 0;
344
+ }
345
+
346
+ /* ── callout (note block) ── */
347
+ .pl-callout {
348
+ background: var(--pl-color-bg-raised);
349
+ border: var(--pl-border-width) solid var(--pl-color-border);
350
+ border-left-width: 2px;
351
+ border-radius: var(--pl-radius);
352
+ padding: 0.85rem 1rem;
353
+ }
354
+
355
+ .pl-callout__title {
356
+ font-family: var(--pl-font-mono);
357
+ font-size: 12px;
358
+ text-transform: lowercase;
359
+ letter-spacing: 0.02em;
360
+ color: var(--pl-color-fg);
361
+ margin-bottom: 0.35rem;
362
+ }
363
+
364
+ .pl-callout__body {
365
+ font-size: 14px;
366
+ line-height: 1.6;
367
+ color: var(--pl-color-fg-muted);
368
+ }
369
+
370
+ .pl-callout--success {
371
+ border-left-color: var(--pl-color-status-success);
372
+ }
373
+
374
+ .pl-callout--warning {
375
+ border-left-color: var(--pl-color-status-warning);
376
+ }
377
+
378
+ .pl-callout--error {
379
+ border-left-color: var(--pl-color-status-error);
380
+ }
381
+
382
+ .pl-callout--info {
383
+ border-left-color: var(--pl-color-status-info);
384
+ }
385
+
386
+ /* ── kbd / inline token ── */
387
+ .pl-kbd {
388
+ font-family: var(--pl-font-mono);
389
+ font-size: 0.82em;
390
+ padding: 0.1rem 0.4rem;
391
+ color: var(--pl-color-fg);
392
+ background: var(--pl-color-bg-raised);
393
+ border: var(--pl-border-width) solid var(--pl-color-border);
394
+ border-bottom-width: 2px;
395
+ border-radius: var(--pl-radius);
396
+ }
397
+
398
+ /* ── standalone link ── */
399
+ .pl-link {
400
+ color: inherit;
401
+ text-decoration: underline;
402
+ text-underline-offset: 3px;
403
+ text-decoration-color: var(--pl-color-border-strong);
404
+ transition:
405
+ text-decoration-color var(--pl-motion-fast) var(--pl-motion-ease),
406
+ color var(--pl-motion-fast) var(--pl-motion-ease);
407
+ }
408
+
409
+ .pl-link:hover {
410
+ text-decoration-color: var(--pl-color-fg);
411
+ }
412
+
413
+ /* Destructive confirm — error-toned border, fills error on hover. */
414
+ .pl-btn--danger {
415
+ border-color: color-mix(in oklch, var(--pl-color-status-error) 60%, transparent);
416
+ color: var(--pl-color-status-error);
417
+ }
418
+
419
+ .pl-btn--danger:hover {
420
+ background: var(--pl-color-status-error);
421
+ border-color: var(--pl-color-status-error);
422
+ color: var(--pl-color-bg);
423
+ }
424
+
425
+ /* Ghost — transparent until hover, for toolbars / inline actions. */
426
+ .pl-btn--ghost {
427
+ border-color: transparent;
428
+ }
429
+
430
+ .pl-btn--ghost:hover {
431
+ border-color: var(--pl-color-border-strong);
432
+ background: var(--pl-color-bg-hover);
433
+ }
434
+
435
+ .pl-btn--sm {
436
+ padding: 0.3rem 0.6rem;
437
+ font-size: 12px;
438
+ }
439
+
440
+ /* Icon-only — square, centered glyph. */
441
+ .pl-btn--icon {
442
+ padding: 0;
443
+ width: 30px;
444
+ height: 30px;
445
+ justify-content: center;
446
+ }
447
+
448
+ .pl-btn--icon.pl-btn--sm {
449
+ width: 26px;
450
+ height: 26px;
451
+ }
452
+
453
+ .pl-btn--icon svg {
454
+ width: 16px;
455
+ height: 16px;
456
+ }
457
+
458
+ /* ── Avatar ──────────────────────────────────────────────────────────────────── */
459
+ .pl-avatar {
460
+ display: inline-flex;
461
+ align-items: center;
462
+ justify-content: center;
463
+ flex-shrink: 0;
464
+ overflow: hidden;
465
+ border-radius: 50%;
466
+ background: var(--pl-color-bg-subtle);
467
+ border: var(--pl-border-width) solid var(--pl-color-border);
468
+ color: var(--pl-color-fg-muted);
469
+ font-family: var(--pl-font-mono);
470
+ font-weight: var(--pl-font-weight-medium);
471
+ line-height: 1;
472
+ user-select: none;
473
+ }
474
+ .pl-avatar__img {
475
+ width: 100%;
476
+ height: 100%;
477
+ object-fit: cover;
478
+ }
479
+ .pl-avatar-group {
480
+ display: inline-flex;
481
+ align-items: center;
482
+ }
483
+ .pl-avatar-group > .pl-avatar {
484
+ margin-left: -8px;
485
+ box-shadow: 0 0 0 2px var(--pl-color-bg);
486
+ }
487
+ .pl-avatar-group > .pl-avatar:first-child {
488
+ margin-left: 0;
489
+ }
490
+
491
+ /* ── Tag / Chip ──────────────────────────────────────────────────────────────── */
492
+ .pl-tag {
493
+ display: inline-flex;
494
+ align-items: center;
495
+ gap: 4px;
496
+ height: 20px;
497
+ padding: 0 6px;
498
+ font-family: var(--pl-font-mono);
499
+ font-size: 11px;
500
+ color: var(--pl-color-fg);
501
+ background: var(--pl-color-bg-subtle);
502
+ border: var(--pl-border-width) solid var(--pl-color-border);
503
+ border-radius: var(--pl-radius);
504
+ }
505
+ .pl-tag__remove {
506
+ display: inline-flex;
507
+ align-items: center;
508
+ justify-content: center;
509
+ width: 14px;
510
+ height: 14px;
511
+ margin-right: -2px;
512
+ padding: 0;
513
+ font-size: 13px;
514
+ line-height: 1;
515
+ color: var(--pl-color-fg-muted);
516
+ background: none;
517
+ border: none;
518
+ border-radius: 50%;
519
+ cursor: pointer;
520
+ }
521
+ .pl-tag__remove:hover {
522
+ color: var(--pl-color-fg);
523
+ background: var(--pl-color-bg-hover);
524
+ }
525
+
526
+ /* ── Logo ────────────────────────────────────────────────────────────────────── */
527
+ .pl-logo {
528
+ display: block;
529
+ flex-shrink: 0;
530
+ object-fit: contain;
531
+ }
532
+
533
+ /* ── ui component: layout.css ──────────────────────────────────────────────── */
534
+ /* @protolabsai/ui — layout styles (over @protolabsai/design --pl-* tokens). */
535
+
536
+ .pl-stat__num {
537
+ font-family: var(--pl-font-mono);
538
+ font-size: 1.1rem;
539
+ color: var(--pl-color-fg);
540
+ }
541
+
542
+ .pl-stat__label {
543
+ margin-top: 0.15rem;
544
+ font-size: 12px;
545
+ color: var(--pl-color-fg-muted);
546
+ }
547
+
548
+ /* ── layout ── */
549
+ .pl-container {
550
+ max-width: 880px;
551
+ margin: 0 auto;
552
+ padding: 0 1.5rem;
553
+ }
554
+
555
+ .pl-section {
556
+ padding: 4rem 0;
557
+ }
558
+
559
+ /* ── stats grid (wraps Stat) ── */
560
+ .pl-stats {
561
+ display: grid;
562
+ grid-template-columns: repeat(2, 1fr);
563
+ gap: 1.5rem 2rem;
564
+ padding: 1.5rem 0;
565
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
566
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
567
+ }
568
+
569
+ @media (min-width: 640px) {
570
+ .pl-stats {
571
+ grid-template-columns: repeat(4, 1fr);
572
+ }
573
+ }
574
+
575
+ /* ── row (label | body [| status]) ── */
576
+ .pl-row {
577
+ display: grid;
578
+ grid-template-columns: 9rem 1fr;
579
+ gap: 1.25rem;
580
+ padding: 1rem 0;
581
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
582
+ text-decoration: none;
583
+ color: var(--pl-color-fg);
584
+ transition: opacity var(--pl-motion-fast) var(--pl-motion-ease);
585
+ }
586
+
587
+ .pl-row:last-of-type {
588
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
589
+ }
590
+
591
+ a.pl-row:hover {
592
+ opacity: 0.7;
593
+ }
594
+
595
+ .pl-row--wide {
596
+ grid-template-columns: 9rem 1fr auto;
597
+ }
598
+
599
+ .pl-row__label {
600
+ font-family: var(--pl-font-mono);
601
+ font-size: 12px;
602
+ color: var(--pl-color-fg-muted);
603
+ }
604
+
605
+ .pl-row__name {
606
+ font-family: var(--pl-font-mono);
607
+ font-size: 13px;
608
+ color: var(--pl-color-fg);
609
+ margin-bottom: 0.25rem;
610
+ }
611
+
612
+ .pl-row__desc {
613
+ font-size: 13px;
614
+ line-height: 1.5;
615
+ color: var(--pl-color-fg-muted);
616
+ }
617
+
618
+ .pl-row__status {
619
+ font-family: var(--pl-font-mono);
620
+ font-size: 11px;
621
+ text-transform: lowercase;
622
+ color: var(--pl-color-fg-muted);
623
+ }
624
+
625
+ @media (max-width: 640px) {
626
+ .pl-row,
627
+ .pl-row--wide {
628
+ grid-template-columns: 1fr;
629
+ gap: 0.25rem;
630
+ }
631
+ }
632
+
633
+ /* ── ui component: marketing.css ───────────────────────────────────────────── */
634
+ /* @protolabsai/ui — marketing styles (over @protolabsai/design --pl-* tokens). */
635
+
636
+ /* ── gradient text (the one gradient — tagline word only) ── */
637
+ .pl-gradient-text {
638
+ background: var(--pl-gradient-brand);
639
+ -webkit-background-clip: text;
640
+ -webkit-text-fill-color: transparent;
641
+ background-clip: text;
642
+ font-weight: 700;
643
+ letter-spacing: -0.02em;
644
+ }
645
+
646
+ /* ── hero ── */
647
+ .pl-hero {
648
+ display: block;
649
+ padding: 5rem 0 3rem;
650
+ }
651
+
652
+ .pl-hero h1 {
653
+ margin: 0 0 1.25rem;
654
+ font-size: clamp(2rem, 4vw, 2.75rem);
655
+ font-weight: 500;
656
+ line-height: 1.2;
657
+ letter-spacing: -0.025em;
658
+ }
659
+
660
+ .pl-hero__cta {
661
+ display: flex;
662
+ gap: 0.75rem;
663
+ flex-wrap: wrap;
664
+ }
665
+
666
+ /* ── lead + section heading/intro ── */
667
+ .pl-lead {
668
+ margin: 0 0 1.5rem;
669
+ font-size: 1.05rem;
670
+ line-height: 1.6;
671
+ color: var(--pl-color-fg-muted);
672
+ max-width: 60ch;
673
+ }
674
+
675
+ .pl-heading {
676
+ margin: 0 0 1rem;
677
+ font-size: 1.4rem;
678
+ font-weight: 500;
679
+ line-height: 1.2;
680
+ letter-spacing: -0.01em;
681
+ color: var(--pl-color-fg);
682
+ }
683
+
684
+ .pl-section-intro {
685
+ margin: 0 0 2rem;
686
+ color: var(--pl-color-fg-muted);
687
+ max-width: 60ch;
688
+ line-height: 1.6;
689
+ }
690
+
691
+ /* ── steps (numbered process) ── */
692
+ .pl-steps {
693
+ display: grid;
694
+ gap: 1.5rem;
695
+ }
696
+
697
+ .pl-step {
698
+ display: grid;
699
+ grid-template-columns: 2rem 1fr;
700
+ gap: 0.5rem;
701
+ align-items: baseline;
702
+ }
703
+
704
+ .pl-step__num {
705
+ font-family: var(--pl-font-mono);
706
+ font-size: 13px;
707
+ color: var(--pl-color-fg-muted);
708
+ }
709
+
710
+ .pl-step__title {
711
+ font-family: var(--pl-font-mono);
712
+ font-size: 13px;
713
+ margin-bottom: 0.4rem;
714
+ color: var(--pl-color-fg);
715
+ }
716
+
717
+ .pl-step__body {
718
+ color: var(--pl-color-fg-muted);
719
+ font-size: 14px;
720
+ line-height: 1.55;
721
+ }
722
+
723
+ /* ── checks (checklist) ── */
724
+ .pl-checks {
725
+ display: grid;
726
+ gap: 0.5rem;
727
+ }
728
+
729
+ .pl-check {
730
+ display: grid;
731
+ grid-template-columns: 1.2rem 1fr;
732
+ gap: 0.5rem;
733
+ align-items: baseline;
734
+ font-size: 14px;
735
+ color: var(--pl-color-fg-muted);
736
+ }
737
+
738
+ .pl-check__mark {
739
+ color: var(--pl-color-fg);
740
+ font-family: var(--pl-font-mono);
741
+ }
742
+
743
+ .pl-check strong {
744
+ color: var(--pl-color-fg);
745
+ font-weight: 500;
746
+ }
747
+
748
+ /* ── deliverables (two-col, left-border cards) ── */
749
+ .pl-deliverables {
750
+ display: grid;
751
+ gap: 1.5rem;
752
+ }
753
+
754
+ @media (min-width: 640px) {
755
+ .pl-deliverables {
756
+ grid-template-columns: 1fr 1fr;
757
+ }
758
+ }
759
+
760
+ .pl-deliverable {
761
+ border-left: var(--pl-border-width) solid var(--pl-color-border-strong);
762
+ padding-left: 1rem;
763
+ }
764
+
765
+ .pl-deliverable__title {
766
+ font-family: var(--pl-font-mono);
767
+ font-size: 13px;
768
+ margin-bottom: 0.4rem;
769
+ color: var(--pl-color-fg);
770
+ }
771
+
772
+ .pl-deliverable__body {
773
+ color: var(--pl-color-fg-muted);
774
+ font-size: 14px;
775
+ line-height: 1.55;
776
+ }
777
+
778
+ /* ── post list (blog index) ── */
779
+ .pl-post-list {
780
+ display: grid;
781
+ gap: 0;
782
+ }
783
+
784
+ .pl-post-item {
785
+ display: block;
786
+ padding: 1.25rem 0;
787
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
788
+ text-decoration: none;
789
+ color: var(--pl-color-fg);
790
+ transition: opacity var(--pl-motion-fast) var(--pl-motion-ease);
791
+ }
792
+
793
+ .pl-post-item:last-of-type {
794
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
795
+ }
796
+
797
+ .pl-post-item:hover {
798
+ opacity: 0.7;
799
+ }
800
+
801
+ .pl-post-item__meta {
802
+ font-family: var(--pl-font-mono);
803
+ font-size: 11px;
804
+ color: var(--pl-color-fg-muted);
805
+ text-transform: uppercase;
806
+ letter-spacing: 0.05em;
807
+ margin-bottom: 0.4rem;
808
+ }
809
+
810
+ .pl-post-item__title {
811
+ font-size: 1.05rem;
812
+ font-weight: 500;
813
+ margin-bottom: 0.4rem;
814
+ }
815
+
816
+ .pl-post-item__excerpt {
817
+ color: var(--pl-color-fg-muted);
818
+ font-size: 14px;
819
+ line-height: 1.55;
820
+ }
821
+
822
+ /* ── prose (long-form rich text) ── */
823
+ .pl-prose {
824
+ font-size: 1rem;
825
+ line-height: 1.7;
826
+ color: var(--pl-color-fg);
827
+ }
828
+
829
+ .pl-prose h2 {
830
+ font-size: 1.3rem;
831
+ margin-top: 2rem;
832
+ margin-bottom: 0.75rem;
833
+ }
834
+
835
+ .pl-prose h3 {
836
+ font-size: 1.1rem;
837
+ margin-top: 1.5rem;
838
+ margin-bottom: 0.5rem;
839
+ }
840
+
841
+ .pl-prose p {
842
+ margin: 1rem 0;
843
+ }
844
+
845
+ .pl-prose ul,
846
+ .pl-prose ol {
847
+ margin: 1rem 0;
848
+ padding-left: 1.25rem;
849
+ }
850
+
851
+ .pl-prose li {
852
+ margin: 0.3rem 0;
853
+ }
854
+
855
+ .pl-prose code {
856
+ background: var(--pl-color-bg-raised);
857
+ padding: 0.1rem 0.35rem;
858
+ border-radius: var(--pl-radius);
859
+ color: var(--pl-color-fg);
860
+ font-size: 0.88em;
861
+ }
862
+
863
+ .pl-prose pre {
864
+ background: var(--pl-color-bg-raised);
865
+ border: var(--pl-border-width) solid var(--pl-color-border);
866
+ padding: 1rem;
867
+ border-radius: var(--pl-radius);
868
+ overflow-x: auto;
869
+ margin: 1rem 0;
870
+ }
871
+
872
+ .pl-prose pre code {
873
+ background: transparent;
874
+ padding: 0;
875
+ }
876
+
877
+ .pl-prose blockquote {
878
+ border-left: 2px solid var(--pl-color-border-strong);
879
+ padding-left: 1rem;
880
+ margin: 1.5rem 0;
881
+ color: var(--pl-color-fg-muted);
882
+ }
883
+
884
+ /* ── Changelog (release timeline) ─────────────────────────────────────────────── */
885
+ .pl-changelog {
886
+ position: relative;
887
+ display: grid;
888
+ gap: 40px;
889
+ margin: 0;
890
+ padding: 0;
891
+ list-style: none;
892
+ }
893
+ /* the timeline spine */
894
+ .pl-changelog::before {
895
+ content: "";
896
+ position: absolute;
897
+ left: 12px;
898
+ top: 8px;
899
+ bottom: 0;
900
+ width: 1px;
901
+ background: var(--pl-color-border);
902
+ }
903
+ .pl-changelog__entry {
904
+ position: relative;
905
+ display: flex;
906
+ gap: 20px;
907
+ }
908
+ .pl-changelog__dot {
909
+ position: relative;
910
+ z-index: 1;
911
+ flex-shrink: 0;
912
+ display: inline-flex;
913
+ align-items: center;
914
+ justify-content: center;
915
+ width: 25px;
916
+ height: 25px;
917
+ margin-top: 2px;
918
+ border-radius: 50%;
919
+ background: var(--pl-color-bg-raised);
920
+ border: var(--pl-border-width) solid var(--pl-color-border);
921
+ }
922
+ .pl-changelog__dot::after {
923
+ content: "";
924
+ width: 6px;
925
+ height: 6px;
926
+ border-radius: 50%;
927
+ background: var(--pl-color-fg-subtle);
928
+ }
929
+ .pl-changelog__entry--latest .pl-changelog__dot {
930
+ background: color-mix(in oklch, var(--pl-color-accent) 15%, transparent);
931
+ border-color: color-mix(in oklch, var(--pl-color-accent) 50%, transparent);
932
+ }
933
+ .pl-changelog__entry--latest .pl-changelog__dot::after {
934
+ background: var(--pl-color-accent);
935
+ }
936
+ .pl-changelog__body {
937
+ flex: 1;
938
+ min-width: 0;
939
+ padding-bottom: 8px;
940
+ }
941
+ .pl-changelog__meta {
942
+ display: flex;
943
+ flex-wrap: wrap;
944
+ align-items: center;
945
+ gap: 12px;
946
+ margin-bottom: 12px;
947
+ }
948
+ .pl-changelog__version {
949
+ padding: 2px 8px;
950
+ font-family: var(--pl-font-mono);
951
+ font-size: 13px;
952
+ color: var(--pl-color-fg-muted);
953
+ background: var(--pl-color-bg-raised);
954
+ border: var(--pl-border-width) solid var(--pl-color-border);
955
+ border-radius: var(--pl-radius);
956
+ text-decoration: none;
957
+ transition: border-color var(--pl-motion-fast) var(--pl-motion-ease);
958
+ }
959
+ a.pl-changelog__version:hover {
960
+ border-color: var(--pl-color-accent);
961
+ }
962
+ .pl-changelog__entry--latest .pl-changelog__version {
963
+ color: var(--pl-color-accent-fg);
964
+ background: color-mix(in oklch, var(--pl-color-accent) 10%, transparent);
965
+ border-color: color-mix(in oklch, var(--pl-color-accent) 35%, transparent);
966
+ }
967
+ .pl-changelog__date {
968
+ font-size: 13px;
969
+ color: var(--pl-color-fg-subtle);
970
+ }
971
+ .pl-changelog__latest {
972
+ padding: 1px 6px;
973
+ font-family: var(--pl-font-mono);
974
+ font-size: 11px;
975
+ color: var(--pl-color-accent-fg);
976
+ background: color-mix(in oklch, var(--pl-color-accent) 8%, transparent);
977
+ border: var(--pl-border-width) solid color-mix(in oklch, var(--pl-color-accent) 25%, transparent);
978
+ border-radius: var(--pl-radius);
979
+ }
980
+ .pl-changelog__changes {
981
+ display: grid;
982
+ gap: 6px;
983
+ }
984
+ .pl-changelog__change {
985
+ display: flex;
986
+ align-items: flex-start;
987
+ gap: 8px;
988
+ font-size: 14px;
989
+ line-height: 1.5;
990
+ color: var(--pl-color-fg);
991
+ }
992
+ .pl-changelog__bullet {
993
+ flex-shrink: 0;
994
+ margin-top: 1px;
995
+ color: var(--pl-color-fg-subtle);
996
+ }
997
+ .pl-changelog__tag {
998
+ flex-shrink: 0;
999
+ min-width: 52px;
1000
+ padding: 0 6px;
1001
+ font-family: var(--pl-font-mono);
1002
+ font-size: 10px;
1003
+ line-height: 18px;
1004
+ text-align: center;
1005
+ text-transform: lowercase;
1006
+ border: var(--pl-border-width) solid var(--pl-color-border);
1007
+ border-radius: var(--pl-radius);
1008
+ }
1009
+ .pl-changelog__tag--added {
1010
+ color: var(--pl-color-status-success);
1011
+ border-color: color-mix(in oklch, var(--pl-color-status-success) 35%, transparent);
1012
+ }
1013
+ .pl-changelog__tag--fixed {
1014
+ color: var(--pl-color-status-info);
1015
+ border-color: color-mix(in oklch, var(--pl-color-status-info) 35%, transparent);
1016
+ }
1017
+ .pl-changelog__tag--changed {
1018
+ color: var(--pl-color-status-warning);
1019
+ border-color: color-mix(in oklch, var(--pl-color-status-warning) 35%, transparent);
1020
+ }
1021
+ .pl-changelog__tag--removed {
1022
+ color: var(--pl-color-status-error);
1023
+ border-color: color-mix(in oklch, var(--pl-color-status-error) 35%, transparent);
1024
+ }
1025
+
1026
+ /* ── ui component: navigation.css ──────────────────────────────────────────── */
1027
+ /* @protolabsai/ui — navigation styles (over @protolabsai/design --pl-* tokens). */
1028
+
1029
+ /* ── Tabs ──────────────────────────────────────────────────────────────────── */
1030
+ .pl-tabs {
1031
+ display: flex;
1032
+ gap: 2px;
1033
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
1034
+ }
1035
+
1036
+ .pl-tab {
1037
+ display: inline-flex;
1038
+ align-items: center;
1039
+ gap: 6px;
1040
+ background: none;
1041
+ border: none;
1042
+ border-bottom: 2px solid transparent;
1043
+ color: var(--pl-color-fg-muted);
1044
+ font: inherit;
1045
+ font-family: var(--pl-font-sans);
1046
+ padding: 8px 14px;
1047
+ cursor: pointer;
1048
+ border-radius: var(--pl-radius) var(--pl-radius) 0 0;
1049
+ }
1050
+
1051
+ .pl-tab__icon {
1052
+ display: inline-flex;
1053
+ align-items: center;
1054
+ }
1055
+
1056
+ .pl-tab__icon svg {
1057
+ width: 15px;
1058
+ height: 15px;
1059
+ }
1060
+
1061
+ .pl-tab__badge {
1062
+ display: inline-flex;
1063
+ align-items: center;
1064
+ justify-content: center;
1065
+ min-width: 16px;
1066
+ height: 16px;
1067
+ padding: 0 5px;
1068
+ font-family: var(--pl-font-mono);
1069
+ font-size: 10px;
1070
+ line-height: 1;
1071
+ color: var(--pl-color-fg-muted);
1072
+ background: var(--pl-color-bg-subtle);
1073
+ border: var(--pl-border-width) solid var(--pl-color-border);
1074
+ border-radius: 999px;
1075
+ }
1076
+
1077
+ .pl-tab--active .pl-tab__badge {
1078
+ color: var(--pl-color-fg);
1079
+ }
1080
+
1081
+ .pl-tab:hover:not(:disabled) {
1082
+ color: var(--pl-color-fg);
1083
+ }
1084
+
1085
+ .pl-tab--active {
1086
+ color: var(--pl-color-fg);
1087
+ border-bottom-color: var(--pl-color-fg);
1088
+ }
1089
+
1090
+ .pl-tab:disabled {
1091
+ opacity: 0.35;
1092
+ cursor: not-allowed;
1093
+ }
1094
+
1095
+ .pl-tab__lock {
1096
+ margin-left: 5px;
1097
+ opacity: 0.6;
1098
+ }
1099
+
1100
+ /* Responsive Tabs (opt-in via `responsive`): below ~30rem of CONTAINER width the
1101
+ strip collapses to a <select>. A container query responds to the Tabs' own
1102
+ container — not the viewport — so it collapses inside a narrow panel/split too. */
1103
+ .pl-tabs-wrap--responsive {
1104
+ container-type: inline-size;
1105
+ width: 100%;
1106
+ }
1107
+ .pl-tabs__select {
1108
+ display: none;
1109
+ width: 100%;
1110
+ padding: 6px 10px;
1111
+ font: inherit;
1112
+ color: var(--pl-color-fg);
1113
+ background: var(--pl-color-bg-inset);
1114
+ border: var(--pl-border-width) solid var(--pl-color-border);
1115
+ border-radius: var(--pl-radius);
1116
+ }
1117
+ @container (max-width: 30rem) {
1118
+ .pl-tabs-wrap--responsive > .pl-tabs {
1119
+ display: none;
1120
+ }
1121
+ .pl-tabs-wrap--responsive > .pl-tabs__select {
1122
+ display: block;
1123
+ }
1124
+ }
1125
+
1126
+ /* ── Board (kanban) ────────────────────────────────────────────────────────── */
1127
+ .pl-board {
1128
+ display: flex;
1129
+ gap: 12px;
1130
+ overflow-x: auto;
1131
+ align-items: flex-start;
1132
+ }
1133
+
1134
+ .pl-board-col {
1135
+ flex: 1 0 200px;
1136
+ min-width: 200px;
1137
+ background: var(--pl-color-bg-raised);
1138
+ border: var(--pl-border-width) solid var(--pl-color-border);
1139
+ border-radius: var(--pl-radius);
1140
+ display: flex;
1141
+ flex-direction: column;
1142
+ }
1143
+
1144
+ .pl-board-col__head {
1145
+ display: flex;
1146
+ align-items: center;
1147
+ justify-content: space-between;
1148
+ padding: 10px 12px;
1149
+ font-size: 12px;
1150
+ font-weight: 600;
1151
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
1152
+ }
1153
+
1154
+ .pl-board-col__count {
1155
+ color: var(--pl-color-fg-muted);
1156
+ font-family: var(--pl-font-mono);
1157
+ }
1158
+
1159
+ .pl-board-col__body {
1160
+ padding: 8px;
1161
+ display: flex;
1162
+ flex-direction: column;
1163
+ gap: 8px;
1164
+ min-height: 40px;
1165
+ }
1166
+
1167
+ .pl-board-card {
1168
+ text-align: left;
1169
+ background: var(--pl-color-bg);
1170
+ border: var(--pl-border-width) solid var(--pl-color-border);
1171
+ border-radius: var(--pl-radius);
1172
+ color: var(--pl-color-fg);
1173
+ padding: 10px 12px;
1174
+ cursor: pointer;
1175
+ display: flex;
1176
+ flex-direction: column;
1177
+ gap: 6px;
1178
+ font: inherit;
1179
+ }
1180
+
1181
+ .pl-board-card:hover {
1182
+ border-color: var(--pl-color-fg);
1183
+ }
1184
+
1185
+ /* ── PanelHeader (console panel header) ──────────────────────────────────────── */
1186
+ .pl-panel-header {
1187
+ display: flex;
1188
+ align-items: center;
1189
+ justify-content: space-between;
1190
+ gap: var(--pl-space-3);
1191
+ padding: var(--pl-space-3) var(--pl-space-4);
1192
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
1193
+ }
1194
+
1195
+ .pl-panel-header__kicker {
1196
+ font-family: var(--pl-font-mono);
1197
+ font-size: 11px;
1198
+ text-transform: uppercase;
1199
+ letter-spacing: 0.06em;
1200
+ color: var(--pl-color-fg-muted);
1201
+ margin-bottom: 2px;
1202
+ }
1203
+
1204
+ .pl-panel-header__title {
1205
+ margin: 0;
1206
+ font-size: 15px;
1207
+ font-weight: var(--pl-font-weight-medium);
1208
+ line-height: 1.2;
1209
+ color: var(--pl-color-fg);
1210
+ }
1211
+
1212
+ .pl-panel-header__actions {
1213
+ display: flex;
1214
+ align-items: center;
1215
+ gap: var(--pl-space-2);
1216
+ flex-shrink: 0;
1217
+ }
1218
+
1219
+ .pl-panel-header--compact {
1220
+ padding: var(--pl-space-2) var(--pl-space-3);
1221
+ }
1222
+
1223
+ .pl-panel-header--compact .pl-panel-header__title {
1224
+ font-size: 13px;
1225
+ }
1226
+
1227
+ /* ── Accordion (disclosure) ───────────────────────────────────────────────────── */
1228
+ .pl-accordion {
1229
+ display: flex;
1230
+ flex-direction: column;
1231
+ overflow: hidden;
1232
+ border: var(--pl-border-width) solid var(--pl-color-border);
1233
+ border-radius: var(--pl-radius);
1234
+ }
1235
+ .pl-accordion__item + .pl-accordion__item {
1236
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
1237
+ }
1238
+ .pl-accordion__trigger {
1239
+ display: flex;
1240
+ align-items: center;
1241
+ justify-content: space-between;
1242
+ gap: var(--pl-space-3);
1243
+ width: 100%;
1244
+ padding: var(--pl-space-3);
1245
+ background: none;
1246
+ border: none;
1247
+ color: var(--pl-color-fg);
1248
+ font: inherit;
1249
+ font-size: 14px;
1250
+ text-align: left;
1251
+ cursor: pointer;
1252
+ transition: background var(--pl-motion-fast) var(--pl-motion-ease);
1253
+ }
1254
+ .pl-accordion__trigger:hover {
1255
+ background: var(--pl-color-bg-hover);
1256
+ }
1257
+ .pl-accordion__trigger:focus-visible {
1258
+ outline: 2px solid var(--pl-color-focus);
1259
+ outline-offset: -2px;
1260
+ }
1261
+ .pl-accordion__trigger:disabled {
1262
+ opacity: 0.5;
1263
+ cursor: not-allowed;
1264
+ }
1265
+ .pl-accordion__title {
1266
+ font-weight: var(--pl-font-weight-medium);
1267
+ }
1268
+ .pl-accordion__chevron {
1269
+ flex-shrink: 0;
1270
+ width: 16px;
1271
+ height: 16px;
1272
+ color: var(--pl-color-fg-muted);
1273
+ transition: transform var(--pl-motion-fast) var(--pl-motion-ease);
1274
+ }
1275
+ .pl-accordion__item--open .pl-accordion__chevron {
1276
+ transform: rotate(90deg);
1277
+ }
1278
+ .pl-accordion__panel {
1279
+ padding: 0 var(--pl-space-3) var(--pl-space-3);
1280
+ font-size: 14px;
1281
+ line-height: 1.55;
1282
+ color: var(--pl-color-fg-muted);
1283
+ }
1284
+
1285
+ /* ── ui component: forms.css ───────────────────────────────────────────────── */
1286
+ /* @protolabsai/ui — forms styles (over @protolabsai/design --pl-* tokens). */
1287
+
1288
+ /* ── Field ─────────────────────────────────────────────────────────────────── */
1289
+ .pl-field {
1290
+ display: block;
1291
+ }
1292
+
1293
+ .pl-field__label {
1294
+ display: block;
1295
+ font-size: 11px;
1296
+ text-transform: uppercase;
1297
+ letter-spacing: 0.05em;
1298
+ color: var(--pl-color-fg-muted);
1299
+ margin-bottom: 6px;
1300
+ }
1301
+
1302
+ .pl-field__input {
1303
+ width: 100%;
1304
+ background: var(--pl-color-bg-raised);
1305
+ border: var(--pl-border-width) solid var(--pl-color-border);
1306
+ color: var(--pl-color-fg);
1307
+ border-radius: var(--pl-radius);
1308
+ padding: 9px 11px;
1309
+ font: inherit;
1310
+ font-family: var(--pl-font-sans);
1311
+ resize: vertical;
1312
+ }
1313
+
1314
+ .pl-field__input:focus {
1315
+ outline: none;
1316
+ border-color: var(--pl-color-fg);
1317
+ }
1318
+
1319
+ /* ── Form controls ───────────────────────────────────────────────────────────── */
1320
+ .pl-input {
1321
+ width: 100%;
1322
+ background: var(--pl-color-bg-raised);
1323
+ border: var(--pl-border-width) solid var(--pl-color-border);
1324
+ color: var(--pl-color-fg);
1325
+ border-radius: var(--pl-radius);
1326
+ padding: 9px 11px;
1327
+ font: inherit;
1328
+ font-family: var(--pl-font-sans);
1329
+ font-size: 13px;
1330
+ }
1331
+
1332
+ .pl-input::placeholder {
1333
+ color: var(--pl-color-fg-muted);
1334
+ }
1335
+
1336
+ .pl-input:focus {
1337
+ outline: none;
1338
+ border-color: var(--pl-color-border-strong);
1339
+ }
1340
+
1341
+ .pl-input:disabled {
1342
+ opacity: 0.5;
1343
+ cursor: not-allowed;
1344
+ }
1345
+
1346
+ .pl-textarea {
1347
+ resize: vertical;
1348
+ min-height: 72px;
1349
+ line-height: 1.5;
1350
+ }
1351
+
1352
+ .pl-select {
1353
+ cursor: pointer;
1354
+ }
1355
+
1356
+ /* Switch */
1357
+ .pl-switch {
1358
+ display: inline-flex;
1359
+ align-items: center;
1360
+ gap: 0.5rem;
1361
+ cursor: pointer;
1362
+ }
1363
+
1364
+ .pl-switch--disabled {
1365
+ opacity: 0.5;
1366
+ cursor: not-allowed;
1367
+ }
1368
+
1369
+ .pl-switch__input {
1370
+ position: absolute;
1371
+ opacity: 0;
1372
+ width: 0;
1373
+ height: 0;
1374
+ }
1375
+
1376
+ .pl-switch__track {
1377
+ position: relative;
1378
+ display: inline-block;
1379
+ width: 32px;
1380
+ height: 18px;
1381
+ background: var(--pl-color-bg-subtle);
1382
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
1383
+ border-radius: 999px;
1384
+ transition: background var(--pl-motion-fast) var(--pl-motion-ease);
1385
+ }
1386
+
1387
+ .pl-switch__thumb {
1388
+ position: absolute;
1389
+ top: 2px;
1390
+ left: 2px;
1391
+ width: 12px;
1392
+ height: 12px;
1393
+ background: var(--pl-color-fg-muted);
1394
+ border-radius: 50%;
1395
+ transition:
1396
+ transform var(--pl-motion-fast) var(--pl-motion-ease),
1397
+ background var(--pl-motion-fast) var(--pl-motion-ease);
1398
+ }
1399
+
1400
+ .pl-switch__input:checked + .pl-switch__track {
1401
+ background: var(--pl-color-fg);
1402
+ border-color: var(--pl-color-fg);
1403
+ }
1404
+
1405
+ .pl-switch__input:checked + .pl-switch__track .pl-switch__thumb {
1406
+ transform: translateX(14px);
1407
+ background: var(--pl-color-bg);
1408
+ }
1409
+
1410
+ .pl-switch__input:focus-visible + .pl-switch__track {
1411
+ outline: 2px solid var(--pl-color-border-strong);
1412
+ outline-offset: 2px;
1413
+ }
1414
+
1415
+ .pl-switch__label {
1416
+ font-size: 13px;
1417
+ color: var(--pl-color-fg);
1418
+ }
1419
+
1420
+ /* Checkbox */
1421
+ .pl-checkbox {
1422
+ display: inline-flex;
1423
+ align-items: center;
1424
+ gap: 0.5rem;
1425
+ cursor: pointer;
1426
+ }
1427
+
1428
+ .pl-checkbox--disabled {
1429
+ opacity: 0.5;
1430
+ cursor: not-allowed;
1431
+ }
1432
+
1433
+ .pl-checkbox__input {
1434
+ position: absolute;
1435
+ opacity: 0;
1436
+ width: 0;
1437
+ height: 0;
1438
+ }
1439
+
1440
+ .pl-checkbox__box {
1441
+ position: relative;
1442
+ display: inline-block;
1443
+ width: 16px;
1444
+ height: 16px;
1445
+ background: var(--pl-color-bg-raised);
1446
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
1447
+ border-radius: var(--pl-radius);
1448
+ transition:
1449
+ background var(--pl-motion-fast) var(--pl-motion-ease),
1450
+ border-color var(--pl-motion-fast) var(--pl-motion-ease);
1451
+ }
1452
+
1453
+ .pl-checkbox__input:checked + .pl-checkbox__box {
1454
+ background: var(--pl-color-fg);
1455
+ border-color: var(--pl-color-fg);
1456
+ }
1457
+
1458
+ .pl-checkbox__input:checked + .pl-checkbox__box::after {
1459
+ content: "";
1460
+ position: absolute;
1461
+ left: 5px;
1462
+ top: 2px;
1463
+ width: 4px;
1464
+ height: 8px;
1465
+ border: solid var(--pl-color-bg);
1466
+ border-width: 0 2px 2px 0;
1467
+ transform: rotate(45deg);
1468
+ }
1469
+
1470
+ .pl-checkbox__input:focus-visible + .pl-checkbox__box {
1471
+ outline: 2px solid var(--pl-color-border-strong);
1472
+ outline-offset: 2px;
1473
+ }
1474
+
1475
+ .pl-checkbox__label {
1476
+ font-size: 13px;
1477
+ color: var(--pl-color-fg);
1478
+ }
1479
+
1480
+ /* ── Radio ───────────────────────────────────────────────────────────────────── */
1481
+ .pl-radiogroup {
1482
+ display: grid;
1483
+ gap: var(--pl-space-2);
1484
+ }
1485
+ .pl-radio {
1486
+ display: inline-flex;
1487
+ align-items: center;
1488
+ gap: 0.5rem;
1489
+ cursor: pointer;
1490
+ }
1491
+ .pl-radio--disabled {
1492
+ opacity: 0.5;
1493
+ cursor: not-allowed;
1494
+ }
1495
+ .pl-radio__input {
1496
+ position: absolute;
1497
+ width: 0;
1498
+ height: 0;
1499
+ opacity: 0;
1500
+ }
1501
+ .pl-radio__control {
1502
+ position: relative;
1503
+ display: inline-block;
1504
+ flex-shrink: 0;
1505
+ width: 16px;
1506
+ height: 16px;
1507
+ background: var(--pl-color-bg-raised);
1508
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
1509
+ border-radius: 50%;
1510
+ transition:
1511
+ background var(--pl-motion-fast) var(--pl-motion-ease),
1512
+ border-color var(--pl-motion-fast) var(--pl-motion-ease);
1513
+ }
1514
+ .pl-radio__control::after {
1515
+ content: "";
1516
+ position: absolute;
1517
+ inset: 0;
1518
+ width: 6px;
1519
+ height: 6px;
1520
+ margin: auto;
1521
+ background: var(--pl-color-fg);
1522
+ border-radius: 50%;
1523
+ transform: scale(0);
1524
+ transition: transform var(--pl-motion-fast) var(--pl-motion-ease);
1525
+ }
1526
+ .pl-radio__input:checked + .pl-radio__control {
1527
+ border-color: var(--pl-color-fg);
1528
+ }
1529
+ .pl-radio__input:checked + .pl-radio__control::after {
1530
+ transform: scale(1);
1531
+ }
1532
+ .pl-radio__input:focus-visible + .pl-radio__control {
1533
+ outline: 2px solid var(--pl-color-border-strong);
1534
+ outline-offset: 2px;
1535
+ }
1536
+ .pl-radio__label {
1537
+ font-size: 13px;
1538
+ color: var(--pl-color-fg);
1539
+ }
1540
+
1541
+ /* ── ui component: overlays.css ────────────────────────────────────────────── */
1542
+ /* @protolabsai/ui — overlays styles (over @protolabsai/design --pl-* tokens). */
1543
+
1544
+ /* ── Overlay scrim (Dialog + Drawer) ─────────────────────────────────────────── */
1545
+ .pl-overlay {
1546
+ position: fixed;
1547
+ inset: 0;
1548
+ z-index: 1000;
1549
+ display: flex;
1550
+ align-items: center;
1551
+ justify-content: center;
1552
+ padding: var(--pl-space-4);
1553
+ background: var(--pl-color-overlay);
1554
+ }
1555
+
1556
+ .pl-overlay--drawer {
1557
+ padding: 0;
1558
+ }
1559
+
1560
+ /* ── Dialog / Modal ──────────────────────────────────────────────────────────── */
1561
+ .pl-dialog {
1562
+ display: flex;
1563
+ flex-direction: column;
1564
+ width: 480px;
1565
+ max-width: 100%;
1566
+ max-height: calc(100vh - 2 * var(--pl-space-4));
1567
+ background: var(--pl-color-bg-raised);
1568
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
1569
+ border-radius: var(--pl-radius);
1570
+ box-shadow: var(--pl-shadow-popover);
1571
+ }
1572
+
1573
+ .pl-dialog:focus {
1574
+ outline: none;
1575
+ }
1576
+
1577
+ .pl-dialog__head {
1578
+ display: flex;
1579
+ align-items: center;
1580
+ justify-content: space-between;
1581
+ gap: var(--pl-space-3);
1582
+ padding: var(--pl-space-3) var(--pl-space-4);
1583
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
1584
+ }
1585
+
1586
+ .pl-dialog__title {
1587
+ font-size: 14px;
1588
+ font-weight: var(--pl-font-weight-medium);
1589
+ color: var(--pl-color-fg);
1590
+ }
1591
+
1592
+ .pl-dialog__close {
1593
+ display: inline-flex;
1594
+ align-items: center;
1595
+ justify-content: center;
1596
+ width: 24px;
1597
+ height: 24px;
1598
+ font-size: 18px;
1599
+ line-height: 1;
1600
+ color: var(--pl-color-fg-muted);
1601
+ background: transparent;
1602
+ border: none;
1603
+ border-radius: var(--pl-radius);
1604
+ cursor: pointer;
1605
+ transition:
1606
+ color var(--pl-motion-fast) var(--pl-motion-ease),
1607
+ background var(--pl-motion-fast) var(--pl-motion-ease);
1608
+ }
1609
+
1610
+ .pl-dialog__close:hover {
1611
+ color: var(--pl-color-fg);
1612
+ background: var(--pl-color-bg-hover);
1613
+ }
1614
+
1615
+ .pl-dialog__body {
1616
+ padding: var(--pl-space-4);
1617
+ overflow-y: auto;
1618
+ font-size: 14px;
1619
+ line-height: 1.6;
1620
+ color: var(--pl-color-fg-muted);
1621
+ }
1622
+
1623
+ .pl-dialog__foot {
1624
+ display: flex;
1625
+ justify-content: flex-end;
1626
+ gap: var(--pl-space-2);
1627
+ padding: var(--pl-space-3) var(--pl-space-4);
1628
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
1629
+ }
1630
+
1631
+ /* ── Drawer (slide-in sheet) ─────────────────────────────────────────────────── */
1632
+ .pl-drawer {
1633
+ display: flex;
1634
+ flex-direction: column;
1635
+ width: 420px;
1636
+ max-width: 100%;
1637
+ height: 100%;
1638
+ background: var(--pl-color-bg-raised);
1639
+ box-shadow: var(--pl-shadow-popover);
1640
+ animation: pl-drawer-in var(--pl-motion-base) var(--pl-motion-ease);
1641
+ }
1642
+
1643
+ .pl-drawer:focus {
1644
+ outline: none;
1645
+ }
1646
+
1647
+ .pl-drawer--right {
1648
+ margin-left: auto;
1649
+ border-left: var(--pl-border-width) solid var(--pl-color-border-strong);
1650
+ }
1651
+
1652
+ .pl-drawer--left {
1653
+ margin-right: auto;
1654
+ border-right: var(--pl-border-width) solid var(--pl-color-border-strong);
1655
+ animation-name: pl-drawer-in-left;
1656
+ }
1657
+
1658
+ .pl-overlay--drawer:has(.pl-drawer--left) {
1659
+ justify-content: flex-start;
1660
+ }
1661
+
1662
+ @keyframes pl-drawer-in {
1663
+ from {
1664
+ transform: translateX(100%);
1665
+ }
1666
+ }
1667
+
1668
+ @keyframes pl-drawer-in-left {
1669
+ from {
1670
+ transform: translateX(-100%);
1671
+ }
1672
+ }
1673
+
1674
+ .pl-drawer__head {
1675
+ display: flex;
1676
+ align-items: center;
1677
+ justify-content: space-between;
1678
+ gap: var(--pl-space-3);
1679
+ padding: var(--pl-space-3) var(--pl-space-4);
1680
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
1681
+ }
1682
+
1683
+ .pl-drawer__title {
1684
+ font-size: 14px;
1685
+ font-weight: var(--pl-font-weight-medium);
1686
+ color: var(--pl-color-fg);
1687
+ }
1688
+
1689
+ .pl-drawer__body {
1690
+ flex: 1;
1691
+ padding: var(--pl-space-4);
1692
+ overflow-y: auto;
1693
+ font-size: 14px;
1694
+ line-height: 1.6;
1695
+ color: var(--pl-color-fg-muted);
1696
+ }
1697
+
1698
+ .pl-drawer__foot {
1699
+ display: flex;
1700
+ justify-content: flex-end;
1701
+ gap: var(--pl-space-2);
1702
+ padding: var(--pl-space-3) var(--pl-space-4);
1703
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
1704
+ }
1705
+
1706
+ /* ── Toast ───────────────────────────────────────────────────────────────────── */
1707
+ .pl-toast-stack {
1708
+ position: fixed;
1709
+ bottom: var(--pl-space-4);
1710
+ right: var(--pl-space-4);
1711
+ z-index: 1100;
1712
+ display: flex;
1713
+ flex-direction: column;
1714
+ gap: var(--pl-space-2);
1715
+ max-width: min(360px, calc(100vw - 2 * var(--pl-space-4)));
1716
+ }
1717
+
1718
+ .pl-toast {
1719
+ display: flex;
1720
+ align-items: flex-start;
1721
+ gap: var(--pl-space-3);
1722
+ padding: var(--pl-space-3);
1723
+ background: var(--pl-color-bg-raised);
1724
+ border: var(--pl-border-width) solid var(--pl-color-border);
1725
+ border-left-width: 2px;
1726
+ border-radius: var(--pl-radius);
1727
+ box-shadow: var(--pl-shadow-popover);
1728
+ animation: pl-toast-in var(--pl-motion-base) var(--pl-motion-ease);
1729
+ }
1730
+
1731
+ @keyframes pl-toast-in {
1732
+ from {
1733
+ opacity: 0;
1734
+ transform: translateY(6px);
1735
+ }
1736
+ }
1737
+
1738
+ .pl-toast--success {
1739
+ border-left-color: var(--pl-color-status-success);
1740
+ }
1741
+
1742
+ .pl-toast--warning {
1743
+ border-left-color: var(--pl-color-status-warning);
1744
+ }
1745
+
1746
+ .pl-toast--error {
1747
+ border-left-color: var(--pl-color-status-error);
1748
+ }
1749
+
1750
+ .pl-toast--info {
1751
+ border-left-color: var(--pl-color-status-info);
1752
+ }
1753
+
1754
+ .pl-toast__body {
1755
+ flex: 1;
1756
+ min-width: 0;
1757
+ }
1758
+
1759
+ .pl-toast__title {
1760
+ font-family: var(--pl-font-mono);
1761
+ font-size: 12px;
1762
+ color: var(--pl-color-fg);
1763
+ margin-bottom: 0.2rem;
1764
+ }
1765
+
1766
+ .pl-toast__msg {
1767
+ font-size: 13px;
1768
+ line-height: 1.5;
1769
+ color: var(--pl-color-fg-muted);
1770
+ }
1771
+
1772
+ .pl-toast__close {
1773
+ flex-shrink: 0;
1774
+ font-size: 16px;
1775
+ line-height: 1;
1776
+ color: var(--pl-color-fg-muted);
1777
+ background: transparent;
1778
+ border: none;
1779
+ cursor: pointer;
1780
+ }
1781
+
1782
+ .pl-toast__close:hover {
1783
+ color: var(--pl-color-fg);
1784
+ }
1785
+
1786
+ /* ── Tooltip (CSS-only) ──────────────────────────────────────────────────────── */
1787
+ .pl-tip-wrap {
1788
+ position: relative;
1789
+ display: inline-flex;
1790
+ }
1791
+
1792
+ .pl-tip {
1793
+ position: absolute;
1794
+ z-index: 1200;
1795
+ pointer-events: none;
1796
+ white-space: nowrap;
1797
+ padding: 0.25rem 0.5rem;
1798
+ font-family: var(--pl-font-mono);
1799
+ font-size: 11px;
1800
+ color: var(--pl-color-fg);
1801
+ background: var(--pl-color-bg-raised);
1802
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
1803
+ border-radius: var(--pl-radius);
1804
+ box-shadow: var(--pl-shadow-popover);
1805
+ opacity: 0;
1806
+ transition: opacity var(--pl-motion-fast) var(--pl-motion-ease);
1807
+ }
1808
+
1809
+ .pl-tip-wrap:hover .pl-tip,
1810
+ .pl-tip-wrap:focus-within .pl-tip {
1811
+ opacity: 1;
1812
+ }
1813
+
1814
+ .pl-tip--top {
1815
+ bottom: calc(100% + 6px);
1816
+ left: 50%;
1817
+ transform: translateX(-50%);
1818
+ }
1819
+
1820
+ .pl-tip--bottom {
1821
+ top: calc(100% + 6px);
1822
+ left: 50%;
1823
+ transform: translateX(-50%);
1824
+ }
1825
+
1826
+ .pl-tip--left {
1827
+ right: calc(100% + 6px);
1828
+ top: 50%;
1829
+ transform: translateY(-50%);
1830
+ }
1831
+
1832
+ .pl-tip--right {
1833
+ left: calc(100% + 6px);
1834
+ top: 50%;
1835
+ transform: translateY(-50%);
1836
+ }
1837
+
1838
+ /* ── Popover (Radix-backed) ──────────────────────────────────────────────────── */
1839
+ .pl-popover {
1840
+ min-width: 200px;
1841
+ max-width: 320px;
1842
+ padding: var(--pl-space-3);
1843
+ font-size: 13px;
1844
+ line-height: 1.5;
1845
+ color: var(--pl-color-fg);
1846
+ background: var(--pl-color-bg-raised);
1847
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
1848
+ border-radius: var(--pl-radius);
1849
+ box-shadow: var(--pl-shadow-popover);
1850
+ z-index: 1200;
1851
+ }
1852
+
1853
+ /* ── ui component: data.css ────────────────────────────────────────────────── */
1854
+ /* @protolabsai/ui — data styles (over @protolabsai/design --pl-* tokens). */
1855
+
1856
+ /* ── Table (dense data) ──────────────────────────────────────────────────────── */
1857
+ .pl-table {
1858
+ width: 100%;
1859
+ border-collapse: collapse;
1860
+ font-size: 13px;
1861
+ }
1862
+
1863
+ .pl-table th {
1864
+ text-align: left;
1865
+ font-family: var(--pl-font-mono);
1866
+ font-size: 11px;
1867
+ font-weight: var(--pl-font-weight-medium);
1868
+ text-transform: uppercase;
1869
+ letter-spacing: 0.04em;
1870
+ color: var(--pl-color-fg-muted);
1871
+ padding: var(--pl-space-2) var(--pl-space-3);
1872
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
1873
+ }
1874
+
1875
+ .pl-table td {
1876
+ padding: var(--pl-space-2) var(--pl-space-3);
1877
+ color: var(--pl-color-fg);
1878
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
1879
+ }
1880
+
1881
+ .pl-table tbody tr.pl-tr--interactive {
1882
+ cursor: pointer;
1883
+ transition: background var(--pl-motion-fast) var(--pl-motion-ease);
1884
+ }
1885
+
1886
+ .pl-table tbody tr.pl-tr--interactive:hover {
1887
+ background: var(--pl-color-bg-hover);
1888
+ }
1889
+
1890
+ .pl-table tbody tr.pl-tr--selected {
1891
+ background: var(--pl-color-bg-subtle);
1892
+ }
1893
+
1894
+ /* ── Status dot ──────────────────────────────────────────────────────────────── */
1895
+ .pl-dot {
1896
+ display: inline-block;
1897
+ width: 8px;
1898
+ height: 8px;
1899
+ border-radius: 50%;
1900
+ background: var(--pl-color-fg-muted);
1901
+ }
1902
+
1903
+ .pl-dot--success {
1904
+ background: var(--pl-color-status-success);
1905
+ }
1906
+
1907
+ .pl-dot--warning {
1908
+ background: var(--pl-color-status-warning);
1909
+ }
1910
+
1911
+ .pl-dot--error {
1912
+ background: var(--pl-color-status-error);
1913
+ }
1914
+
1915
+ .pl-dot--info {
1916
+ background: var(--pl-color-status-info);
1917
+ }
1918
+
1919
+ .pl-dot--pulse {
1920
+ animation: pl-dot-pulse var(--pl-motion-status) var(--pl-motion-ease-in-out) infinite;
1921
+ }
1922
+
1923
+ @keyframes pl-dot-pulse {
1924
+ 0%,
1925
+ 100% {
1926
+ opacity: 1;
1927
+ }
1928
+ 50% {
1929
+ opacity: 0.35;
1930
+ }
1931
+ }
1932
+
1933
+ .pl-dot-row {
1934
+ display: inline-flex;
1935
+ align-items: center;
1936
+ gap: 0.4rem;
1937
+ }
1938
+
1939
+ .pl-dot-row__label {
1940
+ font-size: 12px;
1941
+ color: var(--pl-color-fg-muted);
1942
+ }
1943
+
1944
+ /* ── Spinner ─────────────────────────────────────────────────────────────────── */
1945
+ .pl-spinner {
1946
+ display: inline-block;
1947
+ border: 2px solid var(--pl-color-border-strong);
1948
+ border-top-color: var(--pl-color-fg);
1949
+ border-radius: 50%;
1950
+ animation: pl-spin var(--pl-motion-loading) var(--pl-motion-linear) infinite;
1951
+ }
1952
+
1953
+ @keyframes pl-spin {
1954
+ to {
1955
+ transform: rotate(360deg);
1956
+ }
1957
+ }
1958
+
1959
+ /* ── ScrollArea (thin brand scrollbars) ──────────────────────────────────────── */
1960
+ .pl-scroll {
1961
+ overflow: auto;
1962
+ /* min-height:0 lets the region actually scroll inside a flex/grid parent
1963
+ (the classic min-size trap) instead of overflowing it. */
1964
+ min-height: 0;
1965
+ overscroll-behavior: contain;
1966
+ scrollbar-gutter: stable;
1967
+ scrollbar-width: thin;
1968
+ scrollbar-color: var(--pl-color-border-strong) transparent;
1969
+ }
1970
+
1971
+ .pl-scroll:focus-visible {
1972
+ outline: 1px solid var(--pl-color-fg);
1973
+ outline-offset: -2px;
1974
+ }
1975
+
1976
+ .pl-scroll::-webkit-scrollbar {
1977
+ width: 8px;
1978
+ height: 8px;
1979
+ }
1980
+
1981
+ .pl-scroll::-webkit-scrollbar-thumb {
1982
+ background: var(--pl-color-border-strong);
1983
+ border-radius: var(--pl-radius);
1984
+ }
1985
+
1986
+ .pl-scroll::-webkit-scrollbar-track {
1987
+ background: transparent;
1988
+ }
1989
+
1990
+ /* ── Skeleton (loading placeholder) ──────────────────────────────────────────── */
1991
+ .pl-skel {
1992
+ display: block;
1993
+ border-radius: var(--pl-radius);
1994
+ background-color: var(--pl-color-bg-subtle);
1995
+ background-image: linear-gradient(
1996
+ 90deg,
1997
+ var(--pl-color-bg-subtle) 25%,
1998
+ var(--pl-color-bg-hover) 50%,
1999
+ var(--pl-color-bg-subtle) 75%
2000
+ );
2001
+ background-size: 200% 100%;
2002
+ animation: pl-skel-shimmer 1.4s var(--pl-motion-ease-in-out) infinite;
2003
+ }
2004
+
2005
+ @keyframes pl-skel-shimmer {
2006
+ from {
2007
+ background-position: 200% 0;
2008
+ }
2009
+ to {
2010
+ background-position: -200% 0;
2011
+ }
2012
+ }
2013
+
2014
+ .pl-skel-lines {
2015
+ display: grid;
2016
+ gap: 8px;
2017
+ }
2018
+
2019
+ .pl-skel-group {
2020
+ display: grid;
2021
+ gap: var(--pl-space-3);
2022
+ }
2023
+
2024
+ /* Respect reduced-motion for every animation this package introduces. */
2025
+ @media (prefers-reduced-motion: reduce) {
2026
+ .pl-drawer,
2027
+ .pl-toast,
2028
+ .pl-dot--pulse,
2029
+ .pl-rail__dot,
2030
+ .pl-spinner {
2031
+ animation: none;
2032
+ }
2033
+ /* Skeletons go static (solid fill, no shimmer). */
2034
+ .pl-skel {
2035
+ animation: none;
2036
+ background-image: none;
2037
+ }
2038
+ }
2039
+
2040
+ /* ── Progress ─────────────────────────────────────────────────────────────────── */
2041
+ .pl-progress {
2042
+ display: grid;
2043
+ gap: var(--pl-space-2);
2044
+ width: 100%;
2045
+ }
2046
+ .pl-progress__caption {
2047
+ display: flex;
2048
+ align-items: center;
2049
+ justify-content: space-between;
2050
+ gap: var(--pl-space-2);
2051
+ font-size: 12px;
2052
+ color: var(--pl-color-fg-muted);
2053
+ }
2054
+ .pl-progress__value {
2055
+ font-family: var(--pl-font-mono);
2056
+ color: var(--pl-color-fg);
2057
+ }
2058
+ .pl-progress__track {
2059
+ position: relative;
2060
+ height: 6px;
2061
+ overflow: hidden;
2062
+ background: var(--pl-color-bg-inset);
2063
+ border-radius: 999px;
2064
+ }
2065
+ .pl-progress__fill {
2066
+ height: 100%;
2067
+ background: var(--pl-color-accent);
2068
+ border-radius: inherit;
2069
+ transition: width var(--pl-motion-base) var(--pl-motion-ease);
2070
+ }
2071
+ .pl-progress__fill--success {
2072
+ background: var(--pl-color-status-success);
2073
+ }
2074
+ .pl-progress__fill--warning {
2075
+ background: var(--pl-color-status-warning);
2076
+ }
2077
+ .pl-progress__fill--error {
2078
+ background: var(--pl-color-status-error);
2079
+ }
2080
+ .pl-progress__fill--info {
2081
+ background: var(--pl-color-status-info);
2082
+ }
2083
+ .pl-progress__fill--indeterminate {
2084
+ width: 40%;
2085
+ animation: pl-progress-slide 1.1s var(--pl-motion-ease-in-out) infinite;
2086
+ }
2087
+ @keyframes pl-progress-slide {
2088
+ 0% {
2089
+ transform: translateX(-120%);
2090
+ }
2091
+ 100% {
2092
+ transform: translateX(320%);
2093
+ }
2094
+ }
2095
+
2096
+ /* ── Alert (inline status banner) ─────────────────────────────────────────────── */
2097
+ .pl-alert {
2098
+ display: flex;
2099
+ align-items: flex-start;
2100
+ gap: var(--pl-space-3);
2101
+ padding: var(--pl-space-3);
2102
+ background: var(--pl-color-bg-raised);
2103
+ border: var(--pl-border-width) solid var(--pl-color-border);
2104
+ border-left-width: 3px;
2105
+ border-radius: var(--pl-radius);
2106
+ color: var(--pl-color-fg);
2107
+ }
2108
+ .pl-alert__icon {
2109
+ flex-shrink: 0;
2110
+ width: 16px;
2111
+ height: 16px;
2112
+ margin-top: 1px;
2113
+ }
2114
+ .pl-alert__body {
2115
+ flex: 1;
2116
+ min-width: 0;
2117
+ font-size: 13px;
2118
+ line-height: 1.5;
2119
+ }
2120
+ .pl-alert__title {
2121
+ font-weight: var(--pl-font-weight-medium);
2122
+ }
2123
+ .pl-alert__text {
2124
+ color: var(--pl-color-fg-muted);
2125
+ }
2126
+ .pl-alert__title + .pl-alert__text {
2127
+ margin-top: 2px;
2128
+ }
2129
+ .pl-alert__action {
2130
+ flex-shrink: 0;
2131
+ }
2132
+ .pl-alert__dismiss {
2133
+ flex-shrink: 0;
2134
+ display: inline-flex;
2135
+ padding: 2px;
2136
+ margin: -2px -2px 0 0;
2137
+ background: none;
2138
+ border: none;
2139
+ border-radius: var(--pl-radius);
2140
+ color: var(--pl-color-fg-subtle);
2141
+ cursor: pointer;
2142
+ transition: color var(--pl-motion-fast) var(--pl-motion-ease);
2143
+ }
2144
+ .pl-alert__dismiss:hover {
2145
+ color: var(--pl-color-fg);
2146
+ }
2147
+ .pl-alert__dismiss svg {
2148
+ width: 14px;
2149
+ height: 14px;
2150
+ }
2151
+ .pl-alert--success {
2152
+ border-left-color: var(--pl-color-status-success);
2153
+ }
2154
+ .pl-alert--success .pl-alert__icon {
2155
+ color: var(--pl-color-status-success);
2156
+ }
2157
+ .pl-alert--warning {
2158
+ border-left-color: var(--pl-color-status-warning);
2159
+ }
2160
+ .pl-alert--warning .pl-alert__icon {
2161
+ color: var(--pl-color-status-warning);
2162
+ }
2163
+ .pl-alert--error {
2164
+ border-left-color: var(--pl-color-status-error);
2165
+ }
2166
+ .pl-alert--error .pl-alert__icon {
2167
+ color: var(--pl-color-status-error);
2168
+ }
2169
+ .pl-alert--info {
2170
+ border-left-color: var(--pl-color-status-info);
2171
+ }
2172
+ .pl-alert--info .pl-alert__icon {
2173
+ color: var(--pl-color-status-info);
2174
+ }
2175
+ .pl-alert--neutral .pl-alert__icon {
2176
+ color: var(--pl-color-fg-muted);
2177
+ }
2178
+
2179
+ /* ── ui component: menu.css ────────────────────────────────────────────────── */
2180
+ /* @protolabsai/ui — menu styles (over @protolabsai/design --pl-* tokens). */
2181
+
2182
+ /* ── Menu / DropdownMenu (Radix-backed) ──────────────────────────────────────── */
2183
+ .pl-menu__anchor {
2184
+ width: 0;
2185
+ height: 0;
2186
+ pointer-events: none;
2187
+ }
2188
+
2189
+ .pl-menu {
2190
+ min-width: 180px;
2191
+ padding: 4px;
2192
+ background: var(--pl-color-bg-raised);
2193
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
2194
+ border-radius: var(--pl-radius);
2195
+ box-shadow: var(--pl-shadow-popover);
2196
+ z-index: 1200;
2197
+ }
2198
+
2199
+ .pl-menu__item {
2200
+ display: flex;
2201
+ align-items: center;
2202
+ gap: 8px;
2203
+ padding: 6px 8px;
2204
+ font-size: 13px;
2205
+ color: var(--pl-color-fg);
2206
+ border-radius: calc(var(--pl-radius) - 1px);
2207
+ cursor: pointer;
2208
+ outline: none;
2209
+ user-select: none;
2210
+ }
2211
+
2212
+ /* Radix sets data-highlighted on the keyboard/pointer-focused item. */
2213
+ .pl-menu__item[data-highlighted] {
2214
+ background: var(--pl-color-bg-hover);
2215
+ }
2216
+
2217
+ .pl-menu__item[data-disabled] {
2218
+ color: var(--pl-color-fg-muted);
2219
+ opacity: 0.5;
2220
+ pointer-events: none;
2221
+ }
2222
+
2223
+ .pl-menu__item--destructive {
2224
+ color: var(--pl-color-status-error);
2225
+ }
2226
+
2227
+ .pl-menu__item--destructive[data-highlighted] {
2228
+ background: color-mix(in oklch, var(--pl-color-status-error) 16%, transparent);
2229
+ }
2230
+
2231
+ .pl-menu__icon {
2232
+ display: inline-flex;
2233
+ align-items: center;
2234
+ color: var(--pl-color-fg-muted);
2235
+ }
2236
+
2237
+ .pl-menu__icon svg {
2238
+ width: 15px;
2239
+ height: 15px;
2240
+ }
2241
+
2242
+ .pl-menu__item--destructive .pl-menu__icon {
2243
+ color: var(--pl-color-status-error);
2244
+ }
2245
+
2246
+ .pl-menu__label {
2247
+ flex: 1;
2248
+ }
2249
+
2250
+ .pl-menu__subarrow {
2251
+ color: var(--pl-color-fg-muted);
2252
+ font-size: 14px;
2253
+ line-height: 1;
2254
+ }
2255
+
2256
+ .pl-menu__sep {
2257
+ height: 1px;
2258
+ margin: 4px 0;
2259
+ background: var(--pl-color-border);
2260
+ }
2261
+
2262
+ .pl-menu__group-label {
2263
+ padding: 4px 8px;
2264
+ font-family: var(--pl-font-mono);
2265
+ font-size: 10px;
2266
+ text-transform: uppercase;
2267
+ letter-spacing: 0.06em;
2268
+ color: var(--pl-color-fg-muted);
2269
+ }
2270
+
2271
+ /* ── ui component: app-shell.css ───────────────────────────────────────────── */
2272
+ /* @protolabsai/ui — app-shell styles (over @protolabsai/design --pl-* tokens). */
2273
+
2274
+ /* ── SurfaceRail (icon rail) ─────────────────────────────────────────────────── */
2275
+ .pl-rail {
2276
+ display: flex;
2277
+ flex-direction: column;
2278
+ align-items: stretch;
2279
+ gap: 2px;
2280
+ width: 64px;
2281
+ flex-shrink: 0;
2282
+ padding: 6px;
2283
+ background: var(--pl-color-bg-raised);
2284
+ border-right: var(--pl-border-width) solid var(--pl-color-border);
2285
+ }
2286
+
2287
+ .pl-rail--right {
2288
+ border-right: none;
2289
+ border-left: var(--pl-border-width) solid var(--pl-color-border);
2290
+ }
2291
+
2292
+ .pl-rail__btn {
2293
+ position: relative;
2294
+ display: flex;
2295
+ flex-direction: column;
2296
+ align-items: center;
2297
+ gap: 3px;
2298
+ padding: 8px 2px;
2299
+ background: none;
2300
+ border: none;
2301
+ border-radius: var(--pl-radius);
2302
+ color: var(--pl-color-fg-muted);
2303
+ cursor: pointer;
2304
+ font: inherit;
2305
+ transition:
2306
+ background var(--pl-motion-fast) var(--pl-motion-ease),
2307
+ color var(--pl-motion-fast) var(--pl-motion-ease);
2308
+ }
2309
+
2310
+ .pl-rail__btn:hover {
2311
+ background: var(--pl-color-bg-hover);
2312
+ color: var(--pl-color-fg);
2313
+ }
2314
+
2315
+ .pl-rail__btn--active {
2316
+ background: var(--pl-color-bg-subtle);
2317
+ color: var(--pl-color-fg);
2318
+ }
2319
+
2320
+ .pl-rail__icon {
2321
+ display: inline-flex;
2322
+ }
2323
+
2324
+ .pl-rail__icon svg {
2325
+ width: 18px;
2326
+ height: 18px;
2327
+ }
2328
+
2329
+ .pl-rail__label {
2330
+ max-width: 100%;
2331
+ overflow: hidden;
2332
+ font-size: 9px;
2333
+ line-height: 1.1;
2334
+ text-align: center;
2335
+ text-overflow: ellipsis;
2336
+ white-space: nowrap;
2337
+ }
2338
+
2339
+ .pl-rail__badge {
2340
+ position: absolute;
2341
+ top: 4px;
2342
+ right: 9px;
2343
+ display: inline-flex;
2344
+ align-items: center;
2345
+ justify-content: center;
2346
+ min-width: 15px;
2347
+ height: 15px;
2348
+ padding: 0 4px;
2349
+ font-family: var(--pl-font-mono);
2350
+ font-size: 9px;
2351
+ color: var(--pl-color-fg);
2352
+ background: var(--pl-color-bg-subtle);
2353
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
2354
+ border-radius: 999px;
2355
+ }
2356
+
2357
+ .pl-rail__dot {
2358
+ position: absolute;
2359
+ top: 6px;
2360
+ right: 14px;
2361
+ width: 7px;
2362
+ height: 7px;
2363
+ border-radius: 50%;
2364
+ background: var(--pl-color-status-info);
2365
+ animation: pl-dot-pulse var(--pl-motion-status) var(--pl-motion-ease-in-out) infinite;
2366
+ }
2367
+
2368
+ /* ── MobileNav (bottom bar + drawer list) ────────────────────────────────────── */
2369
+ .pl-mobilenav {
2370
+ display: flex;
2371
+ align-items: stretch;
2372
+ background: var(--pl-color-bg-raised);
2373
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
2374
+ }
2375
+
2376
+ .pl-mobilenav__tab {
2377
+ flex: 1;
2378
+ display: flex;
2379
+ flex-direction: column;
2380
+ align-items: center;
2381
+ gap: 3px;
2382
+ padding: 8px 2px;
2383
+ background: none;
2384
+ border: none;
2385
+ color: var(--pl-color-fg-muted);
2386
+ font: inherit;
2387
+ font-size: 10px;
2388
+ cursor: pointer;
2389
+ }
2390
+
2391
+ .pl-mobilenav__tab--active {
2392
+ color: var(--pl-color-fg);
2393
+ }
2394
+
2395
+ .pl-mobilenav__icon {
2396
+ display: inline-flex;
2397
+ }
2398
+
2399
+ .pl-mobilenav__icon svg {
2400
+ width: 18px;
2401
+ height: 18px;
2402
+ }
2403
+
2404
+ .pl-mobilenav__list {
2405
+ display: grid;
2406
+ gap: 2px;
2407
+ }
2408
+
2409
+ .pl-mobilenav__list-item {
2410
+ display: flex;
2411
+ align-items: center;
2412
+ gap: 10px;
2413
+ width: 100%;
2414
+ padding: 10px 8px;
2415
+ background: none;
2416
+ border: none;
2417
+ border-radius: var(--pl-radius);
2418
+ color: var(--pl-color-fg);
2419
+ font: inherit;
2420
+ font-size: 14px;
2421
+ text-align: left;
2422
+ cursor: pointer;
2423
+ }
2424
+
2425
+ .pl-mobilenav__list-item:hover {
2426
+ background: var(--pl-color-bg-hover);
2427
+ }
2428
+
2429
+ .pl-mobilenav__list-item--active {
2430
+ background: var(--pl-color-bg-subtle);
2431
+ }
2432
+
2433
+ /* ── AppShell (dual-rail + 3-column) ─────────────────────────────────────────── */
2434
+ /* Vertical frame: content row (1fr) + optional utility bar (40px). */
2435
+ .pl-appshell-frame {
2436
+ display: flex;
2437
+ flex-direction: column;
2438
+ height: 100%;
2439
+ min-height: 0;
2440
+ background: var(--pl-color-bg);
2441
+ color: var(--pl-color-fg);
2442
+ }
2443
+ .pl-appshell {
2444
+ display: flex;
2445
+ align-items: stretch;
2446
+ flex: 1 1 auto;
2447
+ min-height: 0;
2448
+ background: var(--pl-color-bg);
2449
+ color: var(--pl-color-fg);
2450
+ }
2451
+ /* Utility bar — the bottom 40px track (third grid row). Desktop only. */
2452
+ .pl-appshell__utility {
2453
+ flex: 0 0 40px;
2454
+ height: 40px;
2455
+ display: flex;
2456
+ align-items: center;
2457
+ border-top: var(--pl-border-width) solid var(--pl-color-border);
2458
+ background: var(--pl-color-bg-raised);
2459
+ }
2460
+ .pl-utilitybar {
2461
+ display: flex;
2462
+ align-items: center;
2463
+ gap: var(--pl-space-2);
2464
+ width: 100%;
2465
+ height: 100%;
2466
+ padding: 0 var(--pl-space-3);
2467
+ font-size: 12px;
2468
+ color: var(--pl-color-fg-muted);
2469
+ }
2470
+ .pl-utilitybar__cluster {
2471
+ display: flex;
2472
+ align-items: center;
2473
+ gap: var(--pl-space-3);
2474
+ }
2475
+ .pl-utilitybar__spacer {
2476
+ flex: 1;
2477
+ }
2478
+
2479
+ .pl-appshell__col {
2480
+ display: flex;
2481
+ flex-direction: column;
2482
+ min-width: 0;
2483
+ min-height: 0;
2484
+ overflow: hidden;
2485
+ }
2486
+
2487
+ .pl-appshell__col--left {
2488
+ flex: 1 1 auto;
2489
+ }
2490
+
2491
+ .pl-appshell__col--right {
2492
+ flex: 0 0 auto;
2493
+ border-left: var(--pl-border-width) solid var(--pl-color-border);
2494
+ }
2495
+
2496
+ /* When the left column is collapsed, the surviving column fills the stage
2497
+ (no fixed width, no divider) instead of sitting at its controlled width. */
2498
+ .pl-appshell__col--fill {
2499
+ flex: 1 1 auto;
2500
+ border-left: none;
2501
+ }
2502
+
2503
+ .pl-appshell__handle {
2504
+ flex: 0 0 auto;
2505
+ width: 5px;
2506
+ cursor: col-resize;
2507
+ background: transparent;
2508
+ touch-action: none;
2509
+ transition: background var(--pl-motion-fast) var(--pl-motion-ease);
2510
+ }
2511
+
2512
+ .pl-appshell__handle:hover,
2513
+ .pl-appshell__handle:focus-visible {
2514
+ background: var(--pl-color-border-strong);
2515
+ outline: none;
2516
+ }
2517
+
2518
+ .pl-appshell--mobile {
2519
+ flex-direction: column;
2520
+ }
2521
+
2522
+ .pl-appshell__mobile-stage {
2523
+ flex: 1 1 auto;
2524
+ min-height: 0;
2525
+ overflow: auto;
2526
+ }
2527
+
2528
+ /* ── Rail drag-and-drop (dnd-kit) ─────────────────────────────────────────────── */
2529
+ .pl-rail--sortable .pl-rail__btn {
2530
+ cursor: grab;
2531
+ touch-action: none;
2532
+ }
2533
+ .pl-rail--sortable .pl-rail__btn:active {
2534
+ cursor: grabbing;
2535
+ }
2536
+ .pl-rail__btn--dragging {
2537
+ opacity: 0.4;
2538
+ }
2539
+ /* The floating drag preview — same shape as a rail button, keeps icon + badge/dot. */
2540
+ .pl-rail__btn--overlay {
2541
+ position: relative;
2542
+ display: flex;
2543
+ flex-direction: column;
2544
+ align-items: center;
2545
+ gap: 3px;
2546
+ width: 56px;
2547
+ padding: 8px 2px;
2548
+ color: var(--pl-color-fg);
2549
+ background: var(--pl-color-bg-raised);
2550
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
2551
+ border-radius: var(--pl-radius);
2552
+ box-shadow: var(--pl-shadow-popover);
2553
+ cursor: grabbing;
2554
+ }
2555
+
2556
+ /* ── Header (top bar) ─────────────────────────────────────────────────────────── */
2557
+ .pl-appshell__header {
2558
+ flex: 0 0 48px;
2559
+ height: 48px;
2560
+ display: flex;
2561
+ align-items: center;
2562
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
2563
+ background: var(--pl-color-bg-raised);
2564
+ }
2565
+ .pl-header {
2566
+ display: flex;
2567
+ align-items: center;
2568
+ gap: var(--pl-space-3);
2569
+ width: 100%;
2570
+ height: 100%;
2571
+ padding: 0 var(--pl-space-3);
2572
+ }
2573
+ .pl-header__brand {
2574
+ display: flex;
2575
+ align-items: center;
2576
+ gap: var(--pl-space-2);
2577
+ min-width: 0;
2578
+ }
2579
+ .pl-header__lockup {
2580
+ display: flex;
2581
+ flex-direction: column;
2582
+ justify-content: center;
2583
+ min-width: 0;
2584
+ line-height: 1.15;
2585
+ }
2586
+ .pl-header__name {
2587
+ overflow: hidden;
2588
+ font-size: 13px;
2589
+ font-weight: var(--pl-font-weight-medium);
2590
+ color: var(--pl-color-fg);
2591
+ text-overflow: ellipsis;
2592
+ white-space: nowrap;
2593
+ }
2594
+ .pl-header__org {
2595
+ font-family: var(--pl-font-mono);
2596
+ font-size: 10px;
2597
+ color: var(--pl-color-fg-muted);
2598
+ }
2599
+ .pl-header__spacer {
2600
+ flex: 1;
2601
+ }
2602
+ .pl-header__status {
2603
+ display: flex;
2604
+ align-items: center;
2605
+ }
2606
+ .pl-header__actions {
2607
+ display: flex;
2608
+ align-items: center;
2609
+ gap: var(--pl-space-2);
2610
+ }
2611
+
2612
+ /* ── ui component: theming.css ─────────────────────────────────────────────── */
2613
+ /* @protolabsai/ui — ThemePanel (live token editor). All --pl-* driven, so the
2614
+ panel itself re-skins live as you edit. */
2615
+
2616
+ .pl-theme-panel {
2617
+ display: flex;
2618
+ flex-direction: column;
2619
+ width: 100%;
2620
+ height: 100%;
2621
+ color: var(--pl-color-fg);
2622
+ font-size: 13px;
2623
+ background: var(--pl-color-bg-raised);
2624
+ border: var(--pl-border-width) solid var(--pl-color-border);
2625
+ border-radius: var(--pl-radius);
2626
+ }
2627
+ .pl-theme-panel__bar {
2628
+ display: flex;
2629
+ align-items: center;
2630
+ gap: var(--pl-space-3);
2631
+ padding: var(--pl-space-3);
2632
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
2633
+ }
2634
+ .pl-theme-panel__title {
2635
+ font-weight: var(--pl-font-weight-medium);
2636
+ }
2637
+ .pl-theme-panel__spacer {
2638
+ flex: 1;
2639
+ }
2640
+
2641
+ /* segmented light/dark control */
2642
+ .pl-segmented {
2643
+ display: inline-flex;
2644
+ padding: 2px;
2645
+ background: var(--pl-color-bg-inset);
2646
+ border: var(--pl-border-width) solid var(--pl-color-border);
2647
+ border-radius: var(--pl-radius);
2648
+ }
2649
+ .pl-segmented__btn {
2650
+ padding: 3px 12px;
2651
+ font: inherit;
2652
+ font-size: 12px;
2653
+ text-transform: capitalize;
2654
+ color: var(--pl-color-fg-muted);
2655
+ background: none;
2656
+ border: none;
2657
+ border-radius: calc(var(--pl-radius) - 1px);
2658
+ cursor: pointer;
2659
+ transition:
2660
+ background var(--pl-motion-fast) var(--pl-motion-ease),
2661
+ color var(--pl-motion-fast) var(--pl-motion-ease);
2662
+ }
2663
+ .pl-segmented__btn--active {
2664
+ color: var(--pl-color-fg);
2665
+ background: var(--pl-color-bg-raised);
2666
+ }
2667
+
2668
+ .pl-theme-panel__presets {
2669
+ display: flex;
2670
+ flex-wrap: wrap;
2671
+ align-items: center;
2672
+ gap: var(--pl-space-2);
2673
+ padding: var(--pl-space-3);
2674
+ border-bottom: var(--pl-border-width) solid var(--pl-color-border);
2675
+ }
2676
+ .pl-theme-panel__preset-select {
2677
+ flex: 1 1 140px;
2678
+ }
2679
+ .pl-theme-panel__preset-name {
2680
+ flex: 1 1 120px;
2681
+ }
2682
+
2683
+ .pl-theme-panel__groups {
2684
+ display: flex;
2685
+ flex-direction: column;
2686
+ flex: 1;
2687
+ min-height: 0;
2688
+ gap: var(--pl-space-4);
2689
+ padding: var(--pl-space-3);
2690
+ overflow-y: auto;
2691
+ }
2692
+ .pl-theme-group {
2693
+ margin: 0;
2694
+ padding: 0;
2695
+ border: none;
2696
+ }
2697
+ .pl-theme-group__legend {
2698
+ padding: 0 0 var(--pl-space-2);
2699
+ font-size: 10px;
2700
+ font-weight: var(--pl-font-weight-medium);
2701
+ text-transform: uppercase;
2702
+ letter-spacing: 0.06em;
2703
+ color: var(--pl-color-fg-subtle);
2704
+ }
2705
+ .pl-theme-row {
2706
+ display: flex;
2707
+ align-items: center;
2708
+ gap: var(--pl-space-2);
2709
+ padding: 3px 0;
2710
+ }
2711
+ .pl-theme-row__swatch {
2712
+ flex-shrink: 0;
2713
+ width: 22px;
2714
+ height: 22px;
2715
+ padding: 0;
2716
+ background: none;
2717
+ border: var(--pl-border-width) solid var(--pl-color-border-strong);
2718
+ border-radius: var(--pl-radius);
2719
+ cursor: pointer;
2720
+ }
2721
+ .pl-theme-row__swatch::-webkit-color-swatch-wrapper {
2722
+ padding: 0;
2723
+ }
2724
+ .pl-theme-row__swatch::-webkit-color-swatch {
2725
+ border: none;
2726
+ border-radius: calc(var(--pl-radius) - 1px);
2727
+ }
2728
+ .pl-theme-row__swatch::-moz-color-swatch {
2729
+ border: none;
2730
+ border-radius: calc(var(--pl-radius) - 1px);
2731
+ }
2732
+ .pl-theme-row__swatch--none {
2733
+ border-color: transparent;
2734
+ cursor: default;
2735
+ }
2736
+ .pl-theme-row__label {
2737
+ flex: 1;
2738
+ overflow: hidden;
2739
+ color: var(--pl-color-fg-muted);
2740
+ text-overflow: ellipsis;
2741
+ white-space: nowrap;
2742
+ }
2743
+ .pl-theme-row__value {
2744
+ flex-shrink: 0;
2745
+ width: 116px;
2746
+ padding: 3px 6px;
2747
+ font-family: var(--pl-font-mono);
2748
+ font-size: 11px;
2749
+ color: var(--pl-color-fg);
2750
+ background: var(--pl-color-bg-inset);
2751
+ border: var(--pl-border-width) solid var(--pl-color-border);
2752
+ border-radius: var(--pl-radius);
2753
+ }
2754
+ .pl-theme-row__value:focus-visible {
2755
+ outline: 2px solid var(--pl-color-focus);
2756
+ outline-offset: -1px;
2757
+ }
2758
+ .pl-theme-row--changed .pl-theme-row__label {
2759
+ color: var(--pl-color-fg);
2760
+ }
2761
+ .pl-theme-row--changed .pl-theme-row__value {
2762
+ border-color: var(--pl-color-accent);
2763
+ }