great-cto 3.2.0 → 3.4.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.
|
@@ -123,17 +123,106 @@
|
|
|
123
123
|
--shadow-card-hover: 0 1px 3px rgba(0, 0, 0, 0.12), 0 8px 24px rgba(0, 168, 98, 0.08);
|
|
124
124
|
--drawer-shadow: 0 16px 32px rgba(0, 0, 0, 0.18);
|
|
125
125
|
}
|
|
126
|
+
/* ── Type scale ──────────────────────────────────────────────────────────────
|
|
127
|
+
The board had 22 raw font sizes (9px…52px, including 11.5/12.5/13.5) and no
|
|
128
|
+
rule for h1/h2/h3 at all — so Budgets, Docs, Sessions and Activity rendered
|
|
129
|
+
their titles in the browser's default bold 700, a weight used nowhere else in
|
|
130
|
+
the design. One role, six renderings.
|
|
131
|
+
|
|
132
|
+
Two ramps, because the board has two kinds of text. Text steps by +1px in the
|
|
133
|
+
dense band (this is a single-operator console; density is the point) and by
|
|
134
|
+
~1.2x in the title band. Live numbers get their own ramp: they are read as
|
|
135
|
+
quantities, not prose, so they take --serif at 500 with tabular-nums.
|
|
136
|
+
|
|
137
|
+
--serif is NOT a serif face — it resolves to the same Geist as --sans. The
|
|
138
|
+
name is legacy; the role is "display numerals". Reach for it only at >=24px.
|
|
139
|
+
|
|
140
|
+
Legal 10px: --fs-eyebrow, and only for mono uppercase labels with tracking.
|
|
141
|
+
10px in sans body text is not a size, it is a mistake. */
|
|
142
|
+
:root {
|
|
143
|
+
--fs-eyebrow: 10px; /* mono uppercase label, tracking 0.08–0.1em */
|
|
144
|
+
--fs-caption: 11px; /* metadata, counts, timestamps */
|
|
145
|
+
--fs-small: 12px; /* table cells, secondary meta, chips */
|
|
146
|
+
--fs-body: 13px; /* dense body: cards, list rows, form fields */
|
|
147
|
+
--fs-base: 14px; /* document base / longform prose */
|
|
148
|
+
--fs-title-s: 15px; /* card or section heading (h3 role) */
|
|
149
|
+
--fs-title-m: 18px; /* region heading (h2 role) */
|
|
150
|
+
--fs-title-l: 22px; /* page heading (h1 role) */
|
|
151
|
+
|
|
152
|
+
--fs-num-s: 24px; /* inline stat */
|
|
153
|
+
--fs-num-m: 30px; /* secondary metric card */
|
|
154
|
+
--fs-num-l: 36px; /* second-tier hero KPI */
|
|
155
|
+
--fs-num-xl: 52px; /* primary hero KPI */
|
|
156
|
+
}
|
|
157
|
+
|
|
126
158
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
127
159
|
html, body { height: 100%; }
|
|
128
160
|
body {
|
|
129
161
|
font-family: var(--sans);
|
|
130
162
|
color: var(--text);
|
|
131
|
-
font-size:
|
|
163
|
+
font-size: var(--fs-base);
|
|
132
164
|
line-height: 1.5;
|
|
133
165
|
-webkit-font-smoothing: antialiased;
|
|
134
166
|
background: var(--bg-card);
|
|
135
167
|
}
|
|
136
|
-
|
|
168
|
+
/* Form controls do not inherit type from the page — they start at the browser's
|
|
169
|
+
own font, and `font-family: inherit` alone fixed only half of that. The size
|
|
170
|
+
stayed at the UA default 13.333px: off every step of the scale, on nine inputs
|
|
171
|
+
and four buttons, including the fields the CTO actually types into. A scale
|
|
172
|
+
that the text you enter does not follow is not the page's scale.
|
|
173
|
+
|
|
174
|
+
Bare-element specificity (0,0,1), so every component rule below still wins —
|
|
175
|
+
this only supplies a floor where nothing else speaks. */
|
|
176
|
+
button, input, select, textarea {
|
|
177
|
+
font-family: inherit;
|
|
178
|
+
font-size: var(--fs-body);
|
|
179
|
+
}
|
|
180
|
+
button { cursor: pointer; }
|
|
181
|
+
|
|
182
|
+
/* Headings had no base rule, so every unstyled h1/h2/h3 fell to the browser's
|
|
183
|
+
bold 700. Three weights exist in this design — 400 body, 500 value, 600 title
|
|
184
|
+
— and 700 is not one of them. This removes it everywhere at once. Bare-element
|
|
185
|
+
specificity (0,0,1), so every component rule below still wins. */
|
|
186
|
+
h1, h2, h3, h4 { font-weight: 600; font-family: var(--sans); }
|
|
187
|
+
|
|
188
|
+
/* The page's own title. Present on every panel, one size, one weight. Before
|
|
189
|
+
this, two panels had no title element at all, four rendered the browser
|
|
190
|
+
default, and one rendered a section heading at title size. */
|
|
191
|
+
.page-title {
|
|
192
|
+
font-size: var(--fs-title-l);
|
|
193
|
+
font-weight: 600;
|
|
194
|
+
line-height: 1.25;
|
|
195
|
+
letter-spacing: -0.02em;
|
|
196
|
+
color: var(--text);
|
|
197
|
+
margin: 0 0 14px;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* A heading INSIDE a page. Notifications rendered its three sections through
|
|
201
|
+
.share-card h2 — the showcase hero — so "Email alerts" was set at 28px, the
|
|
202
|
+
size of a page title, three times on one screen. */
|
|
203
|
+
.section-title {
|
|
204
|
+
font-size: var(--fs-title-m);
|
|
205
|
+
font-weight: 600;
|
|
206
|
+
line-height: 1.3;
|
|
207
|
+
letter-spacing: -0.01em;
|
|
208
|
+
color: var(--text);
|
|
209
|
+
margin: 0 0 6px;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* Sessions had a .panel-head element with no rule of any kind: its h2 fell to
|
|
213
|
+
the browser default of 1.5em bold-700 and the search box beside it did not
|
|
214
|
+
align to anything. */
|
|
215
|
+
.panel-head {
|
|
216
|
+
display: flex; align-items: center; gap: 12px;
|
|
217
|
+
margin: 0 0 14px; flex-wrap: wrap;
|
|
218
|
+
}
|
|
219
|
+
.panel-head h2 {
|
|
220
|
+
font-size: var(--fs-title-l);
|
|
221
|
+
letter-spacing: -0.02em;
|
|
222
|
+
line-height: 1.25;
|
|
223
|
+
margin: 0; flex: 1 1 auto;
|
|
224
|
+
}
|
|
225
|
+
|
|
137
226
|
|
|
138
227
|
.board {
|
|
139
228
|
position: relative;
|
|
@@ -159,16 +248,16 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
159
248
|
background: rgba(180, 83, 9, 0.10);
|
|
160
249
|
border: 1px solid var(--status-progress);
|
|
161
250
|
border-radius: 8px;
|
|
162
|
-
font-size:
|
|
251
|
+
font-size: var(--fs-body); color: var(--text);
|
|
163
252
|
}
|
|
164
|
-
.stale-board code { font-family: var(--mono); font-size:
|
|
253
|
+
.stale-board code { font-family: var(--mono); font-size: var(--fs-small); }
|
|
165
254
|
|
|
166
255
|
/* Per-agent budget. Four states, and they must not look alike: `exceeded` holds
|
|
167
256
|
a dispatch, `unmeasured` deliberately does not. A shared grey chip for
|
|
168
257
|
"under the cap" and "we never measured it" would be the same silent zero this
|
|
169
258
|
board spends its time refusing to render. */
|
|
170
259
|
.budget-chip {
|
|
171
|
-
font-family: var(--mono); font-size:
|
|
260
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
172
261
|
padding: 1px 6px; border-radius: 3px;
|
|
173
262
|
border: 1px solid var(--border);
|
|
174
263
|
white-space: nowrap;
|
|
@@ -187,11 +276,11 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
187
276
|
.ab-row:first-of-type { border-top: 0; }
|
|
188
277
|
.ab-name { font-family: var(--mono); flex: 1 1 auto; min-width: 0; }
|
|
189
278
|
.ab-cap { font-family: var(--mono); color: var(--text2); }
|
|
190
|
-
.ab-spent { font-family: var(--mono); font-size:
|
|
191
|
-
.ab-note { margin-top: 8px; font-size:
|
|
279
|
+
.ab-spent { font-family: var(--mono); font-size: var(--fs-caption); color: var(--text3); }
|
|
280
|
+
.ab-note { margin-top: 8px; font-size: var(--fs-caption); color: var(--status-progress); }
|
|
192
281
|
.ab-note.ab-bad { color: var(--status-blocked); }
|
|
193
282
|
.ab-btn {
|
|
194
|
-
font-family: inherit; font-size:
|
|
283
|
+
font-family: inherit; font-size: var(--fs-caption);
|
|
195
284
|
min-height: 24px; padding: 0 8px;
|
|
196
285
|
border: 1px solid var(--border); border-radius: 5px;
|
|
197
286
|
background: var(--bg-card); color: var(--text2);
|
|
@@ -203,7 +292,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
203
292
|
|
|
204
293
|
.budget-line {
|
|
205
294
|
margin: -18px 0 24px; padding: 8px 12px;
|
|
206
|
-
border-radius: 8px; font-size:
|
|
295
|
+
border-radius: 8px; font-size: var(--fs-small);
|
|
207
296
|
border: 1px solid var(--border);
|
|
208
297
|
}
|
|
209
298
|
.budget-line.exceeded { color: var(--status-blocked); border-color: var(--status-blocked); background: var(--p0-bg); font-weight: 500; }
|
|
@@ -263,7 +352,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
263
352
|
.sidebar-brand .brand-mark svg { width: 22px; height: 22px; }
|
|
264
353
|
.sidebar-brand .brand-name {
|
|
265
354
|
font-family: var(--serif); font-weight: 600;
|
|
266
|
-
font-size:
|
|
355
|
+
font-size: var(--fs-title-s); letter-spacing: -0.01em;
|
|
267
356
|
color: var(--text);
|
|
268
357
|
}
|
|
269
358
|
.proj-switch {
|
|
@@ -276,9 +365,9 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
276
365
|
}
|
|
277
366
|
.proj-switch:hover { background: var(--bg-muted); }
|
|
278
367
|
.proj-switch .star { color: var(--accent); font-size: 16px; }
|
|
279
|
-
.proj-switch .name { font-weight: 600; font-size:
|
|
368
|
+
.proj-switch .name { font-weight: 600; font-size: var(--fs-base); }
|
|
280
369
|
.proj-switch .sw-meta { flex: 1; display: flex; flex-direction: column; gap: 1px; }
|
|
281
|
-
.proj-switch .sw-arch { font-size:
|
|
370
|
+
.proj-switch .sw-arch { font-size: var(--fs-eyebrow); color: var(--text3); font-weight: 400; letter-spacing: 0.03em; }
|
|
282
371
|
.proj-switch .chev {
|
|
283
372
|
color: var(--text3); width: 12px; height: 12px;
|
|
284
373
|
transition: transform 0.15s;
|
|
@@ -306,7 +395,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
306
395
|
}
|
|
307
396
|
.proj-menu-search input {
|
|
308
397
|
flex: 1; border: none; outline: none;
|
|
309
|
-
font-family: inherit; font-size:
|
|
398
|
+
font-family: inherit; font-size: var(--fs-small);
|
|
310
399
|
color: var(--text); background: transparent;
|
|
311
400
|
}
|
|
312
401
|
.proj-item {
|
|
@@ -314,11 +403,11 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
314
403
|
padding: 8px 10px;
|
|
315
404
|
border-radius: 5px;
|
|
316
405
|
cursor: pointer;
|
|
317
|
-
font-size:
|
|
406
|
+
font-size: var(--fs-body);
|
|
318
407
|
}
|
|
319
408
|
.proj-item:hover { background: var(--bg-muted); }
|
|
320
409
|
.proj-item.active { background: var(--bg-strong); font-weight: 500; }
|
|
321
|
-
.proj-item .star { color: var(--accent); font-size:
|
|
410
|
+
.proj-item .star { color: var(--accent); font-size: var(--fs-base); }
|
|
322
411
|
.proj-icon, .proj-switch .proj-icon, .crumbs .proj-icon {
|
|
323
412
|
display: inline-flex; align-items: center; justify-content: center;
|
|
324
413
|
flex-shrink: 0;
|
|
@@ -327,9 +416,9 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
327
416
|
.proj-item .proj-icon { width: 22px; height: 22px; }
|
|
328
417
|
.crumbs .proj-icon { width: 14px; height: 14px; margin-right: 2px; }
|
|
329
418
|
.proj-item-info { flex: 1; min-width: 0; }
|
|
330
|
-
.proj-item-info .name { font-weight: 500; font-size:
|
|
419
|
+
.proj-item-info .name { font-weight: 500; font-size: var(--fs-body); }
|
|
331
420
|
.proj-item-info .arch {
|
|
332
|
-
font-family: var(--mono); font-size:
|
|
421
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
333
422
|
color: var(--text3);
|
|
334
423
|
letter-spacing: 0.04em;
|
|
335
424
|
}
|
|
@@ -341,7 +430,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
341
430
|
.proj-menu-empty {
|
|
342
431
|
padding: 14px 10px;
|
|
343
432
|
text-align: center;
|
|
344
|
-
font-size:
|
|
433
|
+
font-size: var(--fs-small);
|
|
345
434
|
color: var(--text3);
|
|
346
435
|
}
|
|
347
436
|
|
|
@@ -350,7 +439,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
350
439
|
display: flex; align-items: center; gap: 10px;
|
|
351
440
|
height: 32px; padding: 0 10px;
|
|
352
441
|
border-radius: 6px;
|
|
353
|
-
font-size:
|
|
442
|
+
font-size: var(--fs-body);
|
|
354
443
|
color: var(--text);
|
|
355
444
|
cursor: pointer;
|
|
356
445
|
position: relative;
|
|
@@ -368,14 +457,14 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
368
457
|
}
|
|
369
458
|
.nav-item .icon { width: 16px; height: 16px; color: var(--text2); flex-shrink: 0; }
|
|
370
459
|
.nav-item.active .icon { color: var(--accent); }
|
|
371
|
-
.nav-item .count { margin-left: auto; font-size:
|
|
460
|
+
.nav-item .count { margin-left: auto; font-size: var(--fs-caption); color: var(--text3); font-family: var(--mono); }
|
|
372
461
|
.nav-divider { height: 1px; background: var(--border); margin: 12px 8px; }
|
|
373
462
|
|
|
374
463
|
.sidebar-footer {
|
|
375
464
|
padding: 12px 16px;
|
|
376
465
|
border-top: 1px solid var(--border);
|
|
377
466
|
font-family: var(--mono);
|
|
378
|
-
font-size:
|
|
467
|
+
font-size: var(--fs-caption);
|
|
379
468
|
color: var(--text3);
|
|
380
469
|
letter-spacing: 0.04em;
|
|
381
470
|
display: flex; align-items: center; gap: 6px;
|
|
@@ -395,7 +484,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
395
484
|
border-bottom: 1px solid var(--border);
|
|
396
485
|
display: flex; align-items: center; justify-content: space-between;
|
|
397
486
|
padding: 0 20px;
|
|
398
|
-
font-size:
|
|
487
|
+
font-size: var(--fs-body);
|
|
399
488
|
}
|
|
400
489
|
.crumbs { display: flex; align-items: center; gap: 8px; color: var(--text2); }
|
|
401
490
|
.crumbs .star { color: var(--accent); }
|
|
@@ -416,12 +505,12 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
416
505
|
.search-box svg { color: var(--text3); flex-shrink: 0; }
|
|
417
506
|
.search-box input {
|
|
418
507
|
flex: 1; border: none; outline: none; background: transparent;
|
|
419
|
-
font-family: inherit; font-size:
|
|
508
|
+
font-family: inherit; font-size: var(--fs-body);
|
|
420
509
|
color: var(--text); padding: 3px 0;
|
|
421
510
|
}
|
|
422
511
|
.search-box input::placeholder { color: var(--text3); }
|
|
423
512
|
.search-box kbd {
|
|
424
|
-
font-family: var(--mono); font-size:
|
|
513
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
425
514
|
color: var(--text3);
|
|
426
515
|
background: var(--bg-strong);
|
|
427
516
|
border-radius: 3px; padding: 1px 5px;
|
|
@@ -438,7 +527,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
438
527
|
.btn-bell-badge {
|
|
439
528
|
position: absolute; top: -5px; right: -5px;
|
|
440
529
|
background: var(--accent); color: #04140d;
|
|
441
|
-
font-size:
|
|
530
|
+
font-size: var(--fs-eyebrow); font-weight: 700; line-height: 1;
|
|
442
531
|
min-width: 16px; height: 16px; border-radius: 8px;
|
|
443
532
|
display: none; align-items: center; justify-content: center;
|
|
444
533
|
padding: 0 3px;
|
|
@@ -448,7 +537,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
448
537
|
.tab-btn {
|
|
449
538
|
background: transparent; border: none;
|
|
450
539
|
padding: 6px 12px; border-radius: 6px;
|
|
451
|
-
font-size:
|
|
540
|
+
font-size: var(--fs-body); color: var(--text2);
|
|
452
541
|
}
|
|
453
542
|
.tab-btn:hover { background: var(--bg-muted); color: var(--text); }
|
|
454
543
|
.tab-btn.active { background: var(--bg-strong); color: var(--text); font-weight: 500; }
|
|
@@ -469,13 +558,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
469
558
|
background: #0f1115; color: #fff; border: none;
|
|
470
559
|
height: 30px; padding: 0 14px;
|
|
471
560
|
border-radius: 999px;
|
|
472
|
-
font-size:
|
|
561
|
+
font-size: var(--fs-body); font-weight: 500;
|
|
473
562
|
display: inline-flex; align-items: center; gap: 6px;
|
|
474
563
|
}
|
|
475
564
|
.btn-new:hover { background: #2a2d33; }
|
|
476
565
|
|
|
477
566
|
.task-count {
|
|
478
|
-
font-family: var(--mono); font-size:
|
|
567
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
479
568
|
color: var(--text3); letter-spacing: 0.04em;
|
|
480
569
|
margin-right: 6px;
|
|
481
570
|
}
|
|
@@ -505,7 +594,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
505
594
|
.col-head {
|
|
506
595
|
display: flex; align-items: center; gap: 8px;
|
|
507
596
|
padding: 4px 6px 8px;
|
|
508
|
-
font-size:
|
|
597
|
+
font-size: var(--fs-body); font-weight: 600;
|
|
509
598
|
}
|
|
510
599
|
.col-dot {
|
|
511
600
|
width: 10px; height: 10px; border-radius: 50%;
|
|
@@ -515,7 +604,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
515
604
|
.col-dot.filled { background: currentColor; }
|
|
516
605
|
.col-dot.half { background: conic-gradient(currentColor 50%, transparent 50%); }
|
|
517
606
|
.col-count {
|
|
518
|
-
font-family: var(--mono); font-size:
|
|
607
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
519
608
|
color: var(--text3); margin-left: 2px; font-weight: 500;
|
|
520
609
|
}
|
|
521
610
|
.col-title { color: var(--text); }
|
|
@@ -537,7 +626,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
537
626
|
overflow: hidden;
|
|
538
627
|
}
|
|
539
628
|
.card-desc {
|
|
540
|
-
font-size:
|
|
629
|
+
font-size: var(--fs-small);
|
|
541
630
|
line-height: 1.4;
|
|
542
631
|
color: var(--text2);
|
|
543
632
|
display: -webkit-box;
|
|
@@ -549,12 +638,12 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
549
638
|
.card:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-1px); }
|
|
550
639
|
.card.selected { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
|
|
551
640
|
.card .id {
|
|
552
|
-
font-family: var(--mono); font-size:
|
|
641
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
553
642
|
letter-spacing: 0.04em; color: var(--text3);
|
|
554
643
|
flex-shrink: 0;
|
|
555
644
|
}
|
|
556
645
|
.card .title {
|
|
557
|
-
font-weight: 600; font-size:
|
|
646
|
+
font-weight: 600; font-size: var(--fs-body);
|
|
558
647
|
line-height: 1.35;
|
|
559
648
|
color: var(--text);
|
|
560
649
|
display: -webkit-box;
|
|
@@ -577,7 +666,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
577
666
|
.card-footer > * { flex-shrink: 0; }
|
|
578
667
|
.card-time {
|
|
579
668
|
margin-left: auto;
|
|
580
|
-
font-family: var(--mono); font-size:
|
|
669
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
581
670
|
color: var(--text3);
|
|
582
671
|
}
|
|
583
672
|
|
|
@@ -585,7 +674,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
585
674
|
display: inline-flex; align-items: center; gap: 4px;
|
|
586
675
|
height: 20px; padding: 0 8px;
|
|
587
676
|
border-radius: 999px;
|
|
588
|
-
font-size:
|
|
677
|
+
font-size: var(--fs-caption); font-weight: 500;
|
|
589
678
|
background: var(--bg-strong); color: var(--text2);
|
|
590
679
|
}
|
|
591
680
|
.chip-p0 { background: var(--p0-bg); color: var(--p0-fg); }
|
|
@@ -609,7 +698,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
609
698
|
height: 24px;
|
|
610
699
|
border: 1px solid var(--border);
|
|
611
700
|
border-radius: 5px;
|
|
612
|
-
font-family: inherit; font-size:
|
|
701
|
+
font-family: inherit; font-size: var(--fs-caption); font-weight: 500;
|
|
613
702
|
cursor: pointer;
|
|
614
703
|
background: var(--bg-card);
|
|
615
704
|
transition: background 0.12s, border-color 0.12s;
|
|
@@ -627,14 +716,14 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
627
716
|
#agent-panel { position: fixed; right: 16px; bottom: 16px; width: min(560px, 94vw); max-height: 70vh; display: none; flex-direction: column; background: var(--bg-card, #11161a); border: 1px solid var(--border, #1f2a26); border-radius: 12px; box-shadow: 0 24px 70px rgba(0,0,0,.5); z-index: 60; overflow: hidden; }
|
|
628
717
|
#agent-panel.open { display: flex; }
|
|
629
718
|
#agent-panel header { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--border, #1f2a26); background: transparent; }
|
|
630
|
-
#agent-panel header b { font-size:
|
|
631
|
-
#agent-panel .ap-x { margin-left: auto; cursor: pointer; border: 0; background: none; color: var(--
|
|
719
|
+
#agent-panel header b { font-size: var(--fs-body); }
|
|
720
|
+
#agent-panel .ap-x { margin-left: auto; cursor: pointer; border: 0; background: none; color: var(--text3); font-size: 16px; }
|
|
632
721
|
#agent-log { flex: 1; overflow: auto; padding: 10px 14px; font: 12px/1.55 ui-monospace, Menlo, monospace; }
|
|
633
722
|
#agent-log .al { margin: 2px 0; white-space: pre-wrap; word-break: break-word; }
|
|
634
|
-
#agent-log .al.tool { color: var(--status-review); } #agent-log .al.system { color: var(--
|
|
723
|
+
#agent-log .al.tool { color: var(--status-review); } #agent-log .al.system { color: var(--text3); } #agent-log .al.error { color: var(--status-blocked, #ff5a5a); } #agent-log .al.done { color: var(--text3); font-weight: 600; }
|
|
635
724
|
#agent-panel .ap-foot { display: flex; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--border, #1f2a26); }
|
|
636
|
-
#agent-panel input { flex: 1; background: var(--bg
|
|
637
|
-
#agent-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--
|
|
725
|
+
#agent-panel input { flex: 1; background: var(--bg-muted); color: var(--text, #ecf2ee); border: 1px solid var(--border, #1f2a26); border-radius: 8px; padding: 7px 10px; font: inherit; font-size: var(--fs-body); }
|
|
726
|
+
#agent-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text3); }
|
|
638
727
|
#agent-dot.live { background: var(--status-review); animation: apulse 1.2s infinite; }
|
|
639
728
|
@keyframes apulse { 0%,100%{opacity:1} 50%{opacity:.4} }
|
|
640
729
|
.gate-reject { color: var(--status-blocked); border-color: rgba(220, 38, 38, 0.30); }
|
|
@@ -657,7 +746,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
657
746
|
|
|
658
747
|
.empty {
|
|
659
748
|
padding: 20px 8px;
|
|
660
|
-
font-size:
|
|
749
|
+
font-size: var(--fs-small);
|
|
661
750
|
color: var(--text3);
|
|
662
751
|
text-align: center;
|
|
663
752
|
}
|
|
@@ -674,10 +763,10 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
674
763
|
border-left-width: 3px;
|
|
675
764
|
border-radius: 6px;
|
|
676
765
|
background: rgba(240, 180, 41, 0.08);
|
|
677
|
-
font-size:
|
|
766
|
+
font-size: var(--fs-small);
|
|
678
767
|
line-height: 1.45;
|
|
679
768
|
}
|
|
680
|
-
.degraded-banner strong { color: var(--
|
|
769
|
+
.degraded-banner strong { color: var(--text); font-weight: 600; }
|
|
681
770
|
.degraded-banner span { color: var(--text2); font-family: var(--mono, ui-monospace, monospace); word-break: break-word; }
|
|
682
771
|
|
|
683
772
|
/* ── Side panel ───────────────────────────────────────────────────────────── */
|
|
@@ -718,7 +807,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
718
807
|
border-bottom: 1px solid var(--border);
|
|
719
808
|
}
|
|
720
809
|
.side-id {
|
|
721
|
-
font-family: var(--mono); font-size:
|
|
810
|
+
font-family: var(--mono); font-size: var(--fs-caption); font-weight: 500;
|
|
722
811
|
background: var(--bg-strong); color: var(--text);
|
|
723
812
|
padding: 4px 8px; border-radius: 4px;
|
|
724
813
|
letter-spacing: 0.04em;
|
|
@@ -733,14 +822,14 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
733
822
|
.side-close:hover { background: var(--bg-muted); color: var(--text); }
|
|
734
823
|
.side-body { flex: 1; overflow: auto; padding: 18px; }
|
|
735
824
|
.side-title {
|
|
736
|
-
font-family: var(--
|
|
737
|
-
font-size:
|
|
738
|
-
letter-spacing: -0.
|
|
825
|
+
font-family: var(--sans); font-weight: 600;
|
|
826
|
+
font-size: var(--fs-title-m);
|
|
827
|
+
letter-spacing: -0.01em;
|
|
739
828
|
margin-bottom: 12px;
|
|
740
829
|
color: var(--text);
|
|
741
830
|
}
|
|
742
831
|
.side-desc {
|
|
743
|
-
font-size:
|
|
832
|
+
font-size: var(--fs-base); line-height: 1.6;
|
|
744
833
|
color: var(--text2);
|
|
745
834
|
margin-bottom: 16px;
|
|
746
835
|
padding-bottom: 14px;
|
|
@@ -751,30 +840,30 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
751
840
|
.side-desc-empty {
|
|
752
841
|
color: var(--text3, #9ca3af);
|
|
753
842
|
font-style: italic;
|
|
754
|
-
font-size:
|
|
843
|
+
font-size: var(--fs-body);
|
|
755
844
|
}
|
|
756
845
|
.side-desc-empty code {
|
|
757
846
|
font-style: normal;
|
|
758
847
|
background: var(--bg-muted);
|
|
759
848
|
padding: 1px 5px;
|
|
760
849
|
border-radius: 3px;
|
|
761
|
-
font-size:
|
|
850
|
+
font-size: var(--fs-small);
|
|
762
851
|
}
|
|
763
852
|
.side-desc.md { white-space: normal; }
|
|
764
853
|
.side-desc.md h1 { font-size: 16px; margin: 8px 0 6px; font-weight: 600; }
|
|
765
|
-
.side-desc.md h2 { font-size:
|
|
766
|
-
.side-desc.md h3 { font-size:
|
|
767
|
-
.side-desc.md h4 { font-size:
|
|
854
|
+
.side-desc.md h2 { font-size: var(--fs-base); margin: 10px 0 4px; font-weight: 600; color: var(--text); }
|
|
855
|
+
.side-desc.md h3 { font-size: var(--fs-body); margin: 8px 0 3px; font-weight: 600; color: var(--text); }
|
|
856
|
+
.side-desc.md h4 { font-size: var(--fs-small); margin: 6px 0 2px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text2); }
|
|
768
857
|
.side-desc.md p { margin: 0 0 8px; }
|
|
769
858
|
.side-desc.md ul { padding-left: 18px; margin: 4px 0 8px; }
|
|
770
859
|
.side-desc.md li { margin: 2px 0; }
|
|
771
860
|
.side-desc.md code {
|
|
772
861
|
background: var(--bg-muted); padding: 1px 4px;
|
|
773
|
-
border-radius: 3px; font-size:
|
|
862
|
+
border-radius: 3px; font-size: var(--fs-small); font-family: ui-monospace, monospace;
|
|
774
863
|
}
|
|
775
864
|
.side-desc.md pre.md-pre {
|
|
776
865
|
background: var(--bg-muted); padding: 8px 10px;
|
|
777
|
-
border-radius: 4px; overflow-x: auto; font-size:
|
|
866
|
+
border-radius: 4px; overflow-x: auto; font-size: var(--fs-small);
|
|
778
867
|
margin: 6px 0;
|
|
779
868
|
}
|
|
780
869
|
.side-desc.md pre.md-pre code { background: none; padding: 0; }
|
|
@@ -796,7 +885,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
796
885
|
.toast {
|
|
797
886
|
background: #1f2937; color: #fff;
|
|
798
887
|
padding: 8px 14px; border-radius: 6px;
|
|
799
|
-
font-size:
|
|
888
|
+
font-size: var(--fs-body); min-width: 200px; max-width: 360px;
|
|
800
889
|
box-shadow: 0 4px 16px rgba(0,0,0,0.35);
|
|
801
890
|
opacity: 0; transform: translateY(8px);
|
|
802
891
|
transition: opacity 0.2s, transform 0.2s;
|
|
@@ -826,7 +915,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
826
915
|
#cmdk-input {
|
|
827
916
|
border: 0; border-bottom: 1px solid var(--border);
|
|
828
917
|
background: transparent; color: var(--text);
|
|
829
|
-
font-family: inherit; font-size:
|
|
918
|
+
font-family: inherit; font-size: var(--fs-title-s); padding: 14px 16px; outline: none;
|
|
830
919
|
}
|
|
831
920
|
#cmdk-list { overflow-y: auto; padding: 6px; }
|
|
832
921
|
.cmdk-item {
|
|
@@ -836,14 +925,14 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
836
925
|
}
|
|
837
926
|
.cmdk-item.on { background: var(--bg-muted); }
|
|
838
927
|
.cmdk-group {
|
|
839
|
-
font-family: var(--mono); font-size:
|
|
928
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow); letter-spacing: 0.06em;
|
|
840
929
|
text-transform: uppercase; color: var(--text3);
|
|
841
930
|
min-width: 34px; flex-shrink: 0;
|
|
842
931
|
}
|
|
843
|
-
.cmdk-label { font-size:
|
|
932
|
+
.cmdk-label { font-size: var(--fs-body); color: var(--text); flex: 1; min-width: 0;
|
|
844
933
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
845
|
-
.cmdk-hint { font-family: var(--mono); font-size:
|
|
846
|
-
.cmdk-empty { padding: 18px 14px; font-size:
|
|
934
|
+
.cmdk-hint { font-family: var(--mono); font-size: var(--fs-caption); color: var(--text3); flex-shrink: 0; }
|
|
935
|
+
.cmdk-empty { padding: 18px 14px; font-size: var(--fs-body); color: var(--text2); }
|
|
847
936
|
|
|
848
937
|
#hotkey-modal {
|
|
849
938
|
position: fixed; inset: 0; z-index: 10000;
|
|
@@ -853,21 +942,21 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
853
942
|
position: absolute; inset: 0; background: rgba(0,0,0,0.5);
|
|
854
943
|
}
|
|
855
944
|
.hk-card {
|
|
856
|
-
position: relative; background: var(--bg
|
|
945
|
+
position: relative; background: var(--bg-elevated);
|
|
857
946
|
color: var(--text); border: 1px solid var(--border);
|
|
858
947
|
border-radius: 8px; padding: 20px 24px; min-width: 360px;
|
|
859
948
|
box-shadow: 0 12px 32px rgba(0,0,0,0.5);
|
|
860
949
|
}
|
|
861
|
-
.hk-title { font-size:
|
|
950
|
+
.hk-title { font-size: var(--fs-title-s); font-weight: 600; margin-bottom: 12px; }
|
|
862
951
|
.hk-table { border-collapse: collapse; width: 100%; }
|
|
863
|
-
.hk-table td { padding: 4px 8px; font-size:
|
|
952
|
+
.hk-table td { padding: 4px 8px; font-size: var(--fs-body); }
|
|
864
953
|
.hk-table td:first-child { text-align: right; white-space: nowrap; color: var(--text2); }
|
|
865
954
|
.hk-table kbd {
|
|
866
955
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
867
|
-
border-radius: 3px; padding: 1px 5px; font-size:
|
|
956
|
+
border-radius: 3px; padding: 1px 5px; font-size: var(--fs-caption);
|
|
868
957
|
font-family: ui-monospace, monospace; color: var(--text);
|
|
869
958
|
}
|
|
870
|
-
.hk-foot { margin-top: 12px; font-size:
|
|
959
|
+
.hk-foot { margin-top: 12px; font-size: var(--fs-caption); color: var(--text3, #9ca3af); text-align: center; }
|
|
871
960
|
|
|
872
961
|
/* ── Resume detail modal (clickable verdicts + decisions) ───────────── */
|
|
873
962
|
#resume-detail-modal {
|
|
@@ -876,7 +965,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
876
965
|
}
|
|
877
966
|
.rdm-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.5); }
|
|
878
967
|
.rdm-card {
|
|
879
|
-
position: relative; background: var(--bg
|
|
968
|
+
position: relative; background: var(--bg-elevated);
|
|
880
969
|
color: var(--text); border: 1px solid var(--border);
|
|
881
970
|
border-radius: 8px; padding: 18px 22px; min-width: 480px; max-width: 720px;
|
|
882
971
|
box-shadow: 0 12px 32px rgba(0,0,0,0.5);
|
|
@@ -885,30 +974,30 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
885
974
|
.rdm-head .rdm-agent { font-weight: 600; }
|
|
886
975
|
.rdm-head .rdm-verdict.ok { color: #4ade80; }
|
|
887
976
|
.rdm-head .rdm-verdict.fail { color: #f87171; }
|
|
888
|
-
.rdm-head .rdm-ts { color: var(--text2); font-size:
|
|
977
|
+
.rdm-head .rdm-ts { color: var(--text2); font-size: var(--fs-caption); margin-left: auto; }
|
|
889
978
|
.rdm-raw {
|
|
890
979
|
background: var(--bg-muted); padding: 8px 10px; border-radius: 4px;
|
|
891
|
-
font-family: ui-monospace, monospace; font-size:
|
|
980
|
+
font-family: ui-monospace, monospace; font-size: var(--fs-small);
|
|
892
981
|
white-space: pre-wrap; word-break: break-all;
|
|
893
982
|
border: 1px solid var(--border);
|
|
894
983
|
max-height: 200px; overflow-y: auto;
|
|
895
984
|
}
|
|
896
985
|
.rdm-artefacts { margin-top: 12px; }
|
|
897
|
-
.rdm-artefacts-title { font-size:
|
|
986
|
+
.rdm-artefacts-title { font-size: var(--fs-caption); color: var(--text2); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
|
|
898
987
|
.rdm-artefact {
|
|
899
988
|
display: inline-flex; align-items: center; gap: 4px;
|
|
900
989
|
margin: 2px 4px 2px 0; padding: 4px 8px;
|
|
901
990
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
902
|
-
border-radius: 4px; font-size:
|
|
991
|
+
border-radius: 4px; font-size: var(--fs-small); cursor: pointer;
|
|
903
992
|
text-decoration: none; color: var(--text);
|
|
904
993
|
font-family: ui-monospace, monospace;
|
|
905
994
|
}
|
|
906
|
-
.rdm-artefact:hover { background: var(--bg-
|
|
995
|
+
.rdm-artefact:hover { background: var(--bg-muted); }
|
|
907
996
|
.rdm-artefact .rdm-art-kind {
|
|
908
|
-
font-size:
|
|
909
|
-
background: var(--accent-
|
|
997
|
+
font-size: var(--fs-eyebrow); padding: 1px 4px; border-radius: 3px;
|
|
998
|
+
background: var(--accent-soft); color: var(--accent-text);
|
|
910
999
|
}
|
|
911
|
-
.rdm-foot { margin-top: 12px; font-size:
|
|
1000
|
+
.rdm-foot { margin-top: 12px; font-size: var(--fs-caption); color: var(--text3, #9ca3af); }
|
|
912
1001
|
.resume-item { cursor: pointer; }
|
|
913
1002
|
.resume-item:hover { background: var(--bg-muted); border-radius: 4px; }
|
|
914
1003
|
|
|
@@ -937,9 +1026,9 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
937
1026
|
display: flex; align-items: center; justify-content: space-between;
|
|
938
1027
|
padding: 14px 18px; border-bottom: 1px solid var(--border);
|
|
939
1028
|
}
|
|
940
|
-
.ni-header h3 { font-size:
|
|
1029
|
+
.ni-header h3 { font-size: var(--fs-title-s); font-weight: 600; margin: 0; }
|
|
941
1030
|
.ni-close {
|
|
942
|
-
background: transparent; border: 0; color: var(--
|
|
1031
|
+
background: transparent; border: 0; color: var(--text3);
|
|
943
1032
|
cursor: pointer; padding: 4px; display: flex; border-radius: 4px;
|
|
944
1033
|
}
|
|
945
1034
|
.ni-close:hover { background: var(--bg-muted, rgba(255,255,255,0.06)); color: var(--text); }
|
|
@@ -952,8 +1041,8 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
952
1041
|
flex: 1;
|
|
953
1042
|
}
|
|
954
1043
|
.ni-label {
|
|
955
|
-
font-size:
|
|
956
|
-
text-transform: uppercase; letter-spacing: 0.
|
|
1044
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow); color: var(--text3);
|
|
1045
|
+
text-transform: uppercase; letter-spacing: 0.08em; font-weight: 500;
|
|
957
1046
|
}
|
|
958
1047
|
.ni-field input[type="text"],
|
|
959
1048
|
.ni-field textarea,
|
|
@@ -962,7 +1051,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
962
1051
|
border: 1px solid var(--border, #2a2d33);
|
|
963
1052
|
border-radius: 6px;
|
|
964
1053
|
color: var(--text);
|
|
965
|
-
font: inherit; font-size:
|
|
1054
|
+
font: inherit; font-size: var(--fs-body);
|
|
966
1055
|
padding: 8px 10px;
|
|
967
1056
|
outline: none;
|
|
968
1057
|
transition: border-color 120ms;
|
|
@@ -978,21 +1067,21 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
978
1067
|
.ni-row { display: flex; gap: 12px; }
|
|
979
1068
|
.ni-checkbox {
|
|
980
1069
|
flex-direction: row; align-items: center; gap: 8px;
|
|
981
|
-
font-size:
|
|
1070
|
+
font-size: var(--fs-body); cursor: pointer;
|
|
982
1071
|
}
|
|
983
1072
|
.ni-checkbox input { margin: 0; cursor: pointer; }
|
|
984
|
-
.ni-checkbox span { color: var(--
|
|
1073
|
+
.ni-checkbox span { color: var(--text2); }
|
|
985
1074
|
.ni-actions {
|
|
986
1075
|
display: flex; justify-content: flex-end; gap: 8px;
|
|
987
1076
|
margin-top: 4px;
|
|
988
1077
|
}
|
|
989
1078
|
.ni-btn {
|
|
990
1079
|
border: 1px solid transparent; border-radius: 6px;
|
|
991
|
-
padding: 7px 14px; font: inherit; font-size:
|
|
1080
|
+
padding: 7px 14px; font: inherit; font-size: var(--fs-body);
|
|
992
1081
|
cursor: pointer; transition: all 120ms;
|
|
993
1082
|
}
|
|
994
1083
|
.ni-btn-ghost {
|
|
995
|
-
background: transparent; color: var(--
|
|
1084
|
+
background: transparent; color: var(--text2);
|
|
996
1085
|
border-color: var(--border);
|
|
997
1086
|
}
|
|
998
1087
|
.ni-btn-ghost:hover { background: var(--bg-muted, rgba(255,255,255,0.05)); color: var(--text); }
|
|
@@ -1012,19 +1101,19 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1012
1101
|
.side-gate-actions .gate-btn {
|
|
1013
1102
|
flex: 1;
|
|
1014
1103
|
height: 36px;
|
|
1015
|
-
font-size:
|
|
1104
|
+
font-size: var(--fs-body); font-weight: 500;
|
|
1016
1105
|
padding: 0 14px;
|
|
1017
1106
|
}
|
|
1018
1107
|
.side-section {
|
|
1019
1108
|
margin-top: 18px;
|
|
1020
1109
|
}
|
|
1021
1110
|
.side-section-head {
|
|
1022
|
-
font-family: var(--mono); font-size:
|
|
1111
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1023
1112
|
letter-spacing: 0.1em; text-transform: uppercase;
|
|
1024
1113
|
color: var(--text3); margin-bottom: 6px;
|
|
1025
1114
|
}
|
|
1026
1115
|
.side-section-body {
|
|
1027
|
-
font-size:
|
|
1116
|
+
font-size: var(--fs-body); line-height: 1.5;
|
|
1028
1117
|
color: var(--text2);
|
|
1029
1118
|
white-space: pre-wrap;
|
|
1030
1119
|
word-break: break-word;
|
|
@@ -1036,12 +1125,12 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1036
1125
|
border-top: 1px solid var(--border);
|
|
1037
1126
|
padding-top: 14px;
|
|
1038
1127
|
}
|
|
1039
|
-
.prop-key { color: var(--text3); font-size:
|
|
1040
|
-
.prop-val { font-size:
|
|
1128
|
+
.prop-key { color: var(--text3); font-size: var(--fs-small); padding: 6px 0; font-family: var(--mono); letter-spacing: 0.04em; }
|
|
1129
|
+
.prop-val { font-size: var(--fs-body); padding: 6px 0; }
|
|
1041
1130
|
.pill {
|
|
1042
1131
|
display: inline-flex; align-items: center; gap: 6px;
|
|
1043
1132
|
padding: 4px 10px; border-radius: 999px;
|
|
1044
|
-
font-size:
|
|
1133
|
+
font-size: var(--fs-small); font-weight: 500;
|
|
1045
1134
|
background: var(--bg-strong); color: var(--text2);
|
|
1046
1135
|
}
|
|
1047
1136
|
.pill-gate { background: rgba(124, 58, 237, 0.12); color: var(--status-gate); }
|
|
@@ -1055,7 +1144,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1055
1144
|
border: 1px solid var(--border);
|
|
1056
1145
|
border-radius: 8px;
|
|
1057
1146
|
padding: 12px 14px;
|
|
1058
|
-
font-size:
|
|
1147
|
+
font-size: var(--fs-body);
|
|
1059
1148
|
color: var(--text2);
|
|
1060
1149
|
white-space: pre-wrap;
|
|
1061
1150
|
line-height: 1.55;
|
|
@@ -1076,7 +1165,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1076
1165
|
overflow-y: auto;
|
|
1077
1166
|
}
|
|
1078
1167
|
.memory-side-head {
|
|
1079
|
-
font-family: var(--mono); font-size:
|
|
1168
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1080
1169
|
letter-spacing: 0.1em; text-transform: uppercase;
|
|
1081
1170
|
color: var(--text3);
|
|
1082
1171
|
padding: 0 10px 8px;
|
|
@@ -1092,27 +1181,27 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1092
1181
|
.mem-item:hover { background: var(--bg-muted); }
|
|
1093
1182
|
.mem-item.active { background: var(--accent-soft); border-color: rgba(37, 64, 212, 0.16); }
|
|
1094
1183
|
.mem-item .layer-tag {
|
|
1095
|
-
font-family: var(--mono); font-size:
|
|
1184
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1096
1185
|
color: var(--accent); letter-spacing: 0.06em;
|
|
1097
1186
|
font-weight: 600;
|
|
1098
1187
|
}
|
|
1099
1188
|
.mem-item .name {
|
|
1100
|
-
font-family: var(--mono); font-size:
|
|
1189
|
+
font-family: var(--mono); font-size: var(--fs-small);
|
|
1101
1190
|
color: var(--text);
|
|
1102
1191
|
}
|
|
1103
1192
|
.mem-item .desc {
|
|
1104
|
-
font-size:
|
|
1193
|
+
font-size: var(--fs-caption); color: var(--text2);
|
|
1105
1194
|
margin-top: 2px;
|
|
1106
1195
|
}
|
|
1107
1196
|
.mem-item .meta {
|
|
1108
|
-
font-family: var(--mono); font-size:
|
|
1197
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1109
1198
|
color: var(--text3); margin-top: 2px;
|
|
1110
1199
|
}
|
|
1111
1200
|
.mem-item.missing { opacity: 0.55; }
|
|
1112
1201
|
.mem-item.missing .layer-tag { color: var(--text3); }
|
|
1113
1202
|
.mem-group-label {
|
|
1114
1203
|
font-family: var(--mono);
|
|
1115
|
-
font-size:
|
|
1204
|
+
font-size: var(--fs-eyebrow);
|
|
1116
1205
|
letter-spacing: 0.08em;
|
|
1117
1206
|
color: var(--text3);
|
|
1118
1207
|
padding: 14px 12px 6px;
|
|
@@ -1132,18 +1221,18 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1132
1221
|
}
|
|
1133
1222
|
.memory-doc h1 { font-family: var(--serif); font-weight: 600; font-size: 28px; letter-spacing: -0.02em; margin: 0 0 14px; color: var(--text); }
|
|
1134
1223
|
.memory-doc h2 { font-family: var(--serif); font-weight: 600; font-size: 20px; margin: 28px 0 10px; color: var(--text); }
|
|
1135
|
-
.memory-doc h3 { font-family: var(--sans); font-weight: 600; font-size:
|
|
1136
|
-
.memory-doc p { font-size:
|
|
1224
|
+
.memory-doc h3 { font-family: var(--sans); font-weight: 600; font-size: var(--fs-title-s); margin: 18px 0 8px; color: var(--text); }
|
|
1225
|
+
.memory-doc p { font-size: var(--fs-base); line-height: 1.65; color: var(--text2); margin: 0 0 10px; }
|
|
1137
1226
|
.memory-doc ul, .memory-doc ol { padding-left: 22px; margin: 0 0 12px; color: var(--text2); }
|
|
1138
|
-
.memory-doc li { line-height: 1.6; font-size:
|
|
1227
|
+
.memory-doc li { line-height: 1.6; font-size: var(--fs-base); }
|
|
1139
1228
|
.memory-doc code {
|
|
1140
|
-
font-family: var(--mono); font-size:
|
|
1229
|
+
font-family: var(--mono); font-size: var(--fs-small);
|
|
1141
1230
|
background: var(--bg-muted);
|
|
1142
1231
|
padding: 1px 6px; border-radius: 3px;
|
|
1143
1232
|
color: var(--text);
|
|
1144
1233
|
}
|
|
1145
1234
|
.memory-doc pre {
|
|
1146
|
-
font-family: var(--mono); font-size:
|
|
1235
|
+
font-family: var(--mono); font-size: var(--fs-small);
|
|
1147
1236
|
background: var(--bg-strong);
|
|
1148
1237
|
padding: 14px 16px;
|
|
1149
1238
|
border-radius: 8px;
|
|
@@ -1156,7 +1245,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1156
1245
|
.memory-doc table {
|
|
1157
1246
|
border-collapse: collapse;
|
|
1158
1247
|
margin: 12px 0;
|
|
1159
|
-
font-size:
|
|
1248
|
+
font-size: var(--fs-body);
|
|
1160
1249
|
width: 100%;
|
|
1161
1250
|
}
|
|
1162
1251
|
.memory-doc th, .memory-doc td {
|
|
@@ -1172,27 +1261,27 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1172
1261
|
border-bottom: 1px solid var(--border);
|
|
1173
1262
|
}
|
|
1174
1263
|
.memory-doc-head .layer-tag {
|
|
1175
|
-
font-family: var(--mono); font-size:
|
|
1264
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1176
1265
|
background: var(--accent-soft); color: var(--accent);
|
|
1177
1266
|
padding: 4px 10px; border-radius: 4px;
|
|
1178
1267
|
letter-spacing: 0.06em; font-weight: 600;
|
|
1179
1268
|
}
|
|
1180
1269
|
.memory-doc-head .filename {
|
|
1181
|
-
font-family: var(--mono); font-size:
|
|
1270
|
+
font-family: var(--mono); font-size: var(--fs-body);
|
|
1182
1271
|
color: var(--text);
|
|
1183
1272
|
}
|
|
1184
1273
|
.memory-doc-head .filesize {
|
|
1185
1274
|
margin-left: auto;
|
|
1186
|
-
font-family: var(--mono); font-size:
|
|
1275
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1187
1276
|
color: var(--text3);
|
|
1188
1277
|
}
|
|
1189
1278
|
.memory-empty {
|
|
1190
1279
|
text-align: center; padding: 60px 24px;
|
|
1191
|
-
color: var(--text3); font-size:
|
|
1280
|
+
color: var(--text3); font-size: var(--fs-body);
|
|
1192
1281
|
}
|
|
1193
1282
|
|
|
1194
1283
|
/* ── change_tier badge ────────────────────────────────────────────────────── */
|
|
1195
|
-
.tier-badge { font-size:
|
|
1284
|
+
.tier-badge { font-size: var(--fs-caption); padding: 1px 8px; border-radius: 999px; margin-left: 6px;
|
|
1196
1285
|
font-family: var(--mono); white-space: nowrap; }
|
|
1197
1286
|
.tier-badge:empty { display: none; }
|
|
1198
1287
|
.tier-badge.tier-T0 { background: var(--status-review); color: #fff; }
|
|
@@ -1229,12 +1318,12 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1229
1318
|
min-height: 26px; padding: 0 8px;
|
|
1230
1319
|
border: 1px solid var(--border); border-radius: 5px;
|
|
1231
1320
|
background: var(--bg-card); color: var(--text2);
|
|
1232
|
-
font-family: var(--mono); font-size:
|
|
1321
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow); cursor: pointer;
|
|
1233
1322
|
}
|
|
1234
1323
|
.pl-recover-btn:hover { border-color: var(--status-blocked); color: var(--status-blocked); }
|
|
1235
1324
|
.pl-recover-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
|
|
1236
1325
|
.pl-stage .pl-name {
|
|
1237
|
-
font-family: var(--mono); font-size:
|
|
1326
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1238
1327
|
letter-spacing: 0.04em; color: var(--text);
|
|
1239
1328
|
display: flex; align-items: center; gap: 6px;
|
|
1240
1329
|
}
|
|
@@ -1248,7 +1337,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1248
1337
|
.pl-stage.failed .pl-name .dot { background: var(--status-blocked); }
|
|
1249
1338
|
@keyframes pl-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.4); } 50% { box-shadow: 0 0 0 5px rgba(245, 158, 11, 0); } }
|
|
1250
1339
|
.pl-stage .pl-msg {
|
|
1251
|
-
font-size:
|
|
1340
|
+
font-size: var(--fs-caption); color: var(--text2);
|
|
1252
1341
|
line-height: 1.35;
|
|
1253
1342
|
display: -webkit-box;
|
|
1254
1343
|
-webkit-line-clamp: 2;
|
|
@@ -1257,7 +1346,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1257
1346
|
text-overflow: ellipsis;
|
|
1258
1347
|
}
|
|
1259
1348
|
.pl-stage .pl-meta {
|
|
1260
|
-
font-family: var(--mono); font-size:
|
|
1349
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1261
1350
|
color: var(--text3);
|
|
1262
1351
|
}
|
|
1263
1352
|
.pl-stage.idle .pl-msg, .pl-stage.idle .pl-meta { opacity: 0.55; }
|
|
@@ -1278,11 +1367,11 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1278
1367
|
border-radius: 50%; background: rgba(0, 217, 126, 0.12);
|
|
1279
1368
|
color: var(--accent, #00d97e); font-size: 16px; font-weight: 600;
|
|
1280
1369
|
}
|
|
1281
|
-
.inbox-allclear .ac-text { flex: 1; font-size:
|
|
1370
|
+
.inbox-allclear .ac-text { flex: 1; font-size: var(--fs-base); color: var(--text2); }
|
|
1282
1371
|
.inbox-allclear .ac-text b { color: var(--text); font-weight: 600; }
|
|
1283
1372
|
.inbox-allclear .ac-actions { display: flex; gap: 8px; }
|
|
1284
1373
|
.inbox-allclear .ac-btn {
|
|
1285
|
-
font-size:
|
|
1374
|
+
font-size: var(--fs-body); padding: 7px 14px; border-radius: 8px;
|
|
1286
1375
|
border: 1px solid var(--border-strong); background: transparent;
|
|
1287
1376
|
color: var(--text); cursor: pointer; transition: background 0.12s, border-color 0.12s;
|
|
1288
1377
|
}
|
|
@@ -1299,7 +1388,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1299
1388
|
margin: -4px 2px;
|
|
1300
1389
|
padding: 12px 12px 10px;
|
|
1301
1390
|
}
|
|
1302
|
-
.pl-gate .gate-glyph { font-size:
|
|
1391
|
+
.pl-gate .gate-glyph { font-size: var(--fs-small); line-height: 1; flex-shrink: 0; filter: grayscale(1); opacity: 0.6; }
|
|
1303
1392
|
.pl-gate .pl-name { font-weight: 600; }
|
|
1304
1393
|
.pl-gate.active {
|
|
1305
1394
|
border-left-color: var(--status-blocked);
|
|
@@ -1310,7 +1399,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1310
1399
|
.pl-gate .gate-badge {
|
|
1311
1400
|
margin-left: auto;
|
|
1312
1401
|
background: var(--status-blocked); color: #fff;
|
|
1313
|
-
font-size:
|
|
1402
|
+
font-size: var(--fs-eyebrow); font-weight: 700;
|
|
1314
1403
|
min-width: 16px; height: 16px; padding: 0 4px;
|
|
1315
1404
|
border-radius: 8px;
|
|
1316
1405
|
display: inline-flex; align-items: center; justify-content: center;
|
|
@@ -1331,18 +1420,18 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1331
1420
|
display: flex; flex-direction: column; gap: 2px;
|
|
1332
1421
|
}
|
|
1333
1422
|
.cost-cell .lbl {
|
|
1334
|
-
font-family: var(--mono); font-size:
|
|
1423
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1335
1424
|
letter-spacing: 0.08em; text-transform: uppercase;
|
|
1336
1425
|
color: var(--text2);
|
|
1337
1426
|
}
|
|
1338
1427
|
.cost-cell .v {
|
|
1339
1428
|
font-family: var(--serif); font-weight: 500;
|
|
1340
1429
|
font-variant-numeric: tabular-nums;
|
|
1341
|
-
font-size:
|
|
1430
|
+
font-size: var(--fs-num-s); letter-spacing: -0.02em;
|
|
1342
1431
|
color: var(--text); line-height: 1.1;
|
|
1343
1432
|
}
|
|
1344
|
-
.cost-cell .v small { font-size:
|
|
1345
|
-
.cost-cell .sub { font-size:
|
|
1433
|
+
.cost-cell .v small { font-size: var(--fs-base); color: var(--text2); margin-left: 2px; font-weight: 400; }
|
|
1434
|
+
.cost-cell .sub { font-size: var(--fs-caption); color: var(--text2); }
|
|
1346
1435
|
.cost-cell.warn .v { color: var(--status-blocked); }
|
|
1347
1436
|
.cost-cell.good .v { color: var(--status-review); }
|
|
1348
1437
|
|
|
@@ -1374,7 +1463,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1374
1463
|
transform: translateX(-50%);
|
|
1375
1464
|
background: #0f1115; color: #fff;
|
|
1376
1465
|
padding: 4px 8px; border-radius: 4px;
|
|
1377
|
-
font-family: var(--mono); font-size:
|
|
1466
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1378
1467
|
white-space: nowrap;
|
|
1379
1468
|
display: none;
|
|
1380
1469
|
pointer-events: none;
|
|
@@ -1387,7 +1476,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1387
1476
|
chart is the primary reading and this is the exact one. */
|
|
1388
1477
|
.cost-table { margin-top: 10px; }
|
|
1389
1478
|
.cost-table summary {
|
|
1390
|
-
cursor: pointer; font-size:
|
|
1479
|
+
cursor: pointer; font-size: var(--fs-small); color: var(--text2);
|
|
1391
1480
|
padding: 4px 0; list-style-position: inside;
|
|
1392
1481
|
}
|
|
1393
1482
|
.cost-table summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }
|
|
@@ -1395,13 +1484,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1395
1484
|
.cost-table th, .cost-table td {
|
|
1396
1485
|
text-align: left; padding: 5px 10px 5px 0;
|
|
1397
1486
|
border-bottom: 1px solid var(--border);
|
|
1398
|
-
font-size:
|
|
1487
|
+
font-size: var(--fs-small); white-space: nowrap;
|
|
1399
1488
|
}
|
|
1400
|
-
.cost-table th { font-family: var(--mono); font-size:
|
|
1489
|
+
.cost-table th { font-family: var(--mono); font-size: var(--fs-eyebrow); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text2); }
|
|
1401
1490
|
.cost-table td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }
|
|
1402
1491
|
.cost-axis {
|
|
1403
1492
|
display: flex; justify-content: space-between;
|
|
1404
|
-
font-family: var(--mono); font-size:
|
|
1493
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1405
1494
|
color: var(--text3);
|
|
1406
1495
|
margin-top: 4px;
|
|
1407
1496
|
}
|
|
@@ -1414,13 +1503,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1414
1503
|
}
|
|
1415
1504
|
.cost-budget-line .label {
|
|
1416
1505
|
position: absolute; right: 4px; top: -16px;
|
|
1417
|
-
font-family: var(--mono); font-size:
|
|
1506
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1418
1507
|
color: var(--status-progress);
|
|
1419
1508
|
background: var(--bg-card); padding: 0 4px;
|
|
1420
1509
|
}
|
|
1421
1510
|
.cost-empty {
|
|
1422
1511
|
text-align: center; padding: 30px 16px;
|
|
1423
|
-
font-size:
|
|
1512
|
+
font-size: var(--fs-body); color: var(--text3);
|
|
1424
1513
|
}
|
|
1425
1514
|
|
|
1426
1515
|
/* ── Cost per feature ────────────────────────────────────────────────────── */
|
|
@@ -1430,7 +1519,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1430
1519
|
padding-top: 16px;
|
|
1431
1520
|
}
|
|
1432
1521
|
.feat-title {
|
|
1433
|
-
font-size:
|
|
1522
|
+
font-size: var(--fs-caption); font-weight: 600; text-transform: uppercase;
|
|
1434
1523
|
letter-spacing: .06em; color: var(--text3);
|
|
1435
1524
|
margin-bottom: 10px;
|
|
1436
1525
|
}
|
|
@@ -1440,16 +1529,16 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1440
1529
|
grid-template-columns: 160px 1fr 56px 32px;
|
|
1441
1530
|
align-items: center;
|
|
1442
1531
|
gap: 8px;
|
|
1443
|
-
font-size:
|
|
1532
|
+
font-size: var(--fs-small);
|
|
1444
1533
|
}
|
|
1445
1534
|
.feat-name {
|
|
1446
|
-
font-family: var(--mono); color: var(--
|
|
1535
|
+
font-family: var(--mono); color: var(--text);
|
|
1447
1536
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1448
1537
|
}
|
|
1449
|
-
.feat-bar-wrap { background: var(--bg); border-radius: 3px; height: 6px; }
|
|
1538
|
+
.feat-bar-wrap { background: var(--bg-strong); border-radius: 3px; height: 6px; }
|
|
1450
1539
|
.feat-bar { height: 6px; border-radius: 3px; background: var(--accent); transition: width .3s; }
|
|
1451
|
-
.feat-cost { font-family: var(--mono); color: var(--
|
|
1452
|
-
.feat-runs { font-size:
|
|
1540
|
+
.feat-cost { font-family: var(--mono); color: var(--text); text-align: right; }
|
|
1541
|
+
.feat-runs { font-size: var(--fs-caption); color: var(--text3); text-align: right; }
|
|
1453
1542
|
|
|
1454
1543
|
/* ── Inbox page ───────────────────────────────────────────────────────────── */
|
|
1455
1544
|
.inbox-page {
|
|
@@ -1476,11 +1565,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1476
1565
|
display: flex; align-items: center; gap: 10px;
|
|
1477
1566
|
}
|
|
1478
1567
|
.inbox-summary .pill-stat .num {
|
|
1479
|
-
font-family: var(--
|
|
1480
|
-
font-
|
|
1568
|
+
font-family: var(--serif); font-weight: 500;
|
|
1569
|
+
font-variant-numeric: tabular-nums;
|
|
1570
|
+
font-size: var(--fs-num-s); letter-spacing: -0.02em;
|
|
1571
|
+
color: var(--text);
|
|
1481
1572
|
}
|
|
1482
1573
|
.inbox-summary .pill-stat .lbl {
|
|
1483
|
-
font-family: var(--mono); font-size:
|
|
1574
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1484
1575
|
letter-spacing: 0.08em; text-transform: uppercase;
|
|
1485
1576
|
color: var(--text2);
|
|
1486
1577
|
}
|
|
@@ -1507,11 +1598,11 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1507
1598
|
}
|
|
1508
1599
|
.resume-title {
|
|
1509
1600
|
font-family: var(--sans); font-weight: 600;
|
|
1510
|
-
font-size:
|
|
1601
|
+
font-size: var(--fs-body); color: var(--text);
|
|
1511
1602
|
}
|
|
1512
1603
|
.resume-meta {
|
|
1513
1604
|
margin-left: auto;
|
|
1514
|
-
font-family: var(--mono); font-size:
|
|
1605
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1515
1606
|
letter-spacing: 0.08em; text-transform: uppercase;
|
|
1516
1607
|
color: var(--text3);
|
|
1517
1608
|
}
|
|
@@ -1520,7 +1611,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1520
1611
|
gap: 16px;
|
|
1521
1612
|
}
|
|
1522
1613
|
.resume-col-head {
|
|
1523
|
-
font-family: var(--mono); font-size:
|
|
1614
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1524
1615
|
letter-spacing: 0.08em; text-transform: uppercase;
|
|
1525
1616
|
color: var(--text3);
|
|
1526
1617
|
margin-bottom: 8px;
|
|
@@ -1531,7 +1622,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1531
1622
|
display: flex; flex-direction: column; gap: 8px;
|
|
1532
1623
|
}
|
|
1533
1624
|
.resume-list .resume-item {
|
|
1534
|
-
font-size:
|
|
1625
|
+
font-size: var(--fs-small);
|
|
1535
1626
|
line-height: 1.4;
|
|
1536
1627
|
color: var(--text2);
|
|
1537
1628
|
cursor: pointer;
|
|
@@ -1542,7 +1633,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1542
1633
|
.resume-list .resume-item:hover { color: var(--text); }
|
|
1543
1634
|
.resume-list .resume-item .ri-tag {
|
|
1544
1635
|
flex-shrink: 0;
|
|
1545
|
-
font-family: var(--mono); font-size:
|
|
1636
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1546
1637
|
padding: 2px 5px; border-radius: 3px;
|
|
1547
1638
|
letter-spacing: 0.04em;
|
|
1548
1639
|
background: rgba(255,255,255,0.05);
|
|
@@ -1550,13 +1641,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1550
1641
|
margin-top: 1px;
|
|
1551
1642
|
}
|
|
1552
1643
|
.resume-list .resume-item .ri-tag.ok { color: var(--accent); background: rgba(0,217,126,0.08); }
|
|
1553
|
-
.resume-list .resume-item .ri-tag.fail { color: var(--p1); background: rgba(255,80,80,0.08); }
|
|
1644
|
+
.resume-list .resume-item .ri-tag.fail { color: var(--p1-fg); background: rgba(255,80,80,0.08); }
|
|
1554
1645
|
.resume-list .resume-item .ri-text {
|
|
1555
1646
|
flex: 1; min-width: 0;
|
|
1556
1647
|
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1557
1648
|
}
|
|
1558
1649
|
.resume-list .empty {
|
|
1559
|
-
font-size:
|
|
1650
|
+
font-size: var(--fs-small); color: var(--text3); font-style: italic;
|
|
1560
1651
|
}
|
|
1561
1652
|
@media (max-width: 880px) {
|
|
1562
1653
|
.resume-grid { grid-template-columns: 1fr; gap: 12px; }
|
|
@@ -1572,10 +1663,10 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1572
1663
|
}
|
|
1573
1664
|
.inbox-section-head h3 {
|
|
1574
1665
|
font-family: var(--sans); font-weight: 600;
|
|
1575
|
-
font-size:
|
|
1666
|
+
font-size: var(--fs-title-s); margin: 0; color: var(--text);
|
|
1576
1667
|
}
|
|
1577
1668
|
.inbox-section-head .inbox-count {
|
|
1578
|
-
font-family: var(--mono); font-size:
|
|
1669
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1579
1670
|
color: var(--text3); margin-left: 2px;
|
|
1580
1671
|
}
|
|
1581
1672
|
|
|
@@ -1601,13 +1692,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1601
1692
|
.inbox-row:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-1px); }
|
|
1602
1693
|
.inbox-row .id {
|
|
1603
1694
|
padding-top: 2px;
|
|
1604
|
-
font-family: var(--mono); font-size:
|
|
1695
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1605
1696
|
color: var(--text3); letter-spacing: 0.04em;
|
|
1606
1697
|
/* keep a long project-prefixed id inside its own column — never overlap the title */
|
|
1607
1698
|
min-width: 0; overflow-wrap: anywhere; word-break: break-word;
|
|
1608
1699
|
}
|
|
1609
1700
|
.inbox-row .ttl {
|
|
1610
|
-
font-size:
|
|
1701
|
+
font-size: var(--fs-body); color: var(--text);
|
|
1611
1702
|
font-weight: 500;
|
|
1612
1703
|
display: flex;
|
|
1613
1704
|
flex-direction: column;
|
|
@@ -1623,7 +1714,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1623
1714
|
}
|
|
1624
1715
|
.inbox-row .ttl .ttl-desc {
|
|
1625
1716
|
font-weight: 400;
|
|
1626
|
-
font-size:
|
|
1717
|
+
font-size: var(--fs-small);
|
|
1627
1718
|
color: var(--text2);
|
|
1628
1719
|
display: -webkit-box;
|
|
1629
1720
|
-webkit-line-clamp: 2;
|
|
@@ -1633,39 +1724,43 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1633
1724
|
margin-top: 2px;
|
|
1634
1725
|
}
|
|
1635
1726
|
.inbox-row .ttl .meta {
|
|
1636
|
-
font-family: var(--mono); font-size:
|
|
1727
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1637
1728
|
color: var(--text3); margin-top: 4px;
|
|
1638
1729
|
}
|
|
1639
1730
|
.inbox-row .actions {
|
|
1640
1731
|
display: flex; gap: 4px; align-items: center;
|
|
1641
1732
|
}
|
|
1642
|
-
.inbox-row .actions .gate-btn { height: 26px; padding: 0 10px; font-size:
|
|
1643
|
-
.budgets-
|
|
1733
|
+
.inbox-row .actions .gate-btn { height: 26px; padding: 0 10px; font-size: var(--fs-caption); }
|
|
1734
|
+
.budgets-failed { padding: 20px 0; max-width: 560px; }
|
|
1735
|
+
.budgets-failed .bf-head { font-size: var(--fs-title-s); font-weight: 600; margin-bottom: 6px; }
|
|
1736
|
+
.budgets-failed .bf-why { font-family: var(--mono); font-size: var(--fs-small); color: var(--status-blocked); margin-bottom: 10px; word-break: break-word; }
|
|
1737
|
+
.budgets-failed .bf-note { font-size: var(--fs-body); color: var(--text2); line-height: 1.5; margin-bottom: 14px; }
|
|
1738
|
+
.budgets-table { width: 100%; border-collapse: collapse; font-size: var(--fs-body); }
|
|
1644
1739
|
.budgets-table th {
|
|
1645
|
-
text-align: left; font-family: var(--mono); font-size:
|
|
1740
|
+
text-align: left; font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1646
1741
|
letter-spacing: 0.08em; text-transform: uppercase; color: var(--text2);
|
|
1647
1742
|
padding: 0 12px 8px 0; border-bottom: 1px solid var(--border);
|
|
1648
1743
|
}
|
|
1649
1744
|
.budgets-table td { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--border); vertical-align: middle; }
|
|
1650
1745
|
/* A row has to answer three questions: what is this agent, what does it cost,
|
|
1651
1746
|
over what period. The slug alone answered none of them. */
|
|
1652
|
-
.budgets-table .bt-slug { font-family: var(--mono); font-size:
|
|
1747
|
+
.budgets-table .bt-slug { font-family: var(--mono); font-size: var(--fs-small); }
|
|
1653
1748
|
.budgets-table .bt-desc {
|
|
1654
|
-
font-size:
|
|
1749
|
+
font-size: var(--fs-small); color: var(--text2); margin-top: 2px;
|
|
1655
1750
|
max-width: 52ch; text-wrap: pretty;
|
|
1656
1751
|
}
|
|
1657
1752
|
.budgets-table .bt-runs,
|
|
1658
1753
|
.budgets-table .bt-cap { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }
|
|
1659
|
-
.budgets-table .bt-spend { font-family: var(--mono); font-size:
|
|
1754
|
+
.budgets-table .bt-spend { font-family: var(--mono); font-size: var(--fs-small); white-space: nowrap; }
|
|
1660
1755
|
.budgets-table .bt-usd { font-variant-numeric: tabular-nums; color: var(--text); }
|
|
1661
1756
|
.budgets-table th[title] { cursor: help; }
|
|
1662
|
-
.budgets-idle summary { cursor: pointer; font-size:
|
|
1757
|
+
.budgets-idle summary { cursor: pointer; font-size: var(--fs-body); color: var(--text2); }
|
|
1663
1758
|
.budgets-idle summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
|
|
1664
1759
|
.budgets-table .bt-actions { text-align: right; white-space: nowrap; }
|
|
1665
1760
|
.budgets-table .bt-actions .ab-btn + .ab-btn { margin-left: 6px; }
|
|
1666
1761
|
.budgets-empty {
|
|
1667
1762
|
padding: 16px; border: 1px dashed var(--border-strong); border-radius: 8px;
|
|
1668
|
-
color: var(--text2); font-size:
|
|
1763
|
+
color: var(--text2); font-size: var(--fs-body);
|
|
1669
1764
|
}
|
|
1670
1765
|
.budgets-uncapped { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
1671
1766
|
.docs-search { display: flex; align-items: center; gap: 8px; margin: 10px 0 16px; }
|
|
@@ -1673,18 +1768,18 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1673
1768
|
flex: 1 1 auto; min-width: 0; max-width: 460px;
|
|
1674
1769
|
height: 32px; padding: 0 10px;
|
|
1675
1770
|
border: 1px solid var(--border); border-radius: 8px;
|
|
1676
|
-
background: var(--bg-card); color: var(--text); font: inherit; font-size:
|
|
1771
|
+
background: var(--bg-card); color: var(--text); font: inherit; font-size: var(--fs-body);
|
|
1677
1772
|
}
|
|
1678
1773
|
.docs-search input:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
|
|
1679
|
-
.docs-search-hint { font-family: var(--mono); font-size:
|
|
1680
|
-
.docs-search-meta { font-size:
|
|
1774
|
+
.docs-search-hint { font-family: var(--mono); font-size: var(--fs-eyebrow); color: var(--text3); }
|
|
1775
|
+
.docs-search-meta { font-size: var(--fs-small); color: var(--text2); margin-bottom: 12px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
1681
1776
|
.docs-hit { padding: 10px 0; border-top: 1px solid var(--border); }
|
|
1682
|
-
.docs-hit-line { display: flex; gap: 10px; font-family: var(--mono); font-size:
|
|
1777
|
+
.docs-hit-line { display: flex; gap: 10px; font-family: var(--mono); font-size: var(--fs-caption); color: var(--text2); margin-top: 4px; }
|
|
1683
1778
|
.docs-hit-no { color: var(--text3); min-width: 34px; text-align: right; }
|
|
1684
1779
|
.col-more {
|
|
1685
1780
|
display: block; width: 100%;
|
|
1686
1781
|
margin-top: 6px; padding: 8px;
|
|
1687
|
-
font-family: var(--mono); font-size:
|
|
1782
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1688
1783
|
border: 1px dashed var(--border-strong); border-radius: 8px;
|
|
1689
1784
|
background: transparent; color: var(--text2);
|
|
1690
1785
|
}
|
|
@@ -1694,14 +1789,14 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1694
1789
|
padding: 14px 16px;
|
|
1695
1790
|
background: var(--bg-muted);
|
|
1696
1791
|
border-radius: 8px;
|
|
1697
|
-
font-size:
|
|
1792
|
+
font-size: var(--fs-small); color: var(--text3);
|
|
1698
1793
|
text-align: center;
|
|
1699
1794
|
}
|
|
1700
1795
|
|
|
1701
1796
|
/* ── Metrics page ─────────────────────────────────────────────────────────── */
|
|
1702
1797
|
.metrics-page { padding: 24px 32px; }
|
|
1703
1798
|
.mp-section-label {
|
|
1704
|
-
font-family: var(--mono); font-size:
|
|
1799
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1705
1800
|
letter-spacing: 0.1em; text-transform: uppercase;
|
|
1706
1801
|
color: var(--text3); margin: 0 0 12px;
|
|
1707
1802
|
}
|
|
@@ -1714,7 +1809,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1714
1809
|
margin-bottom: 16px;
|
|
1715
1810
|
}
|
|
1716
1811
|
.period-label {
|
|
1717
|
-
font-family: var(--mono); font-size:
|
|
1812
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1718
1813
|
letter-spacing: 0.12em; color: var(--text3);
|
|
1719
1814
|
}
|
|
1720
1815
|
.period-chips {
|
|
@@ -1725,7 +1820,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1725
1820
|
.period-chip {
|
|
1726
1821
|
background: transparent; border: none; color: var(--text2);
|
|
1727
1822
|
padding: 5px 12px; border-radius: 5px;
|
|
1728
|
-
font-family: var(--mono); font-size:
|
|
1823
|
+
font-family: var(--mono); font-size: var(--fs-caption); font-weight: 500;
|
|
1729
1824
|
letter-spacing: 0.05em; cursor: pointer;
|
|
1730
1825
|
transition: background .12s, color .12s;
|
|
1731
1826
|
}
|
|
@@ -1753,7 +1848,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1753
1848
|
so a figure that ticks over re-flows its own width and the number appears to
|
|
1754
1849
|
breathe. Tabular figures cost nothing here and stop it. */
|
|
1755
1850
|
font-variant-numeric: tabular-nums;
|
|
1756
|
-
font-size:
|
|
1851
|
+
font-size: var(--fs-num-xl); line-height: 1;
|
|
1757
1852
|
letter-spacing: -0.02em;
|
|
1758
1853
|
}
|
|
1759
1854
|
/* An absence is rendered quietly and never silently — the glyph stays out of the
|
|
@@ -1766,23 +1861,23 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1766
1861
|
}
|
|
1767
1862
|
.delta {
|
|
1768
1863
|
margin-left: 6px;
|
|
1769
|
-
font-family: var(--mono); font-size:
|
|
1864
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow); font-weight: 600;
|
|
1770
1865
|
letter-spacing: 0.02em; white-space: nowrap;
|
|
1771
1866
|
color: var(--text3); cursor: help;
|
|
1772
1867
|
}
|
|
1773
1868
|
.delta.up { color: var(--status-review); }
|
|
1774
1869
|
.delta.down { color: var(--status-progress); }
|
|
1775
1870
|
.metric-num small {
|
|
1776
|
-
font-size:
|
|
1871
|
+
font-size: var(--fs-title-l); color: var(--text2);
|
|
1777
1872
|
margin-left: 4px; font-weight: 400;
|
|
1778
1873
|
}
|
|
1779
1874
|
.metric-label {
|
|
1780
|
-
font-family: var(--mono); font-size:
|
|
1875
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1781
1876
|
letter-spacing: 0.08em; text-transform: uppercase;
|
|
1782
1877
|
color: var(--text2); margin-top: 14px;
|
|
1783
1878
|
}
|
|
1784
1879
|
.metric-trend {
|
|
1785
|
-
margin-top: 6px; font-size:
|
|
1880
|
+
margin-top: 6px; font-size: var(--fs-small); color: var(--text2);
|
|
1786
1881
|
}
|
|
1787
1882
|
|
|
1788
1883
|
.mp-secondary {
|
|
@@ -1790,7 +1885,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1790
1885
|
gap: 12px; margin-bottom: 28px;
|
|
1791
1886
|
}
|
|
1792
1887
|
.mp-secondary .metric-card { padding: 18px; }
|
|
1793
|
-
.mp-secondary .metric-num { font-size:
|
|
1888
|
+
.mp-secondary .metric-num { font-size: var(--fs-num-m); }
|
|
1794
1889
|
|
|
1795
1890
|
.mp-row {
|
|
1796
1891
|
display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
|
|
@@ -1801,17 +1896,17 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1801
1896
|
}
|
|
1802
1897
|
.mp-card h3 {
|
|
1803
1898
|
font-family: var(--sans); font-weight: 600;
|
|
1804
|
-
font-size:
|
|
1899
|
+
font-size: var(--fs-title-s); margin: 0 0 16px;
|
|
1805
1900
|
}
|
|
1806
1901
|
.mp-card-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 16px; }
|
|
1807
1902
|
.mp-card-head h3 { margin: 0; }
|
|
1808
1903
|
.mp-card-meta {
|
|
1809
|
-
font-family: var(--mono); font-size:
|
|
1904
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1810
1905
|
color: var(--text3); letter-spacing: 0.06em;
|
|
1811
1906
|
text-transform: uppercase;
|
|
1812
1907
|
}
|
|
1813
1908
|
.feed-cost {
|
|
1814
|
-
font-family: var(--mono); font-size:
|
|
1909
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
1815
1910
|
color: var(--accent);
|
|
1816
1911
|
background: var(--accent-soft);
|
|
1817
1912
|
padding: 2px 6px; border-radius: 4px;
|
|
@@ -1821,7 +1916,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1821
1916
|
.bar-row {
|
|
1822
1917
|
display: grid; grid-template-columns: 130px 1fr 50px;
|
|
1823
1918
|
align-items: center; gap: 12px;
|
|
1824
|
-
margin-bottom: 10px; font-size:
|
|
1919
|
+
margin-bottom: 10px; font-size: var(--fs-small);
|
|
1825
1920
|
}
|
|
1826
1921
|
.bar-row .name { font-family: var(--mono); color: var(--text); }
|
|
1827
1922
|
.bar-row .rail {
|
|
@@ -1836,7 +1931,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1836
1931
|
}
|
|
1837
1932
|
.bar-row .pct {
|
|
1838
1933
|
text-align: right; color: var(--text2);
|
|
1839
|
-
font-family: var(--mono); font-size:
|
|
1934
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
1840
1935
|
}
|
|
1841
1936
|
|
|
1842
1937
|
.feed-row {
|
|
@@ -1845,7 +1940,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1845
1940
|
gap: 12px; align-items: baseline;
|
|
1846
1941
|
padding: 10px 0;
|
|
1847
1942
|
border-top: 1px solid var(--border);
|
|
1848
|
-
font-size:
|
|
1943
|
+
font-size: var(--fs-body);
|
|
1849
1944
|
}
|
|
1850
1945
|
.feed-row:first-child { border-top: none; }
|
|
1851
1946
|
.feed-dot {
|
|
@@ -1855,16 +1950,16 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1855
1950
|
.feed-dot.ok { background: var(--status-review); }
|
|
1856
1951
|
.feed-dot.fail { background: var(--status-blocked); }
|
|
1857
1952
|
.feed-dot.def { background: var(--text3); }
|
|
1858
|
-
.feed-row .agent { font-family: var(--mono); color: var(--text2); font-size:
|
|
1953
|
+
.feed-row .agent { font-family: var(--mono); color: var(--text2); font-size: var(--fs-small); }
|
|
1859
1954
|
.feed-row .msg { color: var(--text); }
|
|
1860
|
-
.feed-row .time { font-family: var(--mono); font-size:
|
|
1955
|
+
.feed-row .time { font-family: var(--mono); font-size: var(--fs-caption); color: var(--text3); }
|
|
1861
1956
|
|
|
1862
1957
|
/* ── Share page ───────────────────────────────────────────────────────────── */
|
|
1863
1958
|
/* ── Logs tab ───────────────────────────────────────────── */
|
|
1864
1959
|
.logs-page { display: flex; flex-direction: column; height: 100%; }
|
|
1865
1960
|
.logs-header { padding: 20px 24px 12px; border-bottom: 1px solid var(--border); display: flex; align-items: baseline; gap: 16px; }
|
|
1866
|
-
.logs-header h2 { margin: 0; font-size:
|
|
1867
|
-
.logs-hint { font-size:
|
|
1961
|
+
.logs-header h2 { margin: 0; font-size: var(--fs-title-l); letter-spacing: -0.02em; }
|
|
1962
|
+
.logs-hint { font-size: var(--fs-small); color: var(--text3); }
|
|
1868
1963
|
.logs-hint code { font-family: var(--mono); background: var(--bg-strong); padding: 1px 5px; border-radius: 3px; }
|
|
1869
1964
|
.logs-layout { display: flex; flex: 1; overflow: hidden; }
|
|
1870
1965
|
.logs-list { width: 280px; min-width: 220px; border-right: 1px solid var(--border); overflow-y: auto; padding: 8px 0; flex-shrink: 0; }
|
|
@@ -1877,7 +1972,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1877
1972
|
min-height: 28px; padding: 0 10px;
|
|
1878
1973
|
border: 1px solid var(--border); border-radius: 999px;
|
|
1879
1974
|
background: transparent; color: var(--text2);
|
|
1880
|
-
font-family: var(--mono); font-size:
|
|
1975
|
+
font-family: var(--mono); font-size: var(--fs-caption); cursor: pointer;
|
|
1881
1976
|
}
|
|
1882
1977
|
.log-facet:hover { border-color: var(--border-strong); }
|
|
1883
1978
|
.log-facet.on { background: var(--accent-soft); border-color: var(--accent-2); color: var(--accent-text); }
|
|
@@ -1886,18 +1981,18 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1886
1981
|
.log-item { padding: 10px 16px; cursor: pointer; border-bottom: 1px solid var(--border); }
|
|
1887
1982
|
.log-item:hover { background: var(--bg-muted); }
|
|
1888
1983
|
.log-item.active { background: var(--bg-strong); border-left: 2px solid var(--accent); }
|
|
1889
|
-
.log-item .log-date { font-size:
|
|
1890
|
-
.log-item .log-title { font-size:
|
|
1891
|
-
.log-item .log-meta { font-size:
|
|
1984
|
+
.log-item .log-date { font-size: var(--fs-caption); color: var(--text3); font-family: var(--mono); }
|
|
1985
|
+
.log-item .log-title { font-size: var(--fs-body); font-weight: 500; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
1986
|
+
.log-item .log-meta { font-size: var(--fs-caption); color: var(--text3); margin-top: 2px; }
|
|
1892
1987
|
.log-detail-head { margin-bottom: 20px; padding-bottom: 14px; border-bottom: 1px solid var(--border); }
|
|
1893
|
-
.log-detail-head h3 { margin: 0 0 4px; font-size:
|
|
1894
|
-
.log-detail-head .log-detail-meta { font-size:
|
|
1988
|
+
.log-detail-head h3 { margin: 0 0 4px; font-size: var(--fs-title-m); letter-spacing: -0.01em; }
|
|
1989
|
+
.log-detail-head .log-detail-meta { font-size: var(--fs-small); color: var(--text3); }
|
|
1895
1990
|
.log-section { margin-bottom: 18px; }
|
|
1896
|
-
.log-section-label { font-size:
|
|
1991
|
+
.log-section-label { font-size: var(--fs-caption); color: var(--text3); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; }
|
|
1897
1992
|
.log-bullets { list-style: none; padding: 0; margin: 0; }
|
|
1898
|
-
.log-bullets li { padding: 3px 0 3px 12px; position: relative; font-size:
|
|
1993
|
+
.log-bullets li { padding: 3px 0 3px 12px; position: relative; font-size: var(--fs-body); color: var(--text2); }
|
|
1899
1994
|
.log-bullets li::before { content: '·'; position: absolute; left: 0; color: var(--accent); }
|
|
1900
|
-
.log-empty { font-size:
|
|
1995
|
+
.log-empty { font-size: var(--fs-body); color: var(--text3); font-style: italic; }
|
|
1901
1996
|
|
|
1902
1997
|
/* ── Agents installed list (legacy — kept for fallback) ───────────────── */
|
|
1903
1998
|
.agents-installed { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; margin-top: 4px; }
|
|
@@ -1907,9 +2002,9 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1907
2002
|
.ab-name { font-family: var(--mono, monospace); color: var(--accent); }
|
|
1908
2003
|
.ab-cap { color: var(--text3); }
|
|
1909
2004
|
.agent-card { background: var(--bg-muted); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
|
|
1910
|
-
.agent-card .ac-name { font-size:
|
|
1911
|
-
.agent-card .ac-desc { font-size:
|
|
1912
|
-
.agent-card .ac-meta { font-size:
|
|
2005
|
+
.agent-card .ac-name { font-size: var(--fs-small); font-weight: 600; font-family: var(--mono); color: var(--accent); }
|
|
2006
|
+
.agent-card .ac-desc { font-size: var(--fs-caption); color: var(--text3); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
2007
|
+
.agent-card .ac-meta { font-size: var(--fs-eyebrow); color: var(--text3); margin-top: 5px; display: flex; gap: 8px; }
|
|
1913
2008
|
.agent-card .ac-model { background: var(--bg-strong); padding: 1px 5px; border-radius: 3px; }
|
|
1914
2009
|
.agent-card .ac-used { color: var(--status-review); }
|
|
1915
2010
|
.agent-card .ac-never { color: var(--text3); font-style: italic; }
|
|
@@ -1939,17 +2034,17 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1939
2034
|
.fleet-search input[type="search"] {
|
|
1940
2035
|
flex: 1; max-width: 320px;
|
|
1941
2036
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
1942
|
-
color: var(--text); font-family: var(--mono); font-size:
|
|
2037
|
+
color: var(--text); font-family: var(--mono); font-size: var(--fs-body);
|
|
1943
2038
|
padding: 8px 12px; border-radius: 6px;
|
|
1944
2039
|
}
|
|
1945
2040
|
.fleet-search input[type="search"]:focus {
|
|
1946
2041
|
outline: 2px solid var(--focus-ring); outline-offset: 1px;
|
|
1947
2042
|
border-color: transparent;
|
|
1948
2043
|
}
|
|
1949
|
-
.fleet-search .search-hint { font-size:
|
|
2044
|
+
.fleet-search .search-hint { font-size: var(--fs-caption); color: var(--text3); font-family: var(--mono); }
|
|
1950
2045
|
.fleet-search .search-hint kbd {
|
|
1951
2046
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
1952
|
-
border-radius: 3px; padding: 1px 5px; font-size:
|
|
2047
|
+
border-radius: 3px; padding: 1px 5px; font-size: var(--fs-eyebrow);
|
|
1953
2048
|
}
|
|
1954
2049
|
|
|
1955
2050
|
.fleet-facets { display: flex; flex-direction: column; gap: 6px; }
|
|
@@ -1958,12 +2053,12 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1958
2053
|
display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
|
|
1959
2054
|
}
|
|
1960
2055
|
.fleet-facets legend {
|
|
1961
|
-
font-size:
|
|
2056
|
+
font-size: var(--fs-caption); color: var(--text3); text-transform: uppercase;
|
|
1962
2057
|
letter-spacing: 0.05em; margin-right: 6px; min-width: 60px;
|
|
1963
2058
|
}
|
|
1964
2059
|
.facet-chip {
|
|
1965
2060
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
1966
|
-
color: var(--text2); font-size:
|
|
2061
|
+
color: var(--text2); font-size: var(--fs-small); font-family: var(--mono);
|
|
1967
2062
|
padding: 4px 10px; border-radius: 12px; cursor: pointer;
|
|
1968
2063
|
transition: background-color 0.15s, color 0.15s, border-color 0.15s;
|
|
1969
2064
|
}
|
|
@@ -1977,16 +2072,16 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
1977
2072
|
|
|
1978
2073
|
.fleet-sort {
|
|
1979
2074
|
display: flex; gap: 8px; align-items: center;
|
|
1980
|
-
font-size:
|
|
2075
|
+
font-size: var(--fs-caption); color: var(--text3);
|
|
1981
2076
|
}
|
|
1982
2077
|
.fleet-sort select {
|
|
1983
2078
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
1984
|
-
color: var(--text); font-family: var(--mono); font-size:
|
|
2079
|
+
color: var(--text); font-family: var(--mono); font-size: var(--fs-small);
|
|
1985
2080
|
padding: 4px 8px; border-radius: 6px;
|
|
1986
2081
|
}
|
|
1987
2082
|
.fleet-sort button {
|
|
1988
2083
|
background: transparent; border: 1px solid var(--border);
|
|
1989
|
-
color: var(--text2); font-size:
|
|
2084
|
+
color: var(--text2); font-size: var(--fs-caption); font-family: var(--mono);
|
|
1990
2085
|
padding: 4px 8px; border-radius: 6px;
|
|
1991
2086
|
}
|
|
1992
2087
|
.fleet-sort button:hover { color: var(--text); border-color: var(--border-strong); }
|
|
@@ -2023,11 +2118,11 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2023
2118
|
.agent-row.status-unused .ar-status { background: var(--agent-unused); }
|
|
2024
2119
|
.agent-row.status-retired .ar-status { background: var(--agent-retired); }
|
|
2025
2120
|
.agent-row .ar-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
|
2026
|
-
.agent-row .ar-name { font-family: var(--mono); font-size:
|
|
2027
|
-
.agent-row .ar-meta { font-size:
|
|
2121
|
+
.agent-row .ar-name { font-family: var(--mono); font-size: var(--fs-body); color: var(--text); }
|
|
2122
|
+
.agent-row .ar-meta { font-size: var(--fs-caption); color: var(--text3); display: flex; gap: 10px; flex-wrap: wrap; }
|
|
2028
2123
|
.agent-row .ar-meta .ar-domain {
|
|
2029
2124
|
background: var(--bg-muted); padding: 1px 6px; border-radius: 3px;
|
|
2030
|
-
color: var(--text2); font-family: var(--mono); font-size:
|
|
2125
|
+
color: var(--text2); font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
2031
2126
|
}
|
|
2032
2127
|
.agent-row .ar-rail {
|
|
2033
2128
|
width: 80px; height: 4px;
|
|
@@ -2040,13 +2135,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2040
2135
|
}
|
|
2041
2136
|
.agent-row.status-failing .ar-rail-fill { background: var(--agent-failing); }
|
|
2042
2137
|
.agent-row .ar-chev {
|
|
2043
|
-
color: var(--text3); font-size:
|
|
2138
|
+
color: var(--text3); font-size: var(--fs-base); padding: 0 4px;
|
|
2044
2139
|
}
|
|
2045
2140
|
|
|
2046
2141
|
/* Status pill — used in drawer header */
|
|
2047
2142
|
.status-pill {
|
|
2048
2143
|
display: inline-flex; align-items: center; gap: 6px;
|
|
2049
|
-
font-size:
|
|
2144
|
+
font-size: var(--fs-caption); font-family: var(--mono);
|
|
2050
2145
|
padding: 2px 8px; border-radius: 10px;
|
|
2051
2146
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
2052
2147
|
}
|
|
@@ -2086,12 +2181,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2086
2181
|
padding: 16px 20px; border-bottom: 1px solid var(--border);
|
|
2087
2182
|
}
|
|
2088
2183
|
.agent-drawer-header h3 {
|
|
2089
|
-
font-family: var(--
|
|
2184
|
+
font-family: var(--sans); font-weight: 600;
|
|
2185
|
+
font-size: var(--fs-title-s);
|
|
2090
2186
|
color: var(--text); flex: 1; margin: 0;
|
|
2091
2187
|
}
|
|
2092
2188
|
.agent-drawer-close {
|
|
2093
2189
|
background: transparent; border: 1px solid var(--border);
|
|
2094
|
-
color: var(--text2); font-size:
|
|
2190
|
+
color: var(--text2); font-size: var(--fs-title-m); line-height: 1;
|
|
2095
2191
|
width: 28px; height: 28px; border-radius: 6px;
|
|
2096
2192
|
display: flex; align-items: center; justify-content: center;
|
|
2097
2193
|
}
|
|
@@ -2103,20 +2199,20 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2103
2199
|
}
|
|
2104
2200
|
.agent-drawer-body .mp-card { padding: 12px 14px; }
|
|
2105
2201
|
.agent-drawer-body h4 {
|
|
2106
|
-
font-size:
|
|
2202
|
+
font-size: var(--fs-caption); text-transform: uppercase;
|
|
2107
2203
|
color: var(--text3); letter-spacing: 0.05em;
|
|
2108
2204
|
margin: 0 0 8px;
|
|
2109
2205
|
}
|
|
2110
2206
|
.agent-summary-grid {
|
|
2111
2207
|
display: grid; grid-template-columns: auto 1fr; gap: 4px 12px;
|
|
2112
|
-
font-size:
|
|
2208
|
+
font-size: var(--fs-small);
|
|
2113
2209
|
}
|
|
2114
2210
|
.agent-summary-grid dt { color: var(--text3); font-family: var(--mono); }
|
|
2115
2211
|
.agent-summary-grid dd { color: var(--text); font-family: var(--mono); margin: 0; }
|
|
2116
2212
|
.run-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
|
|
2117
2213
|
.run-row {
|
|
2118
2214
|
display: grid; grid-template-columns: auto auto 1fr auto; gap: 10px;
|
|
2119
|
-
font-size:
|
|
2215
|
+
font-size: var(--fs-caption); font-family: var(--mono); color: var(--text2);
|
|
2120
2216
|
padding: 4px 0;
|
|
2121
2217
|
}
|
|
2122
2218
|
.run-row .rr-verdict.ok { color: var(--agent-ok); }
|
|
@@ -2126,15 +2222,15 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2126
2222
|
.failure-list { list-style: none; margin: 0; padding: 0; }
|
|
2127
2223
|
.failure-list li {
|
|
2128
2224
|
display: flex; gap: 10px; padding: 4px 0;
|
|
2129
|
-
font-family: var(--mono); font-size:
|
|
2225
|
+
font-family: var(--mono); font-size: var(--fs-small);
|
|
2130
2226
|
}
|
|
2131
2227
|
.failure-list .fm-key { flex: 1; color: var(--text); }
|
|
2132
2228
|
.failure-list .fm-count { color: var(--agent-failing); }
|
|
2133
|
-
.failure-list .fm-last { color: var(--text3); font-size:
|
|
2229
|
+
.failure-list .fm-last { color: var(--text3); font-size: var(--fs-caption); }
|
|
2134
2230
|
.agent-actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
|
2135
2231
|
.agent-actions button {
|
|
2136
2232
|
background: var(--bg-muted); border: 1px solid var(--border);
|
|
2137
|
-
color: var(--text); font-family: var(--mono); font-size:
|
|
2233
|
+
color: var(--text); font-family: var(--mono); font-size: var(--fs-small);
|
|
2138
2234
|
padding: 6px 12px; border-radius: 6px;
|
|
2139
2235
|
}
|
|
2140
2236
|
.agent-actions button:hover { border-color: var(--border-strong); }
|
|
@@ -2169,7 +2265,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2169
2265
|
border-radius: 16px;
|
|
2170
2266
|
padding: 32px;
|
|
2171
2267
|
}
|
|
2172
|
-
.share-card h2 {
|
|
2268
|
+
.share-card h2:not(.section-title) {
|
|
2173
2269
|
font-family: var(--serif); font-weight: 500;
|
|
2174
2270
|
font-size: 28px; letter-spacing: -0.01em;
|
|
2175
2271
|
margin: 0 0 6px;
|
|
@@ -2184,13 +2280,13 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2184
2280
|
margin-bottom: 16px;
|
|
2185
2281
|
}
|
|
2186
2282
|
.share-toggle-row .label-grp { flex: 1; }
|
|
2187
|
-
.share-toggle-row .label-grp .l { font-weight: 600; font-size:
|
|
2188
|
-
.share-toggle-row .label-grp .h { color: var(--text2); font-size:
|
|
2283
|
+
.share-toggle-row .label-grp .l { font-weight: 600; font-size: var(--fs-base); }
|
|
2284
|
+
.share-toggle-row .label-grp .h { color: var(--text2); font-size: var(--fs-small); }
|
|
2189
2285
|
|
|
2190
|
-
.notif-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--
|
|
2286
|
+
.notif-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--bg-muted); border: 1px solid var(--border); border-radius: 8px; cursor: pointer; transition: border-color 0.15s; }
|
|
2191
2287
|
.notif-row:hover { border-color: var(--accent); }
|
|
2192
2288
|
.notif-row .emoji { font-size: 16px; flex-shrink: 0; }
|
|
2193
|
-
.notif-row strong { color: var(--
|
|
2289
|
+
.notif-row strong { color: var(--text); margin-right: 4px; }
|
|
2194
2290
|
.notif-row input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
|
|
2195
2291
|
|
|
2196
2292
|
.toggle {
|
|
@@ -2224,24 +2320,24 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2224
2320
|
}
|
|
2225
2321
|
.url-block .url-text {
|
|
2226
2322
|
flex: 1; font-family: var(--mono);
|
|
2227
|
-
font-size:
|
|
2323
|
+
font-size: var(--fs-small); color: var(--text);
|
|
2228
2324
|
white-space: nowrap; overflow: hidden;
|
|
2229
2325
|
text-overflow: ellipsis;
|
|
2230
2326
|
}
|
|
2231
2327
|
.btn-black {
|
|
2232
2328
|
background: #0f1115; color: #fff; border: none;
|
|
2233
2329
|
padding: 8px 14px; border-radius: 999px;
|
|
2234
|
-
font-size:
|
|
2330
|
+
font-size: var(--fs-small); font-weight: 500;
|
|
2235
2331
|
}
|
|
2236
2332
|
.btn-ghost-sm {
|
|
2237
2333
|
background: transparent;
|
|
2238
2334
|
border: 1px solid var(--border-strong);
|
|
2239
2335
|
color: var(--text);
|
|
2240
2336
|
padding: 8px 12px; border-radius: 999px;
|
|
2241
|
-
font-size:
|
|
2337
|
+
font-size: var(--fs-small);
|
|
2242
2338
|
}
|
|
2243
2339
|
.share-note {
|
|
2244
|
-
font-size:
|
|
2340
|
+
font-size: var(--fs-body); color: var(--text2);
|
|
2245
2341
|
margin-top: 16px; line-height: 1.55;
|
|
2246
2342
|
}
|
|
2247
2343
|
.share-note strong { color: var(--text); }
|
|
@@ -2251,7 +2347,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2251
2347
|
padding: 12px 16px;
|
|
2252
2348
|
background: var(--bg-muted);
|
|
2253
2349
|
border-radius: 10px;
|
|
2254
|
-
font-size:
|
|
2350
|
+
font-size: var(--fs-body); color: var(--text2);
|
|
2255
2351
|
margin-top: 12px;
|
|
2256
2352
|
}
|
|
2257
2353
|
.spinner {
|
|
@@ -2265,7 +2361,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2265
2361
|
|
|
2266
2362
|
.share-badge {
|
|
2267
2363
|
display: inline-flex; align-items: center; gap: 4px;
|
|
2268
|
-
font-size:
|
|
2364
|
+
font-size: var(--fs-eyebrow);
|
|
2269
2365
|
padding: 2px 6px; border-radius: 999px;
|
|
2270
2366
|
font-family: var(--mono);
|
|
2271
2367
|
text-transform: uppercase;
|
|
@@ -2292,7 +2388,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2292
2388
|
display: inline-flex; align-items: center; gap: 4px;
|
|
2293
2389
|
height: 22px; padding: 0 9px;
|
|
2294
2390
|
border-radius: 999px;
|
|
2295
|
-
font-size:
|
|
2391
|
+
font-size: var(--fs-caption); font-weight: 500;
|
|
2296
2392
|
background: var(--bg-strong); color: var(--text2);
|
|
2297
2393
|
border: 1px solid var(--border);
|
|
2298
2394
|
cursor: pointer;
|
|
@@ -2306,7 +2402,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2306
2402
|
.fchip-clear { background: transparent; color: var(--text3); border-color: transparent; }
|
|
2307
2403
|
.fchip-clear:hover { background: var(--bg-strong); color: var(--status-blocked); }
|
|
2308
2404
|
.filter-section-label {
|
|
2309
|
-
font-family: var(--mono); font-size:
|
|
2405
|
+
font-family: var(--mono); font-size: var(--fs-eyebrow);
|
|
2310
2406
|
letter-spacing: 0.06em; text-transform: uppercase;
|
|
2311
2407
|
color: var(--text3); padding: 0 4px;
|
|
2312
2408
|
}
|
|
@@ -2317,7 +2413,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2317
2413
|
cursor: pointer;
|
|
2318
2414
|
position: relative;
|
|
2319
2415
|
}
|
|
2320
|
-
.card-status-edit .pill { font-size:
|
|
2416
|
+
.card-status-edit .pill { font-size: var(--fs-eyebrow); height: 18px; padding: 0 7px; }
|
|
2321
2417
|
.card-status-chev {
|
|
2322
2418
|
color: var(--text3); transition: color 0.12s;
|
|
2323
2419
|
display: inline-flex; align-items: center;
|
|
@@ -2338,7 +2434,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2338
2434
|
display: flex; align-items: center; gap: 8px;
|
|
2339
2435
|
padding: 6px 10px;
|
|
2340
2436
|
border-radius: 4px;
|
|
2341
|
-
font-size:
|
|
2437
|
+
font-size: var(--fs-small); font-weight: 500;
|
|
2342
2438
|
color: var(--text);
|
|
2343
2439
|
background: transparent; border: none;
|
|
2344
2440
|
width: 100%; text-align: left;
|
|
@@ -2357,19 +2453,19 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2357
2453
|
display: grid;
|
|
2358
2454
|
grid-template-columns: 130px 1fr 70px;
|
|
2359
2455
|
align-items: center; gap: 12px;
|
|
2360
|
-
margin-bottom: 10px; font-size:
|
|
2456
|
+
margin-bottom: 10px; font-size: var(--fs-small);
|
|
2361
2457
|
}
|
|
2362
2458
|
.agent-cost-row .name { font-family: var(--mono); color: var(--text); }
|
|
2363
2459
|
.agent-cost-row .rail { display: block; height: 6px; background: var(--bg-strong); border-radius: 999px; overflow: hidden; }
|
|
2364
2460
|
.agent-cost-row .fill { display: block; height: 100%; background: var(--accent); border-radius: 999px; min-width: 2px; }
|
|
2365
|
-
.agent-cost-row .amt { text-align: right; color: var(--text2); font-family: var(--mono); font-size:
|
|
2461
|
+
.agent-cost-row .amt { text-align: right; color: var(--text2); font-family: var(--mono); font-size: var(--fs-caption); }
|
|
2366
2462
|
|
|
2367
2463
|
/* ── Task timeline ────────────────────────────────────────────────────────── */
|
|
2368
2464
|
.tl-event {
|
|
2369
2465
|
display: flex; gap: 10px;
|
|
2370
2466
|
padding: 6px 0;
|
|
2371
2467
|
border-top: 1px solid var(--border);
|
|
2372
|
-
font-size:
|
|
2468
|
+
font-size: var(--fs-small);
|
|
2373
2469
|
}
|
|
2374
2470
|
.tl-event:first-child { border-top: none; }
|
|
2375
2471
|
.tl-dot {
|
|
@@ -2379,22 +2475,26 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2379
2475
|
margin-top: 4px; flex-shrink: 0;
|
|
2380
2476
|
}
|
|
2381
2477
|
.tl-content { flex: 1; display: flex; flex-wrap: wrap; align-items: baseline; gap: 5px; }
|
|
2382
|
-
.tl-actor { font-family: var(--mono); font-size:
|
|
2478
|
+
.tl-actor { font-family: var(--mono); font-size: var(--fs-caption); font-weight: 600; color: var(--accent); }
|
|
2383
2479
|
.tl-action { color: var(--text2); }
|
|
2384
2480
|
.tl-change {
|
|
2385
|
-
font-family: var(--mono); font-size:
|
|
2481
|
+
font-family: var(--mono); font-size: var(--fs-caption);
|
|
2386
2482
|
background: var(--bg-strong); color: var(--text);
|
|
2387
2483
|
padding: 1px 6px; border-radius: 3px;
|
|
2388
2484
|
}
|
|
2389
|
-
.tl-ts { margin-left: auto; font-family: var(--mono); font-size:
|
|
2390
|
-
.side-section-head { font-family: var(--mono); font-size:
|
|
2485
|
+
.tl-ts { margin-left: auto; font-family: var(--mono); font-size: var(--fs-eyebrow); color: var(--text3); }
|
|
2486
|
+
.side-section-head { font-family: var(--mono); font-size: var(--fs-eyebrow); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text3); margin-bottom: 8px; margin-top: 16px; }
|
|
2391
2487
|
|
|
2392
2488
|
/* ── Security tab: hero KPI tile + activity feed ──────────────────────────── */
|
|
2393
|
-
.kpi-hero .kpi-value-hero {
|
|
2394
|
-
|
|
2395
|
-
|
|
2489
|
+
.kpi-hero .kpi-value-hero {
|
|
2490
|
+
font-family: var(--serif); font-weight: 500;
|
|
2491
|
+
font-variant-numeric: tabular-nums;
|
|
2492
|
+
font-size: var(--fs-num-l); line-height: 1.1; letter-spacing: -0.02em;
|
|
2493
|
+
}
|
|
2494
|
+
.kpi-hero .kpi-label { font-size: var(--fs-body); font-weight: 500; }
|
|
2495
|
+
.kpi-empty .kpi-value { color: var(--accent); font-size: var(--fs-title-l); }
|
|
2396
2496
|
.kpi-empty .kpi-value::after {
|
|
2397
|
-
content: ' all clear'; font-size:
|
|
2497
|
+
content: ' all clear'; font-size: var(--fs-caption); color: var(--text3); font-weight: 400;
|
|
2398
2498
|
}
|
|
2399
2499
|
@media (max-width: 900px) {
|
|
2400
2500
|
.kpi-hero { grid-column: span 2; }
|
|
@@ -2463,7 +2563,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2463
2563
|
display: flex; flex-wrap: wrap;
|
|
2464
2564
|
gap: 8px 10px; align-items: baseline;
|
|
2465
2565
|
}
|
|
2466
|
-
.inbox-row .ttl { order: 1; flex: 1 1 100%; font-size:
|
|
2566
|
+
.inbox-row .ttl { order: 1; flex: 1 1 100%; font-size: var(--fs-base); }
|
|
2467
2567
|
/* Two lines, wrapped — a phone has the vertical room it lacks sideways. */
|
|
2468
2568
|
.inbox-row .ttl > :first-child { -webkit-line-clamp: 2; white-space: normal; }
|
|
2469
2569
|
/* The id and the status share a line: stacked, each took a full row of its
|
|
@@ -2510,7 +2610,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2510
2610
|
their own size say it after. A button added tomorrow is covered by default;
|
|
2511
2611
|
one that must stay small has to opt out in writing. */
|
|
2512
2612
|
button, [role="button"], .nav-item, .toggle, summary { min-height: 44px; }
|
|
2513
|
-
.gate-btn, .inbox-row .actions .gate-btn { height: 44px; font-size:
|
|
2613
|
+
.gate-btn, .inbox-row .actions .gate-btn { height: 44px; font-size: var(--fs-body); }
|
|
2514
2614
|
.menu-btn { width: 44px; height: 44px; }
|
|
2515
2615
|
.btn-bell { min-width: 44px; justify-content: center; }
|
|
2516
2616
|
.gate-actions, .side-gate-actions, .inbox-row .actions { gap: 12px; }
|
|
@@ -2540,7 +2640,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2540
2640
|
</svg>
|
|
2541
2641
|
</span>
|
|
2542
2642
|
<span class="brand-name">greatcto</span>
|
|
2543
|
-
<span id="build-version" title="great_cto build version" style="margin-left:6px;font-size:
|
|
2643
|
+
<span id="build-version" title="great_cto build version" style="margin-left:6px;font-size:var(--fs-eyebrow);color:var(--text3);font-family:var(--mono);align-self:center">—</span>
|
|
2544
2644
|
</div>
|
|
2545
2645
|
<div class="proj-switch" id="proj-switch" onclick="toggleProjMenu(event)">
|
|
2546
2646
|
<span class="proj-icon" id="proj-switch-icon"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg></span>
|
|
@@ -2625,7 +2725,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2625
2725
|
<span class="task-count" id="topbar-task-count">0 ISSUES</span>
|
|
2626
2726
|
<button class="btn-bell" data-tab="share" onclick="switchTab('share', this)" title="Share a public project report" aria-label="Share" style="gap:6px;padding:6px 10px;">
|
|
2627
2727
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>
|
|
2628
|
-
<span class="btn-label" style="font-size:
|
|
2728
|
+
<span class="btn-label" style="font-size:var(--fs-small);font-weight:500">Share</span>
|
|
2629
2729
|
<span id="share-nav-badge" class="share-badge off"><span class="share-badge-dot"></span>off</span>
|
|
2630
2730
|
</button>
|
|
2631
2731
|
<button class="btn-bell" id="board-theme-btn" onclick="toggleBoardTheme()" title="Toggle light / dark theme" aria-label="Toggle theme">🌙</button>
|
|
@@ -2647,7 +2747,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2647
2747
|
<div class="inbox-summary" id="inbox-summary"></div>
|
|
2648
2748
|
<!-- Top rung of the evidence ladder: are the bytes that were reviewed
|
|
2649
2749
|
still the bytes in the tree? Hidden while they match. -->
|
|
2650
|
-
<div id="inbox-receipt" style="display:none;margin:6px 0 2px;font-size:
|
|
2750
|
+
<div id="inbox-receipt" style="display:none;margin:6px 0 2px;font-size:var(--fs-small)"></div>
|
|
2651
2751
|
|
|
2652
2752
|
<!-- Resume — pick up where you left off -->
|
|
2653
2753
|
<div class="resume-card" id="resume-card" style="display:none">
|
|
@@ -2675,9 +2775,9 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2675
2775
|
</div>
|
|
2676
2776
|
|
|
2677
2777
|
<!-- Goal ancestry banner (Paperclip pattern) — shows archetype+compliance+phase -->
|
|
2678
|
-
<div id="goal-ancestry-banner" style="display:none;font-family:var(--mono,monospace);font-size:
|
|
2778
|
+
<div id="goal-ancestry-banner" style="display:none;font-family:var(--mono,monospace);font-size:var(--fs-caption);color:var(--text3,#6b7280);background:var(--bg-muted);padding:6px 10px;border-radius:6px;margin-bottom:10px;letter-spacing:0.3px;"></div>
|
|
2679
2779
|
<!-- Tool failure rate watchdog warning -->
|
|
2680
|
-
<div id="tool-failure-rate" style="display:none;font-size:
|
|
2780
|
+
<div id="tool-failure-rate" style="display:none;font-size:var(--fs-small);color:var(--status-blocked,#f87171);background:rgba(248,113,113,0.08);padding:6px 10px;border-radius:6px;margin-bottom:10px;"></div>
|
|
2681
2781
|
|
|
2682
2782
|
<div class="inbox-section">
|
|
2683
2783
|
<div class="inbox-section-head">
|
|
@@ -2745,6 +2845,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2745
2845
|
|
|
2746
2846
|
<!-- Kanban -->
|
|
2747
2847
|
<div class="panel" id="panel-kanban">
|
|
2848
|
+
<h1 class="page-title">Tasks</h1>
|
|
2748
2849
|
<div id="filter-bar" class="filter-bar"></div>
|
|
2749
2850
|
<div class="kanban" id="kanban-board"></div>
|
|
2750
2851
|
</div>
|
|
@@ -2753,6 +2854,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2753
2854
|
<!-- Metrics -->
|
|
2754
2855
|
<div class="panel" id="panel-dashboard">
|
|
2755
2856
|
<div class="metrics-page">
|
|
2857
|
+
<h1 class="page-title">Metrics</h1>
|
|
2756
2858
|
<div class="period-toolbar">
|
|
2757
2859
|
<span class="period-label">PERIOD</span>
|
|
2758
2860
|
<div class="period-chips" id="period-chips">
|
|
@@ -2773,7 +2875,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2773
2875
|
project had declared no caps, which is exactly the project that
|
|
2774
2876
|
needs the button to declare one. -->
|
|
2775
2877
|
<div class="mp-section-label" style="margin-top:24px">Agent budgets</div>
|
|
2776
|
-
<div id="agent-budgets" class="mp-card" style="padding:12px 16px;font-size:
|
|
2878
|
+
<div id="agent-budgets" class="mp-card" style="padding:12px 16px;font-size:var(--fs-small);margin-bottom:4px;"></div>
|
|
2777
2879
|
|
|
2778
2880
|
<div class="mp-section-label" id="mp-cost-label" style="margin-top:24px">Cost · last 30 days</div>
|
|
2779
2881
|
<div class="mp-card cost-panel" id="cost-panel">
|
|
@@ -2853,10 +2955,10 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2853
2955
|
<section aria-label="Legacy agents" id="legacy-agents-section" style="margin-top:20px" hidden>
|
|
2854
2956
|
<div class="mp-card">
|
|
2855
2957
|
<div class="mp-card-head">
|
|
2856
|
-
<h3 style="font-size:
|
|
2958
|
+
<h3 style="font-size:var(--fs-body)">Legacy / non-canonical sources</h3>
|
|
2857
2959
|
<span class="mp-card-meta" id="legacy-agents-count"></span>
|
|
2858
2960
|
</div>
|
|
2859
|
-
<div style="font-size:
|
|
2961
|
+
<div style="font-size:var(--fs-small);color:var(--text3);margin-top:6px">
|
|
2860
2962
|
Verdicts logged under agent names not in <code>~/.claude/agents/great_cto-*.md</code>
|
|
2861
2963
|
(older log files, custom scripts). Listed in <code>m.legacy_agent_runs</code>; cleanup is a
|
|
2862
2964
|
one-time housekeeping task.
|
|
@@ -2898,7 +3000,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2898
3000
|
|
|
2899
3001
|
<div class="panel" id="panel-budgets" role="tabpanel">
|
|
2900
3002
|
<div class="metrics-page">
|
|
2901
|
-
<h1>Agent budgets</h1>
|
|
3003
|
+
<h1 class="page-title">Agent budgets</h1>
|
|
2902
3004
|
<p class="muted" style="max-width:70ch;margin:6px 0 20px">
|
|
2903
3005
|
A cap on what one agent may spend. When measured spend passes it, the pipeline
|
|
2904
3006
|
refuses to dispatch that agent and says so — it does not fail quietly.
|
|
@@ -2910,7 +3012,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2910
3012
|
</div>
|
|
2911
3013
|
|
|
2912
3014
|
<div class="panel" id="panel-docs">
|
|
2913
|
-
<h1>Docs</h1>
|
|
3015
|
+
<h1 class="page-title">Docs</h1>
|
|
2914
3016
|
<div class="docs-search">
|
|
2915
3017
|
<input type="search" id="docs-q" placeholder="Search inside documents…"
|
|
2916
3018
|
aria-label="Search inside documents"
|
|
@@ -2961,7 +3063,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2961
3063
|
<button class="btn-black" onclick="copyUrl(event)">Copy</button>
|
|
2962
3064
|
|
|
2963
3065
|
</div>
|
|
2964
|
-
<div class="share-meta" id="share-meta" style="font-size:
|
|
3066
|
+
<div class="share-meta" id="share-meta" style="font-size:var(--fs-caption);color:var(--text3);margin-top:8px;font-family:var(--mono);"></div>
|
|
2965
3067
|
<div class="share-note">
|
|
2966
3068
|
The report includes shipped tasks, recent activity, agent utilization, and the six headline metrics.
|
|
2967
3069
|
Open issues, code, and credentials are <strong>never</strong> exposed.
|
|
@@ -2979,8 +3081,9 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2979
3081
|
<!-- Notifications -->
|
|
2980
3082
|
<div class="panel" id="panel-notifications">
|
|
2981
3083
|
<div class="share-page">
|
|
3084
|
+
<h1 class="page-title">Notifications</h1>
|
|
2982
3085
|
<div class="share-card">
|
|
2983
|
-
<h2>Email alerts</h2>
|
|
3086
|
+
<h2 class="section-title">Email alerts</h2>
|
|
2984
3087
|
<p class="sub">Get notified when something needs your attention — even when you're away from the board. Verify your email once, pick what to receive, done. No API keys, no extra signup.</p>
|
|
2985
3088
|
|
|
2986
3089
|
<div class="share-toggle-row">
|
|
@@ -2995,34 +3098,34 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
2995
3098
|
|
|
2996
3099
|
<!-- Step 1: enter email + send code -->
|
|
2997
3100
|
<div id="notif-step-email">
|
|
2998
|
-
<div style="font-size:
|
|
3101
|
+
<div style="font-size:var(--fs-caption);color:var(--text3);margin-bottom:4px;font-family:var(--mono);letter-spacing:.05em">RECIPIENT EMAIL</div>
|
|
2999
3102
|
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
|
3000
|
-
<input id="notif-to" type="email" placeholder="you@example.com" style="flex:1 1 280px;min-width:240px;padding:8px 10px;background:var(--
|
|
3103
|
+
<input id="notif-to" type="email" placeholder="you@example.com" style="flex:1 1 280px;min-width:240px;padding:8px 10px;background:var(--bg-muted);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:var(--fs-base)" />
|
|
3001
3104
|
<button class="btn-black" onclick="sendVerifyCode()">Send code</button>
|
|
3002
3105
|
</div>
|
|
3003
3106
|
</div>
|
|
3004
3107
|
|
|
3005
3108
|
<!-- Step 2: enter code -->
|
|
3006
3109
|
<div id="notif-step-code" style="display:none;margin-top:14px">
|
|
3007
|
-
<div style="font-size:
|
|
3110
|
+
<div style="font-size:var(--fs-caption);color:var(--text3);margin-bottom:4px;font-family:var(--mono);letter-spacing:.05em">VERIFICATION CODE (CHECK <span id="notif-code-target">YOUR INBOX</span>)</div>
|
|
3008
3111
|
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
|
3009
|
-
<input id="notif-code" type="text" inputmode="numeric" pattern="\d{6}" maxlength="6" placeholder="123456" style="flex:1 1 200px;min-width:140px;padding:8px 10px;background:var(--
|
|
3112
|
+
<input id="notif-code" type="text" inputmode="numeric" pattern="\d{6}" maxlength="6" placeholder="123456" style="flex:1 1 200px;min-width:140px;padding:8px 10px;background:var(--bg-muted);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:var(--fs-title-m);font-family:var(--mono);letter-spacing:.2em;text-align:center" />
|
|
3010
3113
|
<button class="btn-black" onclick="confirmVerifyCode()">Verify</button>
|
|
3011
3114
|
<button class="btn-ghost-sm" onclick="sendVerifyCode()">Resend code</button>
|
|
3012
3115
|
</div>
|
|
3013
3116
|
</div>
|
|
3014
3117
|
|
|
3015
3118
|
<!-- Step 3: verified -->
|
|
3016
|
-
<div id="notif-step-verified" style="display:none;margin-top:14px;padding:10px 14px;background:rgba(0,217,126,0.08);border:1px solid rgba(0,217,126,0.30);border-radius:8px;display:none;align-items:center;gap:10px;font-size:
|
|
3017
|
-
<span style="color:var(--accent);font-size:
|
|
3119
|
+
<div id="notif-step-verified" style="display:none;margin-top:14px;padding:10px 14px;background:rgba(0,217,126,0.08);border:1px solid rgba(0,217,126,0.30);border-radius:8px;display:none;align-items:center;gap:10px;font-size: var(--fs-body)">
|
|
3120
|
+
<span style="color:var(--accent);font-size:var(--fs-title-m)">✓</span>
|
|
3018
3121
|
<span><strong id="notif-verified-email">—</strong> verified · alerts delivered through <code>greatcto.systems/notify</code></span>
|
|
3019
3122
|
<button class="btn-ghost-sm" style="margin-left:auto" onclick="changeEmail()">Change</button>
|
|
3020
3123
|
</div>
|
|
3021
3124
|
|
|
3022
3125
|
<div class="share-note" style="margin-top:24px">
|
|
3023
|
-
<strong style="color:var(--
|
|
3126
|
+
<strong style="color:var(--text)">Which alerts to send</strong>
|
|
3024
3127
|
</div>
|
|
3025
|
-
<div id="notif-triggers" style="display:flex;flex-direction:column;gap:10px;margin-top:10px;font-size:
|
|
3128
|
+
<div id="notif-triggers" style="display:flex;flex-direction:column;gap:10px;margin-top:10px;font-size: var(--fs-body)">
|
|
3026
3129
|
<label class="notif-row"><input type="checkbox" data-trigger="incident.p0"> <span class="emoji">🚨</span><strong>P0 incident</strong> — production failure, ack-grade</label>
|
|
3027
3130
|
<label class="notif-row"><input type="checkbox" data-trigger="gate.stale"> <span class="emoji">⏸️</span><strong>Gate stale > 2h</strong> — ship gate waiting for your approval</label>
|
|
3028
3131
|
<label class="notif-row"><input type="checkbox" data-trigger="gate.blocked"> <span class="emoji">🛡️</span><strong>Security BLOCKED</strong> — security-officer rejected a merge</label>
|
|
@@ -3035,7 +3138,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
3035
3138
|
<button class="btn-ghost-sm" onclick="testNotifications()">Send test email</button>
|
|
3036
3139
|
</div>
|
|
3037
3140
|
|
|
3038
|
-
<div id="notif-status" style="margin-top:14px;font-size:
|
|
3141
|
+
<div id="notif-status" style="margin-top:14px;font-size:var(--fs-body);font-family:var(--mono)"></div>
|
|
3039
3142
|
|
|
3040
3143
|
<div class="share-note" style="margin-top:24px">
|
|
3041
3144
|
Free — up to 100 emails per day per verified email. Delivered through our <code>greatcto.systems/notify</code> relay; your inbox address never leaves your machine without your verification. Local state in <code>~/.great_cto/notifications.json</code>.
|
|
@@ -3044,7 +3147,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
3044
3147
|
|
|
3045
3148
|
<!-- ── Browser push card ───────────────────────────────────────── -->
|
|
3046
3149
|
<div class="share-card" style="margin-top:16px" id="push-card">
|
|
3047
|
-
<h2>Browser push</h2>
|
|
3150
|
+
<h2 class="section-title">Browser push</h2>
|
|
3048
3151
|
<p class="sub">Native desktop notifications — works even when the board tab is in the background. No email required. Uses Web Push (VAPID) — keys stay local.</p>
|
|
3049
3152
|
<div class="share-toggle-row">
|
|
3050
3153
|
<div class="label-grp">
|
|
@@ -3055,7 +3158,7 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
3055
3158
|
<input type="checkbox" id="push-toggle" onclick="event.stopPropagation()">
|
|
3056
3159
|
</div>
|
|
3057
3160
|
</div>
|
|
3058
|
-
<div id="push-status" style="margin-top:10px;font-size:
|
|
3161
|
+
<div id="push-status" style="margin-top:10px;font-size: var(--fs-small);font-family:var(--mono);color:var(--text3)"></div>
|
|
3059
3162
|
<div class="share-note" style="margin-top:16px">
|
|
3060
3163
|
Push subscriptions are stored locally in <code>~/.great_cto/push-subscriptions.json</code>. Notifications fire for the same 5 triggers as email alerts.
|
|
3061
3164
|
</div>
|
|
@@ -3063,10 +3166,10 @@ button { font-family: inherit; cursor: pointer; }
|
|
|
3063
3166
|
|
|
3064
3167
|
<!-- ── In-app notification history ─────────────────────────────── -->
|
|
3065
3168
|
<div class="share-card" style="margin-top:16px">
|
|
3066
|
-
<h2>Recent notifications</h2>
|
|
3169
|
+
<h2 class="section-title">Recent notifications</h2>
|
|
3067
3170
|
<p class="sub">Last 100 alerts fired this session. Also accessible via the notification drawer (bell icon).</p>
|
|
3068
3171
|
<div id="notif-history-inline" style="display:flex;flex-direction:column;gap:0;margin-top:12px;
|
|
3069
|
-
border:1px solid var(--border);border-radius:8px;overflow:hidden;font-size:
|
|
3172
|
+
border:1px solid var(--border);border-radius:8px;overflow:hidden;font-size:var(--fs-body)">
|
|
3070
3173
|
<div id="notif-history-empty" style="padding:20px 16px;color:var(--text3);text-align:center">
|
|
3071
3174
|
No notifications yet this session.
|
|
3072
3175
|
</div>
|
|
@@ -3250,7 +3353,7 @@ function freshnessBadge(doc) {
|
|
|
3250
3353
|
const unreadable = doc.freshnessBasis === 'unreadable';
|
|
3251
3354
|
const colour = v === 'stale' ? 'var(--status-gate)' : 'var(--text3)';
|
|
3252
3355
|
const label = v === 'stale' ? 'stale' : (unreadable ? 'could not read' : 'unknown');
|
|
3253
|
-
return `<span title="${esc(doc.freshnessWhy || '')}" style="font-family:var(--mono);font-size:
|
|
3356
|
+
return `<span title="${esc(doc.freshnessWhy || '')}" style="font-family:var(--mono);font-size:var(--fs-eyebrow);margin-left:6px;padding:0 4px;border:1px solid var(--border);border-radius:3px;color:${colour}">${esc(label)}</span>`;
|
|
3254
3357
|
}
|
|
3255
3358
|
|
|
3256
3359
|
// Will this gate wait for you, or did the pipeline already go past it?
|
|
@@ -3284,7 +3387,7 @@ function gateTierNote(t) {
|
|
|
3284
3387
|
// conclusively, which says nothing about the rest of what this agent is for.
|
|
3285
3388
|
// It is the reading most worth a second look, so it reads differently.
|
|
3286
3389
|
const caveat = thin ? ' — one eval, coverage unmeasured' : '';
|
|
3287
|
-
return `<div style="margin-top:3px;font-size:
|
|
3390
|
+
return `<div style="margin-top:3px;font-size:var(--fs-caption);color:${colour}">
|
|
3288
3391
|
<span style="font-family:var(--mono);border:1px solid var(--border);border-radius:3px;padding:0 4px">${esc(info.tier)}</span>
|
|
3289
3392
|
the pipeline did not wait for this${esc(caveat)} · <span title="${esc(info.why || '')}">${esc((info.why || '').slice(0, 90))}</span>
|
|
3290
3393
|
</div>`;
|
|
@@ -3324,7 +3427,7 @@ async function refreshStandDowns() {
|
|
|
3324
3427
|
// unmeasured coverage. That is the row most worth a second look, so it is
|
|
3325
3428
|
// the row that looks different.
|
|
3326
3429
|
const thin = r.tier === 'notify-thin';
|
|
3327
|
-
const tierTag = `<span style="font-family:var(--mono);font-size:
|
|
3430
|
+
const tierTag = `<span style="font-family:var(--mono);font-size:var(--fs-eyebrow);padding:1px 5px;border-radius:3px;border:1px solid var(--border);color:${thin ? 'var(--status-gate)' : 'var(--text3)'}">${esc(r.tier || 'unknown')}</span>`;
|
|
3328
3431
|
return `
|
|
3329
3432
|
<div class="inbox-row">
|
|
3330
3433
|
<span class="id">gate:${esc(r.gate || '?')}</span>
|
|
@@ -3369,7 +3472,7 @@ function renderInboxList(rootId, items, countId, opts = {}) {
|
|
|
3369
3472
|
<button class="gate-btn gate-approve" onclick="event.stopPropagation(); gateAction('${esc(t.id)}', 'approve')">Approve</button>
|
|
3370
3473
|
<button class="gate-btn gate-reject" onclick="event.stopPropagation(); gateAction('${esc(t.id)}', 'reject')">Reject</button>
|
|
3371
3474
|
</div>`
|
|
3372
|
-
: `<div class="actions"><span style="font-family:var(--mono);font-size:
|
|
3475
|
+
: `<div class="actions"><span style="font-family:var(--mono);font-size:var(--fs-caption);color:var(--text3)">${t.status || ''}</span></div>`;
|
|
3373
3476
|
const desc = t.description ? `<span class="ttl-desc">${esc(t.description.slice(0, 140))}${t.description.length > 140 ? '…' : ''}</span>` : '';
|
|
3374
3477
|
// Only gate rows can stand down, so only they carry the note.
|
|
3375
3478
|
const tierNote = opts.showApprove ? gateTierNote(t) : '';
|
|
@@ -3554,11 +3657,32 @@ async function loadBudgetsPage() {
|
|
|
3554
3657
|
if (!body) return;
|
|
3555
3658
|
body.innerHTML = '<div class="muted">loading…</div>';
|
|
3556
3659
|
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3660
|
+
// Three states, not two: loading | loaded | failed.
|
|
3661
|
+
//
|
|
3662
|
+
// Without this catch the two reads below were awaited bare, so a rejection
|
|
3663
|
+
// returned from the function and left `loading…` on screen permanently. Caught
|
|
3664
|
+
// once in the wild: opening Budgets during startup raced the agent list, the
|
|
3665
|
+
// promise rejected, and the page sat there looking busy. A page that failed
|
|
3666
|
+
// and a page still working are the same picture, and the one you are looking
|
|
3667
|
+
// at is the one where nothing more is coming.
|
|
3668
|
+
let h;
|
|
3669
|
+
try {
|
|
3670
|
+
[h] = await Promise.all([
|
|
3671
|
+
api(`/api/heartbeat${pqs()}`),
|
|
3672
|
+
(typeof refreshAgentsInstalled === 'function' && !(fleetState?.agents || []).length)
|
|
3673
|
+
? refreshAgentsInstalled() : Promise.resolve(),
|
|
3674
|
+
]);
|
|
3675
|
+
} catch (err) {
|
|
3676
|
+
body.innerHTML = `
|
|
3677
|
+
<div class="budgets-failed">
|
|
3678
|
+
<div class="bf-head">Could not read the caps.</div>
|
|
3679
|
+
<div class="bf-why">${esc(String(err && err.message || err))}</div>
|
|
3680
|
+
<div class="bf-note">Caps already set are unaffected — this failed to
|
|
3681
|
+
<em>read</em> them, and the pipeline reads them itself, not from here.</div>
|
|
3682
|
+
<button class="btn" onclick="loadBudgetsPage()">Try again</button>
|
|
3683
|
+
</div>`;
|
|
3684
|
+
return;
|
|
3685
|
+
}
|
|
3562
3686
|
const caps = h?.budgets || {};
|
|
3563
3687
|
const agents = (fleetState?.agents || []).filter((a) => !a.retired);
|
|
3564
3688
|
|
|
@@ -3902,7 +4026,7 @@ function showVerdictDetail(idx) {
|
|
|
3902
4026
|
<span>${esc(a.path)}</span>
|
|
3903
4027
|
</a>`;
|
|
3904
4028
|
}).join('')
|
|
3905
|
-
: '<span style="color: var(--text3); font-size:
|
|
4029
|
+
: '<span style="color: var(--text3); font-size: var(--fs-small);">No artefacts referenced in this verdict</span>';
|
|
3906
4030
|
|
|
3907
4031
|
// Format additional metadata (cost, feature, etc.) as small chips
|
|
3908
4032
|
const metaKeys = ['feature', 'task', 'cost'];
|
|
@@ -3930,7 +4054,7 @@ function showVerdictDetail(idx) {
|
|
|
3930
4054
|
<div class="rdm-artefacts-title">Artefacts (click to open in editor)</div>
|
|
3931
4055
|
${artefactsHtml}
|
|
3932
4056
|
</div>
|
|
3933
|
-
<div class="rdm-foot">Press <kbd style="background:var(--bg-muted);border:1px solid var(--border);border-radius:3px;padding:1px 5px;font-size:
|
|
4057
|
+
<div class="rdm-foot">Press <kbd style="background:var(--bg-muted);border:1px solid var(--border);border-radius:3px;padding:1px 5px;font-size:var(--fs-eyebrow);">Esc</kbd> or click outside to close</div>
|
|
3934
4058
|
</div>
|
|
3935
4059
|
`;
|
|
3936
4060
|
document.body.appendChild(modal);
|
|
@@ -4410,7 +4534,7 @@ async function loadDocs() {
|
|
|
4410
4534
|
? `<div class="card"><b>Pipeline</b> <span class="muted">— how a feature moves, drawn from shared/pipeline.toml</span>
|
|
4411
4535
|
${renderDeclaredPipeline(d.pipeline)}
|
|
4412
4536
|
<details style="margin-top:8px"><summary class="muted">Mermaid source</summary>
|
|
4413
|
-
<pre style="white-space:pre-wrap;font-size:
|
|
4537
|
+
<pre style="white-space:pre-wrap;font-size:var(--fs-caption)">${esc(d.pipeline)}</pre></details></div>`
|
|
4414
4538
|
: '';
|
|
4415
4539
|
|
|
4416
4540
|
const map = d.map ? `<div class="card"><b>Components</b>
|
|
@@ -4418,19 +4542,19 @@ async function loadDocs() {
|
|
|
4418
4542
|
<div style="display:flex;flex-wrap:wrap;gap:8px;margin-top:10px">
|
|
4419
4543
|
${d.map.nodes.map(n => `<div style="border:1px solid var(--border,#ddd);border-radius:6px;padding:8px 10px;min-width:120px">
|
|
4420
4544
|
<div><b>${esc(n.label)}</b> <span class="muted">${n.count}</span></div>
|
|
4421
|
-
<div class="muted" style="font-size:
|
|
4545
|
+
<div class="muted" style="font-size:var(--fs-caption)">${esc(n.what || '')}</div></div>`).join('')}
|
|
4422
4546
|
</div>
|
|
4423
|
-
${d.map.edges.length ? `<div class="muted" style="margin-top:8px;font-size:
|
|
4547
|
+
${d.map.edges.length ? `<div class="muted" style="margin-top:8px;font-size:var(--fs-caption)">
|
|
4424
4548
|
${d.map.edges.map(e => `${esc(e.from)}→${esc(e.to)} (${e.count})`).join(' · ')}</div>` : ''}
|
|
4425
4549
|
<details style="margin-top:8px"><summary class="muted">Mermaid source</summary>
|
|
4426
|
-
<pre style="white-space:pre-wrap;font-size:
|
|
4550
|
+
<pre style="white-space:pre-wrap;font-size:var(--fs-caption)">${esc(d.map.mermaid)}</pre></details></div>` : '';
|
|
4427
4551
|
|
|
4428
4552
|
const groups = (d.groups || []).map(g => `<div class="card">
|
|
4429
4553
|
<b>${esc(g.label)}</b> <span class="muted">${g.docs.length} — ${esc(g.why || '')}</span>
|
|
4430
4554
|
<div style="margin-top:8px">${g.docs.map(doc => `
|
|
4431
4555
|
<div style="padding:4px 0;border-bottom:1px solid var(--border,#eee)">
|
|
4432
4556
|
<a href="#" onclick="openDoc('${esc(doc.path)}');return false">${esc(doc.title)}</a>
|
|
4433
|
-
<span class="muted" style="font-size:
|
|
4557
|
+
<span class="muted" style="font-size:var(--fs-caption)"> · ${esc(doc.path)} · ${ago(doc.modified)}</span>
|
|
4434
4558
|
${freshnessBadge(doc)}
|
|
4435
4559
|
</div>`).join('')}</div>
|
|
4436
4560
|
</div>`).join('');
|
|
@@ -4513,11 +4637,11 @@ async function loadContextLayers() {
|
|
|
4513
4637
|
|
|
4514
4638
|
const layers = (m.layers || []).map(l => {
|
|
4515
4639
|
const global = String(l.path || '').includes('/.great_cto/') && !String(l.path || '').includes(projectRootHint());
|
|
4516
|
-
const where = global ? ' <span class="muted" style="font-size:
|
|
4640
|
+
const where = global ? ' <span class="muted" style="font-size:var(--fs-caption)">shared by every project</span>' : '';
|
|
4517
4641
|
return l.exists
|
|
4518
4642
|
? `<div style="padding:4px 0;border-bottom:1px solid var(--border,#eee)">
|
|
4519
4643
|
<a href="#" onclick="openDoc('${esc(l.path)}');return false">${esc(l.id)}</a>${where}
|
|
4520
|
-
<span class="muted" style="font-size:
|
|
4644
|
+
<span class="muted" style="font-size:var(--fs-caption)"> · ${esc(l.path)}</span></div>`
|
|
4521
4645
|
: `<div style="padding:4px 0;border-bottom:1px solid var(--border,#eee)" class="muted">
|
|
4522
4646
|
${esc(l.id)} — not written yet${where}</div>`;
|
|
4523
4647
|
}).join('');
|
|
@@ -4561,7 +4685,7 @@ function renderDeclaredPipeline(mermaid) {
|
|
|
4561
4685
|
}
|
|
4562
4686
|
if (!edges.length) return '<div class="muted">no transitions declared</div>';
|
|
4563
4687
|
const name = (id) => id.replace(/_/g, '-');
|
|
4564
|
-
return `<div style="margin-top:10px;font-size:
|
|
4688
|
+
return `<div style="margin-top:10px;font-size:var(--fs-small)">${edges.map(e => `
|
|
4565
4689
|
<div style="display:flex;align-items:center;gap:8px;padding:3px 0">
|
|
4566
4690
|
<span style="border:1px solid var(--border,#ddd);border-radius:4px;padding:2px 8px">${esc(name(e.from))}</span>
|
|
4567
4691
|
<span class="muted">${e.join ? '⋯ join ⋯' : (e.gate ? `→ ${esc(e.gate)} →` : '→')}</span>
|
|
@@ -4596,7 +4720,7 @@ async function openDoc(p) {
|
|
|
4596
4720
|
const d = await api(`/api/doc?path=${encodeURIComponent(p)}${q ? '&' + q.slice(1) : ''}`);
|
|
4597
4721
|
if (!d || d.error) throw new Error(d?.error || 'doc not found');
|
|
4598
4722
|
idEl.textContent = d.name || p;
|
|
4599
|
-
body.innerHTML = `<div class="muted" style="font-size:
|
|
4723
|
+
body.innerHTML = `<div class="muted" style="font-size:var(--fs-caption);margin-bottom:10px">${esc(d.path)}</div>
|
|
4600
4724
|
<div class="side-desc md">${mdToHtml(d.content)}</div>`;
|
|
4601
4725
|
} catch (e) {
|
|
4602
4726
|
body.innerHTML = `<div class="side-desc"><b>Could not open ${esc(p)}</b>
|
|
@@ -5462,7 +5586,7 @@ function cardHTML(t) {
|
|
|
5462
5586
|
${t.agent ? `<span class="chip chip-agent">${esc(t.agent)}</span>` : ''}
|
|
5463
5587
|
${labels.map(l => `<span class="chip">${esc(l)}</span>`).join('')}
|
|
5464
5588
|
<div class="card-status-edit" onclick="event.stopPropagation(); openStatusPicker('${esc(t.id)}', this)">
|
|
5465
|
-
<span class="pill pill-${t.status || 'backlog'}" style="font-size:
|
|
5589
|
+
<span class="pill pill-${t.status || 'backlog'}" style="font-size:var(--fs-eyebrow);height:18px;padding:0 7px">${(t.status || 'backlog').replace('_',' ')}</span>
|
|
5466
5590
|
<span class="card-status-chev"><svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg></span>
|
|
5467
5591
|
</div>
|
|
5468
5592
|
${elapsed}
|
|
@@ -6095,7 +6219,7 @@ function openSide(task) {
|
|
|
6095
6219
|
const docsSec = docRefs.length ? `
|
|
6096
6220
|
<div class="side-section"><div class="side-section-head">Documents</div>
|
|
6097
6221
|
${docRefs.map(p => `
|
|
6098
|
-
<button onclick="openDocInSide('${esc(p)}')" style="display:flex;width:100%;gap:8px;align-items:center;text-align:left;background:var(--
|
|
6222
|
+
<button onclick="openDocInSide('${esc(p)}')" style="display:flex;width:100%;gap:8px;align-items:center;text-align:left;background:var(--bg-muted);border:1px solid var(--border);border-radius:6px;padding:6px 10px;margin:4px 0;cursor:pointer;font-family:var(--mono);font-size:var(--fs-small);color:inherit">
|
|
6099
6223
|
<span style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${esc(p)}</span>
|
|
6100
6224
|
<span style="color:var(--text3)">open →</span>
|
|
6101
6225
|
</button>`).join('')}
|
|
@@ -6197,15 +6321,22 @@ document.addEventListener('keydown', e => { if (e.key === 'Escape') closeSide();
|
|
|
6197
6321
|
*/
|
|
6198
6322
|
async function checkBoardFreshness() {
|
|
6199
6323
|
const v = await api('/api/version');
|
|
6200
|
-
|
|
6324
|
+
// `behind` and `ahead` are different problems with different fixes; `no` and
|
|
6325
|
+
// `unknown` are both silent, because a comparison we could not make must not
|
|
6326
|
+
// render as a mismatch.
|
|
6327
|
+
if (!v || (v.stale !== 'behind' && v.stale !== 'ahead')) return;
|
|
6201
6328
|
const host = document.querySelector('.workspace');
|
|
6202
6329
|
if (!host || document.getElementById('stale-board')) return;
|
|
6203
6330
|
const el = document.createElement('div');
|
|
6204
6331
|
el.id = 'stale-board';
|
|
6205
6332
|
el.className = 'stale-board';
|
|
6206
6333
|
el.setAttribute('role', 'status');
|
|
6207
|
-
el.innerHTML =
|
|
6208
|
-
|
|
6334
|
+
el.innerHTML = v.stale === 'behind'
|
|
6335
|
+
? `<span>This board is running <code>v${esc(v.version)}</code> — `
|
|
6336
|
+
+ `<code>v${esc(v.installed)}</code> is installed. Restart it to pick up the new version.</span>`
|
|
6337
|
+
: `<span>This board is running <code>v${esc(v.version)}</code>, which is newer than the `
|
|
6338
|
+
+ `installed <code>v${esc(v.installed)}</code>. Restarting would go back to the older build — `
|
|
6339
|
+
+ `install this version first.</span>`;
|
|
6209
6340
|
host.insertBefore(el, host.firstChild);
|
|
6210
6341
|
}
|
|
6211
6342
|
|
|
@@ -6491,7 +6622,7 @@ function renderLogsList() {
|
|
|
6491
6622
|
|
|
6492
6623
|
el.innerHTML = bar + shown.map(({ log, i }) => `
|
|
6493
6624
|
<div class="log-item ${i === 0 ? 'active' : ''}" onclick="selectLog(${i}, this)">
|
|
6494
|
-
<div class="log-date">${esc(log.date)}${log.time ? ' · ' + esc(log.time) : ''}${log.source === 'verdicts' || log.source === 'auto' ? ' <span style="color:var(--text3);font-size:
|
|
6625
|
+
<div class="log-date">${esc(log.date)}${log.time ? ' · ' + esc(log.time) : ''}${log.source === 'verdicts' || log.source === 'auto' ? ' <span style="color:var(--text3);font-size:var(--fs-eyebrow)">· auto</span>' : ''}</div>
|
|
6495
6626
|
<div class="log-title">${esc(log.title)}</div>
|
|
6496
6627
|
<div class="log-meta">${log.done.length} done · ${log.pending.length} pending${log.duration ? ' · ' + esc(log.duration) : ''}</div>
|
|
6497
6628
|
</div>`).join('');
|
|
@@ -6854,14 +6985,14 @@ function renderAgentProfile(p) {
|
|
|
6854
6985
|
<dt>domain</dt> <dd>${esc(p.domain)}</dd>
|
|
6855
6986
|
<dt>model</dt> <dd>${esc(p.model)}</dd>
|
|
6856
6987
|
${p.applies_to.length ? `<dt>applies_to</dt><dd>${esc(p.applies_to.join(', '))}</dd>` : ''}
|
|
6857
|
-
${(p.tools && p.tools.length) ? `<dt>tools</dt><dd>${p.tools.map(t => `<span class="chip" style="font-size:
|
|
6858
|
-
${(p.skills && p.skills.length) ? `<dt>skills</dt><dd>${p.skills.map(s => `<span class="chip chip-agent" style="font-size:
|
|
6988
|
+
${(p.tools && p.tools.length) ? `<dt>tools</dt><dd>${p.tools.map(t => `<span class="chip" style="font-size:var(--fs-caption)">${esc(t)}</span>`).join(' ')}</dd>` : '<dt>tools</dt><dd style="color:var(--text3)">none declared</dd>'}
|
|
6989
|
+
${(p.skills && p.skills.length) ? `<dt>skills</dt><dd>${p.skills.map(s => `<span class="chip chip-agent" style="font-size:var(--fs-caption)">${esc(s)}</span>`).join(' ')}</dd>` : ''}
|
|
6859
6990
|
<dt>runs total</dt> <dd>${p.runs_total} · ${p.runs_30d} in 30d</dd>
|
|
6860
6991
|
<dt>success</dt> <dd>${p.success_rate != null ? `${p.success_rate}% (${p.ok_30d}/${p.ok_30d + p.fail_30d})` : 'no verdicts in 30d'}</dd>
|
|
6861
6992
|
<dt>last run</dt> <dd>${p.last_run ? esc(p.last_run.slice(0, 16).replace('T', ' ') + ' · ' + agoStr(p.last_run)) : 'never'}</dd>
|
|
6862
6993
|
<dt>savings</dt> <dd>${esc(savings)} ${esc(realCost)}</dd>
|
|
6863
6994
|
</dl>
|
|
6864
|
-
${p.description ? `<div style="font-size:
|
|
6995
|
+
${p.description ? `<div style="font-size:var(--fs-caption);color:var(--text3);margin-top:8px;line-height:1.5">${esc(p.description)}</div>` : ''}
|
|
6865
6996
|
</div>
|
|
6866
6997
|
|
|
6867
6998
|
<div class="mp-card">
|
|
@@ -6899,7 +7030,7 @@ function renderAgentProfile(p) {
|
|
|
6899
7030
|
? `<button type="button" onclick="restoreAgentAction('${esc(p.slug)}')">Restore agent</button>`
|
|
6900
7031
|
: `<button type="button" class="danger" onclick="retireAgentAction('${esc(p.slug)}')">Retire agent</button>`}
|
|
6901
7032
|
</div>
|
|
6902
|
-
<div style="font-size:
|
|
7033
|
+
<div style="font-size:var(--fs-caption);color:var(--text3);margin-top:8px">
|
|
6903
7034
|
File: <code>${esc(p.file_path)}</code>
|
|
6904
7035
|
</div>
|
|
6905
7036
|
</div>`;
|
|
@@ -7234,12 +7365,12 @@ function renderNotifDrawer() {
|
|
|
7234
7365
|
style="padding:12px 16px;border-bottom:1px solid var(--border);
|
|
7235
7366
|
${n.read ? '' : 'background:rgba(59,130,246,0.06);'}">
|
|
7236
7367
|
<div style="display:flex;align-items:flex-start;gap:10px">
|
|
7237
|
-
<span style="font-size:
|
|
7368
|
+
<span style="font-size:var(--fs-title-s);flex-shrink:0;margin-top:1px">${_notifLevelIcon(n.level)}</span>
|
|
7238
7369
|
<div style="flex:1;min-width:0">
|
|
7239
|
-
<div style="font-size:
|
|
7370
|
+
<div style="font-size:var(--fs-body);font-weight:${n.read ? '400' : '600'};color:var(--text);
|
|
7240
7371
|
white-space:nowrap;overflow:hidden;text-overflow:ellipsis">${esc(n.title)}</div>
|
|
7241
|
-
<div style="font-size:
|
|
7242
|
-
<div style="font-size:
|
|
7372
|
+
<div style="font-size:var(--fs-small);color:var(--text3);margin-top:2px;line-height:1.4">${esc(n.body)}</div>
|
|
7373
|
+
<div style="font-size:var(--fs-caption);color:var(--text3);margin-top:4px;font-family:var(--mono)">
|
|
7243
7374
|
${n.project ? `<span style="color:var(--accent);margin-right:6px">${esc(n.project)}</span>` : ''}
|
|
7244
7375
|
${new Date(n.ts).toLocaleString()}
|
|
7245
7376
|
</div>
|
|
@@ -7260,12 +7391,12 @@ function renderNotifHistoryInline() {
|
|
|
7260
7391
|
el.innerHTML = _notifHistory.slice(0, 20).map(n => `
|
|
7261
7392
|
<div class="notif-inline-row" style="padding:10px 14px;border-bottom:1px solid var(--border);
|
|
7262
7393
|
display:flex;align-items:center;gap:10px;${n.read ? '' : 'background:rgba(59,130,246,0.05);'}">
|
|
7263
|
-
<span style="font-size:
|
|
7394
|
+
<span style="font-size:var(--fs-base)">${_notifLevelIcon(n.level)}</span>
|
|
7264
7395
|
<div style="flex:1;min-width:0">
|
|
7265
|
-
<span style="font-size:
|
|
7266
|
-
<span style="font-size:
|
|
7396
|
+
<span style="font-size:var(--fs-body);font-weight:${n.read?'400':'600'}">${esc(n.title)}</span>
|
|
7397
|
+
<span style="font-size:var(--fs-small);color:var(--text3);margin-left:8px">${esc(n.body)}</span>
|
|
7267
7398
|
</div>
|
|
7268
|
-
<span style="font-size:
|
|
7399
|
+
<span style="font-size:var(--fs-caption);color:var(--text3);font-family:var(--mono);flex-shrink:0">
|
|
7269
7400
|
${new Date(n.ts).toLocaleTimeString()}
|
|
7270
7401
|
</span>
|
|
7271
7402
|
</div>`).join('');
|
|
@@ -7416,7 +7547,7 @@ if (_costLbl) _costLbl.textContent = `Cost · last ${periodLabel(currentPeriod)}
|
|
|
7416
7547
|
|
|
7417
7548
|
<!-- ── Notification drawer ──────────────────────────────────────────────── -->
|
|
7418
7549
|
<div id="notif-drawer" style="position:fixed;top:0;right:-400px;width:380px;height:100vh;
|
|
7419
|
-
background:var(--
|
|
7550
|
+
background:var(--bg-elevated);border-left:1px solid var(--border);z-index:9999;
|
|
7420
7551
|
transition:right .25s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;
|
|
7421
7552
|
box-shadow:-4px 0 32px rgba(0,0,0,.5)">
|
|
7422
7553
|
<div style="padding:14px 16px;border-bottom:1px solid var(--border);
|
|
@@ -7425,16 +7556,16 @@ if (_costLbl) _costLbl.textContent = `Cost · last ${periodLabel(currentPeriod)}
|
|
|
7425
7556
|
style="width:16px;height:16px;color:var(--text2)">
|
|
7426
7557
|
<path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9 M10.3 21a1.94 1.94 0 0 0 3.4 0"/>
|
|
7427
7558
|
</svg>
|
|
7428
|
-
<span style="font-weight:600;font-size:
|
|
7559
|
+
<span style="font-weight:600;font-size:var(--fs-base);flex:1;color:var(--text)">Notifications</span>
|
|
7429
7560
|
<button class="btn-ghost-sm" onclick="markAllNotifsRead()"
|
|
7430
|
-
style="font-size:
|
|
7561
|
+
style="font-size:var(--fs-small)">Mark all read</button>
|
|
7431
7562
|
<button onclick="closeNotifDrawer()" style="background:none;border:none;cursor:pointer;
|
|
7432
|
-
color:var(--text3);font-size:
|
|
7563
|
+
color:var(--text3);font-size:var(--fs-title-l);line-height:1;padding:0 4px;margin-left:4px">×</button>
|
|
7433
7564
|
</div>
|
|
7434
7565
|
<div id="notif-drawer-list" tabindex="0" role="region" aria-label="Notifications list" style="flex:1;overflow-y:auto"></div>
|
|
7435
7566
|
<div id="notif-drawer-empty" style="display:flex;flex:1;align-items:center;
|
|
7436
|
-
justify-content:center;flex-direction:column;gap:8px;color:var(--text3);font-size:
|
|
7437
|
-
<span style="font-size:
|
|
7567
|
+
justify-content:center;flex-direction:column;gap:8px;color:var(--text3);font-size:var(--fs-body)">
|
|
7568
|
+
<span style="font-size:var(--fs-num-l)">🔔</span>No notifications yet
|
|
7438
7569
|
</div>
|
|
7439
7570
|
</div>
|
|
7440
7571
|
<div id="notif-drawer-overlay" onclick="closeNotifDrawer()"
|