@goodbones/browser 0.1.0-beta.1

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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/build/dts/index.d.ts +12 -0
  3. package/build/dts/index.d.ts.map +1 -0
  4. package/build/dts/main.d.ts +3 -0
  5. package/build/dts/main.d.ts.map +1 -0
  6. package/build/dts/model/atlas.d.ts +157 -0
  7. package/build/dts/model/atlas.d.ts.map +1 -0
  8. package/build/dts/model/campaigns.d.ts +141 -0
  9. package/build/dts/model/campaigns.d.ts.map +1 -0
  10. package/build/dts/server/collect.d.ts +16 -0
  11. package/build/dts/server/collect.d.ts.map +1 -0
  12. package/build/dts/server/compose.d.ts +13 -0
  13. package/build/dts/server/compose.d.ts.map +1 -0
  14. package/build/dts/server/export.d.ts +3 -0
  15. package/build/dts/server/export.d.ts.map +1 -0
  16. package/build/dts/server/handler.d.ts +6 -0
  17. package/build/dts/server/handler.d.ts.map +1 -0
  18. package/build/dts/server/serve.d.ts +15 -0
  19. package/build/dts/server/serve.d.ts.map +1 -0
  20. package/build/dts/server/site.d.ts +2 -0
  21. package/build/dts/server/site.d.ts.map +1 -0
  22. package/build/dts/server/source.d.ts +19 -0
  23. package/build/dts/server/source.d.ts.map +1 -0
  24. package/build/dts/server/vite-plugin.d.ts +8 -0
  25. package/build/dts/server/vite-plugin.d.ts.map +1 -0
  26. package/build/dts/server/watch.d.ts +10 -0
  27. package/build/dts/server/watch.d.ts.map +1 -0
  28. package/build/esm/index.js +14 -0
  29. package/build/esm/index.js.map +1 -0
  30. package/build/esm/main.js +134 -0
  31. package/build/esm/main.js.map +1 -0
  32. package/build/esm/model/atlas.js +431 -0
  33. package/build/esm/model/atlas.js.map +1 -0
  34. package/build/esm/model/campaigns.js +181 -0
  35. package/build/esm/model/campaigns.js.map +1 -0
  36. package/build/esm/server/collect.js +83 -0
  37. package/build/esm/server/collect.js.map +1 -0
  38. package/build/esm/server/compose.js +50 -0
  39. package/build/esm/server/compose.js.map +1 -0
  40. package/build/esm/server/export.js +19 -0
  41. package/build/esm/server/export.js.map +1 -0
  42. package/build/esm/server/handler.js +67 -0
  43. package/build/esm/server/handler.js.map +1 -0
  44. package/build/esm/server/serve.js +80 -0
  45. package/build/esm/server/serve.js.map +1 -0
  46. package/build/esm/server/site.js +6 -0
  47. package/build/esm/server/site.js.map +1 -0
  48. package/build/esm/server/source.js +67 -0
  49. package/build/esm/server/source.js.map +1 -0
  50. package/build/esm/server/vite-plugin.js +21 -0
  51. package/build/esm/server/vite-plugin.js.map +1 -0
  52. package/build/esm/server/watch.js +56 -0
  53. package/build/esm/server/watch.js.map +1 -0
  54. package/build/site/_astro/Browser.yxldcnQ3.js +3 -0
  55. package/build/site/_astro/client.Buyw3Q1S.js +9 -0
  56. package/build/site/_astro/index.DQrWs1cb.css +1 -0
  57. package/build/site/_astro/react.DJY1zw8Z.js +1 -0
  58. package/build/site/favicon.svg +1 -0
  59. package/build/site/index.html +8 -0
  60. package/package.json +78 -0
  61. package/src/app/components/Browser.tsx +153 -0
  62. package/src/app/components/architecture/ArchitectureBrowser.tsx +240 -0
  63. package/src/app/components/architecture/Detail.tsx +655 -0
  64. package/src/app/components/architecture/ManifestPane.tsx +178 -0
  65. package/src/app/components/architecture/Tree.tsx +205 -0
  66. package/src/app/components/architecture/rows.ts +181 -0
  67. package/src/app/components/architecture/selection.ts +6 -0
  68. package/src/app/components/campaigns/CampaignBrowser.tsx +146 -0
  69. package/src/app/components/campaigns/Detail.tsx +653 -0
  70. package/src/app/components/campaigns/Ladder.tsx +326 -0
  71. package/src/app/components/campaigns/pick.ts +7 -0
  72. package/src/app/components/lib/data.ts +132 -0
  73. package/src/app/pages/index.astro +34 -0
  74. package/src/app/public/favicon.svg +1 -0
  75. package/src/app/styles/theme.css +993 -0
  76. package/src/index.ts +37 -0
  77. package/src/main.ts +155 -0
  78. package/src/model/atlas.ts +751 -0
  79. package/src/model/campaigns.ts +376 -0
  80. package/src/server/collect.ts +132 -0
  81. package/src/server/compose.ts +79 -0
  82. package/src/server/export.ts +24 -0
  83. package/src/server/handler.ts +77 -0
  84. package/src/server/serve.ts +100 -0
  85. package/src/server/site.ts +6 -0
  86. package/src/server/source.ts +89 -0
  87. package/src/server/vite-plugin.ts +32 -0
  88. package/src/server/watch.ts +65 -0
@@ -0,0 +1,993 @@
1
+ /*
2
+ Bone & Ink, as the docs site wears it: warm paper and ink neutrals, one accent (marrow), and
3
+ colour spent on the thing under the pointer and nowhere else. Dark by default; `data-theme`
4
+ on the root switches, set before paint from the stored preference or the system's.
5
+ */
6
+
7
+ :root {
8
+ --bg: #141311;
9
+ --bg-2: #1f1d1a;
10
+ --bg-3: #2a2723;
11
+ --ink: #f6f2ea;
12
+ --ink-2: #d6d0c4;
13
+ --muted: #9a9488;
14
+ --faint: #5c574f;
15
+ --hair: #34302b;
16
+ --accent: #e0714a;
17
+ --accent-low: #3a1d12;
18
+ --accent-high: #f3b49a;
19
+ --red: #e5654f;
20
+ --red-low: #3b1a15;
21
+ --green: #7fbf7a;
22
+ --green-low: #17301a;
23
+ --orange: #e0a04a;
24
+ --orange-low: #3a2a12;
25
+ --blue: #7aa6d6;
26
+ --blue-low: #16232f;
27
+ --radius: 6px;
28
+ --font:
29
+ ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
30
+ --mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
31
+ color-scheme: dark;
32
+ }
33
+
34
+ :root[data-theme="light"] {
35
+ --bg: #faf8f4;
36
+ --bg-2: #f4f1ea;
37
+ --bg-3: #eeeae1;
38
+ --ink: #1a1815;
39
+ --ink-2: #34302a;
40
+ --muted: #6b665d;
41
+ --faint: #9c9588;
42
+ --hair: #ddd7cb;
43
+ --accent: #b4411e;
44
+ --accent-low: #f6e2d8;
45
+ --accent-high: #7a2a12;
46
+ --red: #b83a2a;
47
+ --red-low: #f8e0dc;
48
+ --green: #2f7d3a;
49
+ --green-low: #dff0e0;
50
+ --orange: #a86a12;
51
+ --orange-low: #f7e8cf;
52
+ --blue: #2f5f95;
53
+ --blue-low: #dde8f5;
54
+ color-scheme: light;
55
+ }
56
+
57
+ * {
58
+ box-sizing: border-box;
59
+ }
60
+
61
+ html,
62
+ body {
63
+ margin: 0;
64
+ height: 100%;
65
+ background: var(--bg);
66
+ color: var(--ink-2);
67
+ font-family: var(--font);
68
+ font-size: 14px;
69
+ line-height: 1.45;
70
+ }
71
+
72
+ button {
73
+ font: inherit;
74
+ color: inherit;
75
+ background: none;
76
+ border: none;
77
+ cursor: pointer;
78
+ }
79
+
80
+ .mono {
81
+ font-family: var(--mono);
82
+ font-size: 0.92em;
83
+ }
84
+
85
+ .muted {
86
+ color: var(--muted);
87
+ }
88
+ .small {
89
+ font-size: 12px;
90
+ }
91
+ .good {
92
+ color: var(--green);
93
+ }
94
+ .bad {
95
+ color: var(--red);
96
+ }
97
+ .warn {
98
+ color: var(--orange);
99
+ }
100
+
101
+ /* the page ------------------------------------------------------------- */
102
+
103
+ .page {
104
+ height: 100vh;
105
+ display: grid;
106
+ grid-template-rows: auto auto 1fr;
107
+ }
108
+
109
+ .bar {
110
+ display: flex;
111
+ align-items: center;
112
+ gap: 24px;
113
+ padding: 0 16px;
114
+ height: 46px;
115
+ border-bottom: 1px solid var(--hair);
116
+ background: var(--bg);
117
+ }
118
+
119
+ .brand {
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 8px;
123
+ font-weight: 700;
124
+ color: var(--ink);
125
+ }
126
+ .brand .mark {
127
+ width: 14px;
128
+ height: 14px;
129
+ border-radius: 3px;
130
+ background: var(--accent);
131
+ }
132
+ .brand .repo {
133
+ font-family: var(--mono);
134
+ font-weight: 400;
135
+ color: var(--muted);
136
+ }
137
+ .brand .repo::before {
138
+ content: "/ ";
139
+ }
140
+
141
+ .tabs {
142
+ display: flex;
143
+ gap: 4px;
144
+ }
145
+ .tab {
146
+ padding: 6px 12px;
147
+ border-radius: var(--radius);
148
+ color: var(--muted);
149
+ }
150
+ .tab:hover {
151
+ color: var(--ink);
152
+ background: var(--bg-2);
153
+ }
154
+ .tab.active {
155
+ color: var(--ink);
156
+ background: var(--bg-3);
157
+ }
158
+ .tab .count,
159
+ .tab .pct {
160
+ margin-left: 8px;
161
+ font-size: 11px;
162
+ color: var(--muted);
163
+ }
164
+
165
+ .status {
166
+ margin-left: auto;
167
+ display: flex;
168
+ align-items: center;
169
+ gap: 14px;
170
+ font-size: 12px;
171
+ color: var(--muted);
172
+ }
173
+ .live {
174
+ display: inline-flex;
175
+ align-items: center;
176
+ gap: 6px;
177
+ }
178
+ .live .dot {
179
+ width: 8px;
180
+ height: 8px;
181
+ border-radius: 50%;
182
+ background: var(--faint);
183
+ }
184
+ .live.on .dot {
185
+ background: var(--green);
186
+ box-shadow: 0 0 0 3px var(--green-low);
187
+ }
188
+ .theme {
189
+ font-size: 16px;
190
+ padding: 2px 6px;
191
+ border-radius: var(--radius);
192
+ }
193
+ .theme:hover {
194
+ background: var(--bg-2);
195
+ }
196
+
197
+ .banner {
198
+ padding: 8px 16px;
199
+ font-size: 12px;
200
+ background: var(--bg-2);
201
+ border-bottom: 1px solid var(--hair);
202
+ color: var(--muted);
203
+ }
204
+ .banner.error {
205
+ background: var(--red-low);
206
+ color: var(--ink);
207
+ }
208
+
209
+ .body {
210
+ min-height: 0;
211
+ overflow: hidden;
212
+ }
213
+
214
+ .placeholder {
215
+ padding: 48px;
216
+ color: var(--muted);
217
+ text-align: center;
218
+ }
219
+
220
+ /* panes ---------------------------------------------------------------- */
221
+
222
+ .arch,
223
+ .camp {
224
+ height: 100%;
225
+ display: grid;
226
+ min-height: 0;
227
+ }
228
+ .arch {
229
+ grid-template-columns: minmax(420px, 1.15fr) minmax(360px, 1fr) minmax(320px, 0.95fr);
230
+ }
231
+ .camp {
232
+ grid-template-columns: minmax(520px, 1.6fr) minmax(340px, 1fr);
233
+ }
234
+ @media (max-width: 1100px) {
235
+ .arch {
236
+ grid-template-columns: 1fr 1fr;
237
+ grid-template-rows: 1fr 1fr;
238
+ }
239
+ .arch .detail-pane {
240
+ grid-column: 1 / -1;
241
+ }
242
+ .camp {
243
+ grid-template-columns: 1fr;
244
+ grid-template-rows: 1fr 1fr;
245
+ }
246
+ }
247
+
248
+ .pane {
249
+ min-height: 0;
250
+ display: flex;
251
+ flex-direction: column;
252
+ border-right: 1px solid var(--hair);
253
+ overflow: hidden;
254
+ }
255
+ .pane:last-child {
256
+ border-right: none;
257
+ }
258
+ .pane-head {
259
+ display: flex;
260
+ align-items: center;
261
+ gap: 8px;
262
+ padding: 8px 12px;
263
+ border-bottom: 1px solid var(--hair);
264
+ min-height: 40px;
265
+ flex: none;
266
+ }
267
+ .eyebrow {
268
+ font-size: 10px;
269
+ letter-spacing: 0.08em;
270
+ text-transform: uppercase;
271
+ font-weight: 600;
272
+ color: var(--muted);
273
+ }
274
+ .hint {
275
+ margin-left: auto;
276
+ font-size: 11px;
277
+ color: var(--faint);
278
+ }
279
+ button.small {
280
+ font-size: 11px;
281
+ padding: 3px 8px;
282
+ border: 1px solid var(--hair);
283
+ border-radius: var(--radius);
284
+ color: var(--muted);
285
+ }
286
+ button.small:hover {
287
+ color: var(--ink);
288
+ border-color: var(--muted);
289
+ }
290
+ .pane-head button.small:last-child {
291
+ margin-left: auto;
292
+ }
293
+ .filter {
294
+ flex: 1;
295
+ min-width: 0;
296
+ font: inherit;
297
+ font-size: 12px;
298
+ padding: 4px 8px;
299
+ border: 1px solid var(--hair);
300
+ border-radius: var(--radius);
301
+ background: var(--bg-2);
302
+ color: var(--ink);
303
+ }
304
+ .filter:focus {
305
+ outline: none;
306
+ border-color: var(--accent);
307
+ }
308
+ .tabs-row {
309
+ gap: 2px;
310
+ overflow-x: auto;
311
+ }
312
+ .tabs-row .tab {
313
+ font-size: 12px;
314
+ padding: 4px 10px;
315
+ white-space: nowrap;
316
+ }
317
+
318
+ .legend {
319
+ flex: none;
320
+ display: flex;
321
+ flex-wrap: wrap;
322
+ gap: 4px 14px;
323
+ padding: 6px 12px;
324
+ border-top: 1px solid var(--hair);
325
+ font-size: 11px;
326
+ color: var(--muted);
327
+ }
328
+ .legend .key::before {
329
+ content: "";
330
+ display: inline-block;
331
+ width: 14px;
332
+ height: 3px;
333
+ border-radius: 2px;
334
+ margin-right: 6px;
335
+ vertical-align: middle;
336
+ background: var(--faint);
337
+ }
338
+ .legend .key.out::before {
339
+ background: var(--accent);
340
+ }
341
+ .legend .key.in::before {
342
+ background: var(--blue);
343
+ }
344
+ .legend .key.refused::before {
345
+ background: var(--red);
346
+ }
347
+ .legend .key.sibling::before {
348
+ background: var(--green);
349
+ }
350
+ .legend .key.governed::before {
351
+ background: var(--orange);
352
+ }
353
+ .legend .key.defined::before,
354
+ .legend .key.open::before,
355
+ .legend .key.sector::before,
356
+ .legend .key.legacy::before,
357
+ .legend .key.done::before,
358
+ .legend .key.nudged::before {
359
+ width: 12px;
360
+ height: 10px;
361
+ border-radius: 3px;
362
+ border: 1px solid var(--faint);
363
+ background: transparent;
364
+ }
365
+ .legend .key.defined::before {
366
+ background: var(--accent-low);
367
+ border-color: var(--accent);
368
+ }
369
+ .legend .key.open::before {
370
+ border-style: dashed;
371
+ border-color: var(--orange);
372
+ }
373
+ .legend .key.legacy::before {
374
+ background: var(--orange-low);
375
+ border-color: var(--orange);
376
+ border-style: dashed;
377
+ }
378
+ .legend .key.done::before {
379
+ background: var(--green-low);
380
+ border-color: var(--green);
381
+ }
382
+ .legend .key.nudged::before {
383
+ border-color: var(--blue);
384
+ box-shadow: 0 0 0 2px var(--blue-low);
385
+ }
386
+
387
+ /* the tree ------------------------------------------------------------- */
388
+
389
+ .tree {
390
+ flex: 1;
391
+ min-height: 0;
392
+ overflow: auto;
393
+ display: grid;
394
+ grid-template-columns: 1fr 150px;
395
+ align-items: start;
396
+ }
397
+ .rows {
398
+ list-style: none;
399
+ margin: 0;
400
+ padding: 0;
401
+ font-family: var(--mono);
402
+ font-size: 12.5px;
403
+ }
404
+ .row {
405
+ display: flex;
406
+ align-items: center;
407
+ gap: 4px;
408
+ padding-right: 8px;
409
+ white-space: nowrap;
410
+ color: var(--ink-2);
411
+ cursor: pointer;
412
+ border-left: 3px solid transparent;
413
+ }
414
+ .row:hover {
415
+ background: var(--bg-2);
416
+ }
417
+ .row.folder .name {
418
+ color: var(--ink);
419
+ font-weight: 600;
420
+ }
421
+ .row .name.outside {
422
+ color: var(--muted);
423
+ font-style: italic;
424
+ }
425
+ .row .chevron {
426
+ width: 16px;
427
+ flex: none;
428
+ color: var(--muted);
429
+ padding: 0;
430
+ text-align: center;
431
+ }
432
+ .row .chevron.spacer {
433
+ display: inline-block;
434
+ }
435
+ .row .meta {
436
+ margin-left: auto;
437
+ color: var(--faint);
438
+ font-size: 11px;
439
+ }
440
+ .row .node-mark {
441
+ color: var(--accent);
442
+ font-size: 11px;
443
+ margin-left: 4px;
444
+ }
445
+ .badge {
446
+ margin-left: 6px;
447
+ font-size: 10px;
448
+ padding: 0 5px;
449
+ border-radius: 8px;
450
+ background: var(--red-low);
451
+ color: var(--red);
452
+ }
453
+ .row.focus {
454
+ background: var(--bg-3);
455
+ border-left-color: var(--ink);
456
+ }
457
+ .row.selected {
458
+ border-left-color: var(--accent);
459
+ }
460
+ .row.dep {
461
+ background: var(--accent-low);
462
+ }
463
+ .row.dep .name {
464
+ color: var(--accent-high);
465
+ }
466
+ .row.importer {
467
+ background: var(--blue-low);
468
+ }
469
+ .row.importer .name {
470
+ color: var(--blue);
471
+ }
472
+ .row.within {
473
+ background: var(--bg-2);
474
+ }
475
+ .row.sibling {
476
+ background: var(--green-low);
477
+ }
478
+ .row.sibling .name {
479
+ color: var(--green);
480
+ }
481
+ .row.governed .name {
482
+ text-decoration: underline;
483
+ text-decoration-color: var(--orange);
484
+ text-underline-offset: 3px;
485
+ }
486
+ .row.governed {
487
+ box-shadow: inset 0 0 0 1px var(--orange-low);
488
+ }
489
+
490
+ .arcs {
491
+ display: block;
492
+ overflow: visible;
493
+ }
494
+ .arc {
495
+ fill: none;
496
+ stroke-width: 1.25;
497
+ stroke: var(--faint);
498
+ opacity: 0.45;
499
+ transition: opacity 120ms ease;
500
+ }
501
+ .arc.out {
502
+ stroke: var(--accent);
503
+ stroke-width: 2;
504
+ opacity: 1;
505
+ }
506
+ .arc.in {
507
+ stroke: var(--blue);
508
+ stroke-width: 2;
509
+ opacity: 1;
510
+ }
511
+ .arc.within {
512
+ stroke: var(--muted);
513
+ opacity: 0.8;
514
+ }
515
+ .arc.refused {
516
+ stroke-dasharray: 4 3;
517
+ }
518
+ .arc.refused.out,
519
+ .arc.refused.in,
520
+ .arc.refused.within {
521
+ stroke: var(--red);
522
+ }
523
+ .head {
524
+ fill: var(--faint);
525
+ }
526
+ .head.out {
527
+ fill: var(--accent);
528
+ }
529
+ .head.in {
530
+ fill: var(--blue);
531
+ }
532
+ .head.within {
533
+ fill: var(--muted);
534
+ }
535
+ .head.refused {
536
+ fill: var(--red);
537
+ }
538
+
539
+ /* the manifest --------------------------------------------------------- */
540
+
541
+ .manifest {
542
+ flex: 1;
543
+ min-height: 0;
544
+ display: flex;
545
+ flex-direction: column;
546
+ }
547
+ .source {
548
+ flex: 1;
549
+ min-height: 0;
550
+ overflow: auto;
551
+ list-style: none;
552
+ margin: 0;
553
+ padding: 8px 0;
554
+ font-family: var(--mono);
555
+ font-size: 12px;
556
+ line-height: 1.5;
557
+ }
558
+ .line {
559
+ display: flex;
560
+ align-items: baseline;
561
+ padding: 0 12px 0 0;
562
+ white-space: pre;
563
+ color: var(--ink-2);
564
+ border-left: 3px solid transparent;
565
+ }
566
+ .line .ln {
567
+ flex: none;
568
+ width: 40px;
569
+ text-align: right;
570
+ padding-right: 12px;
571
+ color: var(--faint);
572
+ user-select: none;
573
+ }
574
+ .line .code {
575
+ flex: 1;
576
+ min-width: 0;
577
+ overflow: hidden;
578
+ text-overflow: ellipsis;
579
+ }
580
+ .line .node-tag {
581
+ flex: none;
582
+ margin-left: 12px;
583
+ font-size: 10px;
584
+ color: var(--accent);
585
+ opacity: 0.7;
586
+ }
587
+ .line:hover {
588
+ background: var(--bg-2);
589
+ cursor: pointer;
590
+ }
591
+ .line.anchor .code {
592
+ color: var(--ink);
593
+ font-weight: 600;
594
+ }
595
+ .line.own {
596
+ background: var(--bg-2);
597
+ border-left-color: var(--orange);
598
+ }
599
+ .line.chain {
600
+ border-left-color: var(--accent);
601
+ }
602
+ .line.selected {
603
+ background: var(--accent-low);
604
+ }
605
+ .line.slack .code {
606
+ text-decoration: line-through;
607
+ text-decoration-color: var(--red);
608
+ color: var(--muted);
609
+ }
610
+
611
+ /* the detail ----------------------------------------------------------- */
612
+
613
+ .detail {
614
+ flex: 1;
615
+ min-height: 0;
616
+ overflow: auto;
617
+ padding: 0 14px 24px;
618
+ }
619
+ .detail .pane-head {
620
+ margin: 0 -14px;
621
+ }
622
+ .detail h2 {
623
+ font-size: 15px;
624
+ margin: 14px 0 4px;
625
+ color: var(--ink);
626
+ word-break: break-all;
627
+ }
628
+ .detail h2.path {
629
+ font-size: 13px;
630
+ }
631
+ .detail h3 {
632
+ font-size: 10px;
633
+ letter-spacing: 0.08em;
634
+ text-transform: uppercase;
635
+ color: var(--muted);
636
+ margin: 18px 0 6px;
637
+ font-weight: 600;
638
+ }
639
+ .detail p {
640
+ margin: 4px 0;
641
+ }
642
+ .message {
643
+ color: var(--ink-2);
644
+ border-left: 2px solid var(--accent);
645
+ padding-left: 10px;
646
+ font-size: 13px;
647
+ }
648
+ .crumbs {
649
+ font-size: 12px;
650
+ margin: 2px 0 8px;
651
+ }
652
+ .link {
653
+ color: var(--accent);
654
+ padding: 0;
655
+ text-align: left;
656
+ word-break: break-all;
657
+ }
658
+ .link:hover {
659
+ text-decoration: underline;
660
+ }
661
+ .facts {
662
+ display: grid;
663
+ grid-template-columns: max-content 1fr;
664
+ gap: 2px 14px;
665
+ margin: 8px 0;
666
+ font-size: 12.5px;
667
+ }
668
+ .facts dt {
669
+ color: var(--muted);
670
+ }
671
+ .facts dd {
672
+ margin: 0;
673
+ word-break: break-all;
674
+ }
675
+ .list {
676
+ list-style: none;
677
+ margin: 0;
678
+ padding: 0;
679
+ }
680
+ .list li {
681
+ padding: 3px 0;
682
+ border-bottom: 1px solid var(--hair);
683
+ word-break: break-all;
684
+ }
685
+ .list.compact li {
686
+ padding: 1px 0;
687
+ border-bottom: none;
688
+ }
689
+ .list li:last-child {
690
+ border-bottom: none;
691
+ }
692
+ .chips {
693
+ list-style: none;
694
+ margin: 4px 0;
695
+ padding: 0;
696
+ display: flex;
697
+ flex-wrap: wrap;
698
+ gap: 4px;
699
+ }
700
+ .chip {
701
+ font-family: var(--mono);
702
+ font-size: 11px;
703
+ padding: 1px 8px;
704
+ border-radius: 10px;
705
+ background: var(--bg-3);
706
+ color: var(--ink-2);
707
+ border: 1px solid transparent;
708
+ }
709
+ .chip.external {
710
+ background: var(--blue-low);
711
+ color: var(--blue);
712
+ }
713
+ .chip.allow {
714
+ background: var(--accent-low);
715
+ color: var(--accent-high);
716
+ }
717
+ .chip.deny {
718
+ background: var(--red-low);
719
+ color: var(--red);
720
+ }
721
+ .chip.rule {
722
+ background: transparent;
723
+ border-color: var(--hair);
724
+ color: var(--muted);
725
+ }
726
+ .chip.slack {
727
+ text-decoration: line-through;
728
+ opacity: 0.7;
729
+ border-color: var(--red);
730
+ }
731
+ .allowlist {
732
+ margin: 6px 0 10px;
733
+ }
734
+ .verdict {
735
+ display: inline-block;
736
+ width: 16px;
737
+ font-weight: 700;
738
+ }
739
+ .verdict.allowed {
740
+ color: var(--green);
741
+ }
742
+ .verdict.refused {
743
+ color: var(--red);
744
+ }
745
+ .verdict.ungoverned {
746
+ color: var(--muted);
747
+ }
748
+ .edge-row.refused {
749
+ color: var(--ink);
750
+ }
751
+ .family {
752
+ font-size: 10px;
753
+ letter-spacing: 0.06em;
754
+ text-transform: uppercase;
755
+ color: var(--accent);
756
+ font-weight: 600;
757
+ }
758
+ .violation.baselined {
759
+ color: var(--muted);
760
+ }
761
+ .flag {
762
+ display: inline-block;
763
+ margin-left: 8px;
764
+ font-size: 10px;
765
+ letter-spacing: 0.06em;
766
+ text-transform: uppercase;
767
+ padding: 1px 6px;
768
+ border-radius: 8px;
769
+ background: var(--bg-3);
770
+ vertical-align: middle;
771
+ font-weight: 600;
772
+ }
773
+ .flag.good {
774
+ background: var(--green-low);
775
+ color: var(--green);
776
+ }
777
+ .flag.bad {
778
+ background: var(--red-low);
779
+ color: var(--red);
780
+ }
781
+ .flag.warn {
782
+ background: var(--orange-low);
783
+ color: var(--orange);
784
+ }
785
+ .progress {
786
+ height: 6px;
787
+ border-radius: 3px;
788
+ background: var(--bg-3);
789
+ margin: 8px 0;
790
+ overflow: hidden;
791
+ }
792
+ .progress-bar {
793
+ height: 100%;
794
+ background: var(--accent);
795
+ }
796
+ details summary {
797
+ cursor: pointer;
798
+ margin: 6px 0;
799
+ }
800
+ .sector-block {
801
+ margin: 8px 0 12px;
802
+ }
803
+ .declared {
804
+ margin: 6px 0;
805
+ }
806
+
807
+ /* the ladder ----------------------------------------------------------- */
808
+
809
+ .camp-head {
810
+ padding: 10px 14px 6px;
811
+ border-bottom: 1px solid var(--hair);
812
+ flex: none;
813
+ }
814
+ .camp-head h2 {
815
+ margin: 0;
816
+ font-size: 16px;
817
+ color: var(--ink);
818
+ }
819
+ .ladder-scroll {
820
+ flex: 1;
821
+ min-height: 0;
822
+ overflow: auto;
823
+ padding: 8px;
824
+ }
825
+ .ladder {
826
+ display: block;
827
+ font-family: var(--font);
828
+ }
829
+ .ladder text {
830
+ fill: var(--ink-2);
831
+ font-size: 12px;
832
+ }
833
+ .ladder .eyebrow {
834
+ font-size: 9.5px;
835
+ letter-spacing: 0.08em;
836
+ font-weight: 600;
837
+ fill: var(--muted);
838
+ }
839
+ .ladder .phase-name {
840
+ font-size: 13px;
841
+ font-weight: 600;
842
+ fill: var(--ink);
843
+ }
844
+ .ladder .phase-count {
845
+ font-size: 12px;
846
+ font-weight: 600;
847
+ fill: var(--muted);
848
+ }
849
+ .ladder .phase {
850
+ fill: var(--bg-2);
851
+ stroke: var(--hair);
852
+ }
853
+ .ladder .phase-box.defined .phase {
854
+ fill: var(--accent-low);
855
+ stroke: var(--accent);
856
+ }
857
+ .ladder .phase-box.defined .eyebrow {
858
+ fill: var(--accent-high);
859
+ }
860
+ .ladder .phase-box.open .phase {
861
+ fill: var(--bg);
862
+ stroke: var(--orange);
863
+ stroke-width: 1.5;
864
+ stroke-dasharray: 5 4;
865
+ }
866
+ .ladder .phase-box.open .eyebrow,
867
+ .ladder .phase-box.open .phase-name {
868
+ fill: var(--orange);
869
+ }
870
+ .ladder .phase-box.standing .phase {
871
+ fill: var(--bg-2);
872
+ stroke: var(--faint);
873
+ stroke-dasharray: 2 3;
874
+ }
875
+ .ladder .phase.end {
876
+ fill: var(--green-low);
877
+ stroke: var(--green);
878
+ }
879
+ .ladder .end-text {
880
+ fill: var(--green);
881
+ }
882
+ .ladder .intent {
883
+ font-size: 11px;
884
+ font-style: italic;
885
+ fill: var(--muted);
886
+ }
887
+ .ladder .connector {
888
+ stroke: var(--faint);
889
+ stroke-width: 1.5;
890
+ }
891
+ .ladder .arrowhead {
892
+ fill: var(--faint);
893
+ }
894
+ .ladder .rule {
895
+ stroke: var(--hair);
896
+ stroke-dasharray: 2 4;
897
+ }
898
+ .ladder .label {
899
+ font-size: 12px;
900
+ font-weight: 600;
901
+ fill: var(--ink);
902
+ }
903
+ .ladder .lane {
904
+ fill: none;
905
+ stroke: var(--hair);
906
+ stroke-dasharray: 3 3;
907
+ }
908
+ .ladder .chip {
909
+ fill: var(--accent-low);
910
+ }
911
+ .ladder .chip-text {
912
+ font-size: 11px;
913
+ fill: var(--accent-high);
914
+ }
915
+ .ladder .chip-count {
916
+ font-size: 11px;
917
+ font-weight: 600;
918
+ fill: var(--accent-high);
919
+ }
920
+ .ladder .chip-box.complete .chip {
921
+ fill: var(--green-low);
922
+ }
923
+ .ladder .chip-box.complete .chip-text,
924
+ .ladder .chip-box.complete .chip-count {
925
+ fill: var(--green);
926
+ }
927
+ .ladder .chip-box.unledgered .chip {
928
+ stroke: var(--red);
929
+ stroke-dasharray: 3 2;
930
+ }
931
+ .ladder .sector {
932
+ fill: var(--bg);
933
+ stroke: var(--muted);
934
+ }
935
+ .ladder .sector-name {
936
+ font-size: 12px;
937
+ fill: var(--ink);
938
+ }
939
+ .ladder .sector-count {
940
+ font-size: 12px;
941
+ font-weight: 600;
942
+ fill: var(--ink-2);
943
+ }
944
+ .ladder .sector-box.legacy .sector {
945
+ fill: var(--orange-low);
946
+ stroke: var(--orange);
947
+ stroke-dasharray: 4 3;
948
+ }
949
+ .ladder .sector-box.legacy .sector-name,
950
+ .ladder .sector-box.legacy .sector-count {
951
+ fill: var(--orange);
952
+ }
953
+ .ladder .sector-box.done .sector {
954
+ fill: var(--green-low);
955
+ stroke: var(--green);
956
+ }
957
+ .ladder .sector-box.done .sector-name,
958
+ .ladder .sector-box.done .sector-count {
959
+ fill: var(--green);
960
+ }
961
+ .ladder .sector-box.stalled .sector-count {
962
+ fill: var(--red);
963
+ }
964
+ .ladder .sector-box.nudged .sector {
965
+ stroke: var(--blue);
966
+ stroke-width: 2;
967
+ }
968
+ .ladder .phase-box,
969
+ .ladder .chip-box,
970
+ .ladder .sector-box {
971
+ cursor: pointer;
972
+ transition: opacity 120ms ease;
973
+ }
974
+ .ladder.focused .phase-box:not(.lit),
975
+ .ladder.focused .chip-box:not(.lit),
976
+ .ladder.focused .sector-box:not(.lit) {
977
+ opacity: 0.35;
978
+ }
979
+ .ladder.focused .column.lit .phase-box,
980
+ .ladder.focused .phase-box.lit,
981
+ .ladder.focused .chip-box.lit,
982
+ .ladder.focused .sector-box.lit {
983
+ opacity: 1;
984
+ }
985
+ .ladder .phase-box.selected .phase,
986
+ .ladder .chip-box.selected .chip,
987
+ .ladder .sector-box.selected .sector {
988
+ stroke: var(--ink);
989
+ stroke-width: 2;
990
+ }
991
+ .ladder .column.lit .phase {
992
+ stroke-width: 2;
993
+ }