portable-agent-layer 0.72.0 → 0.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/package.json +10 -7
  2. package/src/cli/index.ts +21 -2
  3. package/src/cli/server.ts +33 -0
  4. package/src/hooks/handlers/agenda.ts +195 -7
  5. package/src/hooks/handlers/update-check.ts +1 -1
  6. package/src/hooks/lib/agenda-store.ts +2 -0
  7. package/src/hooks/lib/goal-links.ts +83 -0
  8. package/src/hooks/lib/models.ts +1 -1
  9. package/src/hooks/lib/projects.ts +5 -0
  10. package/src/hooks/lib/settings.ts +2 -0
  11. package/src/hooks/lib/telos-goals.ts +8 -2
  12. package/src/hooks/lib/token-usage.ts +2 -0
  13. package/src/tools/agent/project.ts +22 -20
  14. package/src/tools/control-room/attention.ts +146 -0
  15. package/src/tools/control-room/data.ts +76 -5
  16. package/src/tools/control-room/detail.ts +158 -0
  17. package/src/tools/control-room/matrix.ts +91 -19
  18. package/src/tools/control-room/prefs.ts +96 -0
  19. package/src/tools/control-room/server-config.ts +8 -0
  20. package/src/tools/control-room/server.ts +196 -11
  21. package/src/tools/control-room/snooze.ts +65 -0
  22. package/src/tools/control-room/static.ts +68 -0
  23. package/src/tools/control-room/ui/app.tsx +196 -50
  24. package/src/tools/control-room/ui/attention-bell.tsx +118 -0
  25. package/src/tools/control-room/ui/components/README.md +18 -0
  26. package/src/tools/control-room/ui/components/badge.tsx +38 -0
  27. package/src/tools/control-room/ui/components/button.tsx +43 -0
  28. package/src/tools/control-room/ui/components/card.tsx +45 -0
  29. package/src/tools/control-room/ui/components/input.tsx +24 -0
  30. package/src/tools/control-room/ui/components/label.tsx +18 -0
  31. package/src/tools/control-room/ui/components/popover.tsx +37 -0
  32. package/src/tools/control-room/ui/components/separator.tsx +25 -0
  33. package/src/tools/control-room/ui/components/skeleton.tsx +14 -0
  34. package/src/tools/control-room/ui/components/switch.tsx +27 -0
  35. package/src/tools/control-room/ui/components/table.tsx +60 -0
  36. package/src/tools/control-room/ui/components/toggle-group.tsx +38 -0
  37. package/src/tools/control-room/ui/dist/assets/index-BoQjFpzV.js +49 -0
  38. package/src/tools/control-room/ui/dist/assets/index-Dncp2bYg.css +2 -0
  39. package/src/tools/control-room/ui/dist/index.html +19 -0
  40. package/src/tools/control-room/ui/format.ts +0 -12
  41. package/src/tools/control-room/ui/frame.tsx +125 -0
  42. package/src/tools/control-room/ui/index.html +2 -2
  43. package/src/tools/control-room/ui/lib/api.ts +27 -0
  44. package/src/tools/control-room/ui/lib/cn.ts +6 -0
  45. package/src/tools/control-room/ui/lib/write.ts +43 -0
  46. package/src/tools/control-room/ui/package.json +28 -0
  47. package/src/tools/control-room/ui/parts.tsx +235 -0
  48. package/src/tools/control-room/ui/screens/log.tsx +274 -0
  49. package/src/tools/control-room/ui/screens/project-detail.tsx +302 -0
  50. package/src/tools/control-room/ui/screens/projects.tsx +128 -0
  51. package/src/tools/control-room/ui/screens/settings.tsx +205 -0
  52. package/src/tools/control-room/ui/screens/today.tsx +391 -0
  53. package/src/tools/control-room/ui/theme.css +127 -0
  54. package/src/tools/control-room/ui/vite.config.ts +36 -0
  55. package/src/tools/control-room/writes.ts +106 -0
  56. package/src/tools/ledger/outcomes.ts +9 -0
  57. package/src/tools/ledger/query.ts +2 -0
  58. package/src/tools/ledger/view.ts +31 -10
  59. package/src/tools/lib/handoff-note.ts +14 -0
  60. package/src/tools/lib/project-isc.ts +61 -0
  61. package/src/tools/control-room/ui/agenda.tsx +0 -43
  62. package/src/tools/control-room/ui/agents.tsx +0 -67
  63. package/src/tools/control-room/ui/app.css +0 -857
  64. package/src/tools/control-room/ui/board.tsx +0 -82
  65. package/src/tools/control-room/ui/handoffs.tsx +0 -37
  66. package/src/tools/control-room/ui/ledger.tsx +0 -137
  67. package/src/tools/control-room/ui/matrix.tsx +0 -117
  68. package/src/tools/control-room/ui/panel.tsx +0 -60
  69. package/src/tools/control-room/ui/signal.tsx +0 -161
@@ -1,857 +0,0 @@
1
- :root {
2
- --bg: #0d1013;
3
- --panel: #13171b;
4
- --panel-raised: #181d22;
5
- --line: rgba(230, 226, 214, 0.1);
6
- --line-strong: rgba(230, 226, 214, 0.22);
7
- --ink: #e6e2d6;
8
- --ink-soft: #b9b5aa;
9
- --muted: #7f8790;
10
- --amber: #f0b14a;
11
- --amber-ink: #2a1d05;
12
- --good: #6fd3b6;
13
- --bad: #ee6a5f;
14
- --wait: #86b4ff;
15
- --serif: "Newsreader", "Iowan Old Style", Georgia, serif;
16
- --mono: "Martian Mono", ui-monospace, "SF Mono", Menlo, monospace;
17
- }
18
-
19
- * {
20
- box-sizing: border-box;
21
- }
22
-
23
- html,
24
- body {
25
- margin: 0;
26
- background: var(--bg);
27
- color: var(--ink);
28
- font-family: var(--mono);
29
- font-size: 12px;
30
- line-height: 1.5;
31
- -webkit-font-smoothing: antialiased;
32
- }
33
-
34
- body::before {
35
- content: "";
36
- position: fixed;
37
- inset: 0;
38
- pointer-events: none;
39
- background:
40
- radial-gradient(1200px 500px at 20% -10%, rgba(240, 177, 74, 0.09), transparent 60%),
41
- radial-gradient(rgba(230, 226, 214, 0.055) 1px, transparent 1px) 0 0 / 24px 24px;
42
- }
43
-
44
- a {
45
- color: inherit;
46
- }
47
-
48
- .room {
49
- position: relative;
50
- max-width: 1480px;
51
- margin: 0 auto;
52
- padding: 28px 32px 64px;
53
- }
54
-
55
- .masthead {
56
- display: flex;
57
- align-items: baseline;
58
- justify-content: space-between;
59
- gap: 24px;
60
- padding-bottom: 18px;
61
- border-bottom: 1px solid var(--line-strong);
62
- margin-bottom: 22px;
63
- }
64
-
65
- .masthead h1 {
66
- margin: 0;
67
- font-family: var(--serif);
68
- font-weight: 400;
69
- font-size: 34px;
70
- letter-spacing: -0.01em;
71
- line-height: 1;
72
- }
73
-
74
- .masthead h1 em {
75
- font-style: italic;
76
- color: var(--amber);
77
- }
78
-
79
- .masthead .meta {
80
- display: flex;
81
- gap: 22px;
82
- color: var(--muted);
83
- font-size: 11px;
84
- letter-spacing: 0.04em;
85
- text-transform: uppercase;
86
- }
87
-
88
- .masthead b {
89
- color: var(--ink-soft);
90
- font-weight: 400;
91
- }
92
-
93
- .grid {
94
- display: grid;
95
- grid-template-columns: repeat(12, minmax(0, 1fr));
96
- gap: 18px;
97
- }
98
-
99
- .panel {
100
- grid-column: span var(--span, 12);
101
- background: var(--panel);
102
- border: 1px solid var(--line);
103
- padding: 18px 20px 20px;
104
- min-width: 0;
105
- opacity: 0;
106
- transform: translateY(8px);
107
- animation: rise 520ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
108
- animation-delay: calc(var(--i, 0) * 80ms);
109
- }
110
-
111
- @keyframes rise {
112
- to {
113
- opacity: 1;
114
- transform: none;
115
- }
116
- }
117
-
118
- .panel > header {
119
- display: flex;
120
- align-items: baseline;
121
- justify-content: space-between;
122
- gap: 12px;
123
- margin-bottom: 14px;
124
- }
125
-
126
- .panel > header .index {
127
- display: block;
128
- color: var(--muted);
129
- font-size: 10px;
130
- letter-spacing: 0.14em;
131
- text-transform: uppercase;
132
- margin-bottom: 2px;
133
- }
134
-
135
- .panel > header h2 {
136
- margin: 0;
137
- font-family: var(--serif);
138
- font-style: italic;
139
- font-weight: 400;
140
- font-size: 22px;
141
- line-height: 1.1;
142
- }
143
-
144
- .panel > header .aside {
145
- color: var(--muted);
146
- font-size: 11px;
147
- white-space: nowrap;
148
- }
149
-
150
- .empty {
151
- color: var(--muted);
152
- font-family: var(--serif);
153
- font-style: italic;
154
- font-size: 15px;
155
- padding: 10px 0;
156
- }
157
-
158
- .tag {
159
- display: inline-block;
160
- padding: 1px 7px;
161
- font-size: 10px;
162
- letter-spacing: 0.06em;
163
- text-transform: uppercase;
164
- border: 1px solid var(--line-strong);
165
- color: var(--ink-soft);
166
- white-space: nowrap;
167
- }
168
-
169
- .tag.amber {
170
- background: var(--amber);
171
- border-color: var(--amber);
172
- color: var(--amber-ink);
173
- font-weight: 600;
174
- }
175
-
176
- .tag.bad {
177
- border-color: var(--bad);
178
- color: var(--bad);
179
- }
180
-
181
- .tag.good {
182
- border-color: var(--good);
183
- color: var(--good);
184
- }
185
-
186
- .tag.wait {
187
- border-color: var(--wait);
188
- color: var(--wait);
189
- }
190
-
191
- .tag.ghost {
192
- border-style: dashed;
193
- color: var(--muted);
194
- }
195
-
196
- /* ── board ─────────────────────────────────────────────── */
197
-
198
- .board {
199
- display: flex;
200
- flex-direction: column;
201
- }
202
-
203
- .project {
204
- display: grid;
205
- grid-template-columns: 220px minmax(0, 1fr) auto;
206
- gap: 8px 18px;
207
- padding: 11px 0;
208
- border-top: 1px solid var(--line);
209
- align-items: baseline;
210
- }
211
-
212
- .project:first-child {
213
- border-top: 0;
214
- }
215
-
216
- .project .name {
217
- font-weight: 600;
218
- font-size: 13px;
219
- overflow: hidden;
220
- text-overflow: ellipsis;
221
- white-space: nowrap;
222
- }
223
-
224
- .project.asking .name {
225
- color: var(--amber);
226
- }
227
-
228
- .project .name small {
229
- display: block;
230
- font-weight: 300;
231
- color: var(--muted);
232
- font-size: 10px;
233
- letter-spacing: 0.06em;
234
- text-transform: uppercase;
235
- }
236
-
237
- .project .reasons {
238
- display: flex;
239
- flex-wrap: wrap;
240
- gap: 6px;
241
- min-height: 18px;
242
- }
243
-
244
- .project .counts {
245
- color: var(--muted);
246
- font-size: 11px;
247
- white-space: nowrap;
248
- text-align: right;
249
- }
250
-
251
- .project .counts b {
252
- color: var(--ink);
253
- font-weight: 400;
254
- }
255
-
256
- .project .next {
257
- grid-column: 2 / -1;
258
- color: var(--ink-soft);
259
- font-family: var(--serif);
260
- font-size: 15px;
261
- line-height: 1.35;
262
- }
263
-
264
- .project .next::before {
265
- content: "→ ";
266
- color: var(--muted);
267
- }
268
-
269
- .project.quiet .name {
270
- color: var(--muted);
271
- font-weight: 400;
272
- }
273
-
274
- /* ── signal ────────────────────────────────────────────── */
275
-
276
- .figures {
277
- display: grid;
278
- grid-template-columns: repeat(3, 1fr);
279
- gap: 8px 14px;
280
- margin-bottom: 14px;
281
- }
282
-
283
- .figure .value {
284
- font-family: var(--serif);
285
- font-size: 30px;
286
- line-height: 1;
287
- font-weight: 500;
288
- }
289
-
290
- .figure .value.bad {
291
- color: var(--bad);
292
- }
293
-
294
- .figure .value.good {
295
- color: var(--good);
296
- }
297
-
298
- .figure .label {
299
- color: var(--muted);
300
- font-size: 10px;
301
- letter-spacing: 0.1em;
302
- text-transform: uppercase;
303
- margin-top: 4px;
304
- }
305
-
306
- .spark {
307
- display: block;
308
- width: 100%;
309
- height: 72px;
310
- overflow: visible;
311
- }
312
-
313
- .spark .area {
314
- fill: url(#sparkfill);
315
- }
316
-
317
- .spark .line {
318
- fill: none;
319
- stroke: var(--amber);
320
- stroke-width: 1.4;
321
- stroke-linejoin: round;
322
- stroke-linecap: round;
323
- }
324
-
325
- .spark .low {
326
- fill: var(--bad);
327
- }
328
-
329
- .spark .last {
330
- fill: var(--amber);
331
- stroke: var(--panel);
332
- stroke-width: 2;
333
- }
334
-
335
- .spark .rule {
336
- stroke: var(--line-strong);
337
- stroke-dasharray: 2 4;
338
- }
339
-
340
- .spark-caption {
341
- display: flex;
342
- justify-content: space-between;
343
- color: var(--muted);
344
- font-size: 10px;
345
- letter-spacing: 0.06em;
346
- text-transform: uppercase;
347
- margin-top: 6px;
348
- }
349
-
350
- .due {
351
- display: flex;
352
- flex-direction: column;
353
- gap: 8px;
354
- margin-top: 16px;
355
- padding-top: 14px;
356
- border-top: 1px solid var(--line);
357
- }
358
-
359
- .due-row {
360
- display: grid;
361
- grid-template-columns: 74px minmax(0, 1fr);
362
- gap: 12px;
363
- align-items: baseline;
364
- font-size: 11px;
365
- }
366
-
367
- .due-row .detail {
368
- color: var(--ink-soft);
369
- }
370
-
371
- .due-row.due .detail {
372
- color: var(--ink);
373
- }
374
-
375
- .due-row.na .detail,
376
- .due-row.clear .detail {
377
- color: var(--muted);
378
- }
379
-
380
- /* ── handoffs ──────────────────────────────────────────── */
381
-
382
- .handoff {
383
- padding: 12px 0;
384
- border-top: 1px solid var(--line);
385
- }
386
-
387
- .handoff:first-child {
388
- border-top: 0;
389
- padding-top: 0;
390
- }
391
-
392
- .handoff .where {
393
- display: flex;
394
- justify-content: space-between;
395
- gap: 12px;
396
- color: var(--muted);
397
- font-size: 10px;
398
- letter-spacing: 0.08em;
399
- text-transform: uppercase;
400
- margin-bottom: 4px;
401
- }
402
-
403
- .handoff .where b {
404
- color: var(--amber);
405
- font-weight: 600;
406
- }
407
-
408
- .handoff .sentence {
409
- font-family: var(--serif);
410
- font-size: 17px;
411
- line-height: 1.35;
412
- color: var(--ink);
413
- }
414
-
415
- .handoff .title {
416
- color: var(--muted);
417
- font-size: 11px;
418
- margin-top: 4px;
419
- }
420
-
421
- /* ── agents ────────────────────────────────────────────── */
422
-
423
- table {
424
- width: 100%;
425
- border-collapse: collapse;
426
- font-size: 11px;
427
- }
428
-
429
- th {
430
- text-align: left;
431
- color: var(--muted);
432
- font-weight: 400;
433
- font-size: 10px;
434
- letter-spacing: 0.1em;
435
- text-transform: uppercase;
436
- padding: 0 10px 8px 0;
437
- border-bottom: 1px solid var(--line-strong);
438
- white-space: nowrap;
439
- }
440
-
441
- td {
442
- padding: 7px 10px 7px 0;
443
- border-bottom: 1px solid var(--line);
444
- vertical-align: top;
445
- }
446
-
447
- td.num,
448
- th.num {
449
- text-align: right;
450
- padding-right: 18px;
451
- font-variant-numeric: tabular-nums;
452
- }
453
-
454
- td.num:last-child,
455
- th.num:last-child {
456
- padding-right: 0;
457
- }
458
-
459
- .runtimes {
460
- display: flex;
461
- flex-wrap: wrap;
462
- gap: 4px;
463
- }
464
-
465
- .bar {
466
- position: relative;
467
- display: block;
468
- height: 4px;
469
- background: var(--line);
470
- margin-top: 5px;
471
- }
472
-
473
- .bar i {
474
- position: absolute;
475
- inset: 0 auto 0 0;
476
- background: var(--amber);
477
- }
478
-
479
- /* ── ledger ────────────────────────────────────────────── */
480
-
481
- .filters {
482
- display: flex;
483
- gap: 10px;
484
- align-items: center;
485
- flex-wrap: wrap;
486
- }
487
-
488
- .filters label {
489
- display: flex;
490
- gap: 6px;
491
- align-items: center;
492
- color: var(--muted);
493
- font-size: 10px;
494
- letter-spacing: 0.08em;
495
- text-transform: uppercase;
496
- }
497
-
498
- select,
499
- input[type="date"] {
500
- font: inherit;
501
- font-size: 11px;
502
- color: var(--ink);
503
- background: var(--panel-raised);
504
- border: 1px solid var(--line-strong);
505
- padding: 4px 8px;
506
- color-scheme: dark;
507
- }
508
-
509
- select:focus,
510
- input:focus {
511
- outline: 1px solid var(--amber);
512
- outline-offset: 0;
513
- }
514
-
515
- .strip {
516
- display: flex;
517
- gap: 26px;
518
- flex-wrap: wrap;
519
- padding: 10px 0 12px;
520
- color: var(--muted);
521
- font-size: 11px;
522
- }
523
-
524
- .strip span b {
525
- color: var(--ink);
526
- font-weight: 600;
527
- font-size: 13px;
528
- margin-right: 5px;
529
- }
530
-
531
- .strip span.refusals b {
532
- color: var(--bad);
533
- }
534
-
535
- .ledger td.target {
536
- max-width: 420px;
537
- overflow: hidden;
538
- text-overflow: ellipsis;
539
- white-space: nowrap;
540
- }
541
-
542
- .ledger td.target b {
543
- font-weight: 600;
544
- color: var(--ink-soft);
545
- }
546
-
547
- .ledger .outcome {
548
- font-size: 10px;
549
- letter-spacing: 0.06em;
550
- text-transform: uppercase;
551
- }
552
-
553
- .ledger .outcome.applied {
554
- color: var(--good);
555
- }
556
-
557
- .ledger .outcome.failed,
558
- .ledger .outcome.denied,
559
- .ledger .outcome.blocked {
560
- color: var(--bad);
561
- }
562
-
563
- .ledger .reason {
564
- display: block;
565
- color: var(--muted);
566
- font-size: 10px;
567
- white-space: normal;
568
- }
569
-
570
- .ledger td.when {
571
- color: var(--muted);
572
- white-space: nowrap;
573
- }
574
-
575
- .ledger .plus {
576
- color: var(--good);
577
- }
578
-
579
- .ledger .minus {
580
- color: var(--bad);
581
- }
582
-
583
- /* ── Today ── */
584
-
585
- .agenda {
586
- margin-bottom: 30px;
587
- }
588
-
589
- .agenda header,
590
- .matrix header {
591
- display: flex;
592
- align-items: baseline;
593
- justify-content: space-between;
594
- gap: 16px;
595
- margin-bottom: 14px;
596
- }
597
-
598
- .agenda > header h2,
599
- .matrix > header h2 {
600
- margin: 0;
601
- font-family: var(--serif);
602
- font-weight: 400;
603
- font-size: 22px;
604
- letter-spacing: -0.01em;
605
- }
606
-
607
- .agenda-age {
608
- color: var(--muted);
609
- font-size: 10px;
610
- letter-spacing: 0.06em;
611
- text-transform: uppercase;
612
- }
613
-
614
- .agenda-age.stale {
615
- color: var(--amber);
616
- }
617
-
618
- .agenda-empty {
619
- margin: 0;
620
- color: var(--muted);
621
- border-left: 2px solid var(--line-strong);
622
- padding-left: 14px;
623
- }
624
-
625
- .moves {
626
- list-style: none;
627
- margin: 0;
628
- padding: 0;
629
- display: grid;
630
- gap: 2px;
631
- }
632
-
633
- .moves li {
634
- display: grid;
635
- grid-template-columns: 34px minmax(0, 1fr);
636
- align-items: baseline;
637
- gap: 0 12px;
638
- padding: 14px 16px;
639
- background: var(--panel);
640
- border: 1px solid var(--line);
641
- }
642
-
643
- .moves li:first-child {
644
- border-left: 2px solid var(--amber);
645
- }
646
-
647
- .moves .rank {
648
- font-family: var(--serif);
649
- font-size: 24px;
650
- color: var(--muted);
651
- }
652
-
653
- .moves .move {
654
- font-family: var(--serif);
655
- font-size: 19px;
656
- line-height: 1.35;
657
- }
658
-
659
- .moves .because {
660
- grid-column: 2;
661
- color: var(--muted);
662
- font-size: 10px;
663
- letter-spacing: 0.05em;
664
- text-transform: uppercase;
665
- margin-top: 4px;
666
- }
667
-
668
- /* ── The grid ── */
669
-
670
- .matrix {
671
- margin-bottom: 30px;
672
- }
673
-
674
- .quadrants {
675
- display: grid;
676
- grid-template-columns: repeat(2, minmax(0, 1fr));
677
- gap: 2px;
678
- }
679
-
680
- .quadrant {
681
- background: var(--panel);
682
- border: 1px solid var(--line);
683
- padding: 14px 16px 16px;
684
- min-height: 130px;
685
- }
686
-
687
- .quadrant.q-now {
688
- border-top: 2px solid var(--amber);
689
- background: var(--panel-raised);
690
- }
691
-
692
- .quadrant.q-plan {
693
- border-top: 2px solid var(--good);
694
- }
695
-
696
- .quadrant.q-noise {
697
- border-top: 2px solid var(--wait);
698
- }
699
-
700
- .q-head {
701
- display: flex;
702
- align-items: baseline;
703
- justify-content: space-between;
704
- gap: 10px;
705
- padding-bottom: 10px;
706
- margin-bottom: 10px;
707
- border-bottom: 1px solid var(--line);
708
- }
709
-
710
- .q-head h3 {
711
- margin: 0;
712
- font-family: var(--serif);
713
- font-weight: 400;
714
- font-size: 16px;
715
- }
716
-
717
- .q-head span {
718
- color: var(--muted);
719
- font-size: 10px;
720
- letter-spacing: 0.05em;
721
- text-transform: uppercase;
722
- }
723
-
724
- .quadrant ul {
725
- list-style: none;
726
- margin: 0;
727
- padding: 0;
728
- display: grid;
729
- gap: 12px;
730
- }
731
-
732
- .m-head {
733
- display: flex;
734
- align-items: center;
735
- justify-content: space-between;
736
- gap: 10px;
737
- }
738
-
739
- .m-label {
740
- font-size: 13px;
741
- }
742
-
743
- .m-item.goal .m-label {
744
- font-family: var(--serif);
745
- font-size: 15px;
746
- color: var(--amber);
747
- }
748
-
749
- .m-detail {
750
- color: var(--ink-soft);
751
- margin-top: 3px;
752
- }
753
-
754
- .waiting {
755
- color: var(--wait);
756
- margin-top: 3px;
757
- }
758
-
759
- .m-reasons {
760
- display: flex;
761
- flex-wrap: wrap;
762
- gap: 6px;
763
- margin-top: 7px;
764
- }
765
-
766
- .m-reasons span {
767
- font-size: 10px;
768
- padding: 1px 7px;
769
- border: 1px solid var(--line-strong);
770
- color: var(--muted);
771
- }
772
-
773
- .m-reasons .why-urgent {
774
- border-color: var(--amber);
775
- color: var(--amber);
776
- }
777
-
778
- select.serves {
779
- background: transparent;
780
- color: var(--muted);
781
- border: 1px solid var(--line-strong);
782
- font-family: var(--mono);
783
- font-size: 10px;
784
- padding: 1px 4px;
785
- }
786
-
787
- select.serves.mine {
788
- color: var(--ink);
789
- border-color: var(--ink-soft);
790
- }
791
-
792
- /* ── The drawer ── */
793
-
794
- .drawer {
795
- border-top: 1px solid var(--line-strong);
796
- padding-top: 16px;
797
- }
798
-
799
- .drawer > summary {
800
- cursor: pointer;
801
- color: var(--muted);
802
- font-size: 10px;
803
- letter-spacing: 0.06em;
804
- text-transform: uppercase;
805
- list-style: none;
806
- }
807
-
808
- .drawer > summary::before {
809
- content: "▸ ";
810
- }
811
-
812
- .drawer[open] > summary::before {
813
- content: "▾ ";
814
- }
815
-
816
- .drawer > summary:hover {
817
- color: var(--ink);
818
- }
819
-
820
- .drawer .grid {
821
- margin-top: 18px;
822
- }
823
-
824
- .foot {
825
- margin-top: 28px;
826
- color: var(--muted);
827
- font-size: 10px;
828
- letter-spacing: 0.06em;
829
- text-transform: uppercase;
830
- display: flex;
831
- justify-content: space-between;
832
- }
833
-
834
- .error {
835
- border: 1px solid var(--bad);
836
- color: var(--bad);
837
- padding: 10px 14px;
838
- margin-bottom: 18px;
839
- }
840
-
841
- @media (max-width: 1100px) {
842
- .panel {
843
- grid-column: span 12;
844
- }
845
-
846
- .quadrants {
847
- grid-template-columns: minmax(0, 1fr);
848
- }
849
-
850
- .project {
851
- grid-template-columns: minmax(0, 1fr);
852
- }
853
-
854
- .project .counts {
855
- text-align: left;
856
- }
857
- }