portable-agent-layer 0.69.0 → 0.71.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 (43) hide show
  1. package/README.md +5 -0
  2. package/assets/schema/pal-settings.schema.json +4 -0
  3. package/assets/skills/onboarding/SKILL.md +109 -0
  4. package/assets/skills/projects/SKILL.md +11 -2
  5. package/assets/templates/pal-settings.json +1 -0
  6. package/package.json +5 -1
  7. package/src/cli/index.ts +45 -10
  8. package/src/cli/ledger.ts +1 -17
  9. package/src/cli/personal-context.ts +67 -0
  10. package/src/cli/server.ts +201 -0
  11. package/src/cli/setup-identity.ts +13 -1
  12. package/src/hooks/handlers/agenda.ts +223 -0
  13. package/src/hooks/handlers/inject-retrieval.ts +6 -2
  14. package/src/hooks/lib/agenda-store.ts +41 -0
  15. package/src/hooks/lib/paths.ts +1 -0
  16. package/src/hooks/lib/projects.ts +16 -1
  17. package/src/hooks/lib/serves.ts +60 -0
  18. package/src/hooks/lib/stop.ts +14 -0
  19. package/src/hooks/lib/telos-goals.ts +144 -0
  20. package/src/hooks/lib/telos-topics.ts +68 -0
  21. package/src/hooks/lib/token-usage.ts +3 -1
  22. package/src/hooks/lib/wall-clock.ts +58 -0
  23. package/src/tools/agent/handoff-note.ts +38 -20
  24. package/src/tools/agent/project.ts +36 -4
  25. package/src/tools/control-room/data.ts +332 -0
  26. package/src/tools/control-room/matrix.ts +182 -0
  27. package/src/tools/control-room/server.ts +150 -0
  28. package/src/tools/control-room/ui/agenda.tsx +43 -0
  29. package/src/tools/control-room/ui/agents.tsx +67 -0
  30. package/src/tools/control-room/ui/app.css +857 -0
  31. package/src/tools/control-room/ui/app.tsx +74 -0
  32. package/src/tools/control-room/ui/board.tsx +82 -0
  33. package/src/tools/control-room/ui/format.ts +31 -0
  34. package/src/tools/control-room/ui/handoffs.tsx +37 -0
  35. package/src/tools/control-room/ui/index.html +19 -0
  36. package/src/tools/control-room/ui/ledger.tsx +136 -0
  37. package/src/tools/control-room/ui/matrix.tsx +117 -0
  38. package/src/tools/control-room/ui/panel.tsx +60 -0
  39. package/src/tools/control-room/ui/signal.tsx +161 -0
  40. package/src/tools/ledger/query.ts +18 -0
  41. package/src/tools/ledger/view.ts +130 -0
  42. package/src/cli/setup-telos.ts +0 -52
  43. package/src/hooks/lib/setup.ts +0 -60
@@ -0,0 +1,857 @@
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
+ }