-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimplementation-packet.html
More file actions
1167 lines (1048 loc) · 152 KB
/
Copy pathimplementation-packet.html
File metadata and controls
1167 lines (1048 loc) · 152 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="dossier/1.0">
<title>Implementation Packet: Search Filter</title>
<style>
:root{
color-scheme:light dark;
--ds-bg:#fbfbfc; --ds-bg-2:#f5f4f8; --ds-bg-3:#edebf1;
--ds-line:#e8e6ee; --ds-line-2:#dcd9e4; --ds-line-strong:#c7c2d3;
--ds-ink:#1a1822; --ds-ink-2:#56525f; --ds-ink-3:#8b8698;
--ds-accent:#c81e4a; --ds-accent-2:#a8183d; --ds-accent-tint:rgba(200,30,74,.08);
--ds-ok:#0f7a52; --ds-warn:#9a5b00; --ds-danger:#c0263b;
--ds-ok-tint:rgba(15,122,82,.1); --ds-warn-tint:rgba(154,91,0,.12); --ds-danger-tint:rgba(192,38,59,.1);
--ds-frame:1180px; --ds-rail:212px;
--ds-font:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
--ds-serif:Charter,"Bitstream Charter","Iowan Old Style","Palatino Linotype",Georgia,serif;
--ds-mono:"Geist Mono",ui-monospace,"SF Mono",SFMono-Regular,Menlo,monospace;
--ds-ease:cubic-bezier(.2,0,0,1);
}
[data-theme="dark"]{
--ds-bg:#0e0d13; --ds-bg-2:#16141d; --ds-bg-3:#1e1b27;
--ds-line:#2c2937; --ds-line-2:#3b3749; --ds-line-strong:#524c63;
--ds-ink:#eceaf1; --ds-ink-2:#a8a3b6; --ds-ink-3:#7b7689;
--ds-accent:#ff6b88; --ds-accent-2:#ff8aa0; --ds-accent-tint:rgba(255,107,136,.12);
--ds-ok:#34d399; --ds-warn:#fbbf24; --ds-danger:#fb7185;
--ds-ok-tint:rgba(52,211,153,.12); --ds-warn-tint:rgba(251,191,36,.12); --ds-danger-tint:rgba(251,113,133,.12);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;scroll-padding-top:66px}
body{margin:0;background:var(--ds-bg);color:var(--ds-ink);font-family:var(--ds-font);font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden;-webkit-tap-highlight-color:transparent}
::selection{background:var(--ds-accent-tint)}
a{color:var(--ds-accent);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:2px}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--ds-accent);outline-offset:2px;border-radius:5px}
.ds-tabbar,.ds-tablewrap,pre,.ds-diff-lines,.ds-diff-empty,.ds-math{scrollbar-width:none}
.ds-tabbar::-webkit-scrollbar,.ds-tablewrap::-webkit-scrollbar,pre::-webkit-scrollbar,.ds-diff-lines::-webkit-scrollbar,.ds-diff-empty::-webkit-scrollbar,.ds-math::-webkit-scrollbar{display:none}
h1,h2,h3,h4{font-weight:640;letter-spacing:-.014em;scroll-margin-top:66px}
h1{font-size:30px;line-height:1.18;letter-spacing:-.02em}
h2{font-size:22px;line-height:1.24;letter-spacing:-.015em;margin:0 0 5px}
h3{font-size:17.5px;line-height:1.3;letter-spacing:-.006em;margin:0 0 4px}
h4{font-size:15px;margin:0 0 3px}
p{margin:0 0 13px}
ul,ol{margin:0 0 13px;padding-left:21px}
li{margin:5px 0}
strong{font-weight:640}
code{font-family:var(--ds-mono);font-size:.86em;background:var(--ds-bg-2);border:1px solid var(--ds-line);border-radius:5px;padding:.5px 5px;color:var(--ds-ink)}
.ds-prose p:last-child,.ds-prose-list:last-child{margin-bottom:0}
.ds-prose-list{color:var(--ds-ink-2)}
.ds-prose-list strong{color:var(--ds-ink)}
.ds-muted{color:var(--ds-ink-2)}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important;scroll-behavior:auto!important}}
.ds-progress{position:fixed;inset:0 0 auto 0;height:2px;z-index:60}
.ds-progress-bar{height:100%;width:0;background:linear-gradient(90deg,var(--ds-accent),var(--ds-accent-2))}
.ds-skip{position:fixed;left:14px;top:10px;z-index:100;transform:translateY(-140%);background:var(--ds-ink);color:var(--ds-bg);border-radius:8px;padding:8px 12px;font-size:13px;font-weight:650;box-shadow:0 10px 30px rgba(20,16,40,.18)}
.ds-skip:focus{transform:none;text-decoration:none}
.ds-shell{width:min(var(--ds-frame),calc(100% - 48px));margin:0 auto;padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}
/* top bar */
.ds-topbar{position:sticky;top:0;z-index:40;display:flex;align-items:center;justify-content:space-between;gap:14px;height:54px;background:var(--ds-bg);border-bottom:1px solid var(--ds-line)}
.ds-brand{display:flex;align-items:center;gap:10px;min-width:0;flex:1}
.ds-mark{width:9px;height:9px;border-radius:50%;background:var(--ds-accent);box-shadow:0 0 0 4px var(--ds-accent-tint);flex:none}
.ds-crumbs{color:var(--ds-ink);font-size:14.5px;font-weight:580;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ds-tools{display:flex;align-items:center;gap:8px;flex:none}
.ds-btn{display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 11px;border:0;background:transparent;color:var(--ds-ink-2);font-size:13px;font-weight:560;border-radius:9px;cursor:pointer;transition:background .12s var(--ds-ease),color .12s var(--ds-ease),border-color .12s var(--ds-ease),transform .1s var(--ds-ease)}
.ds-btn:hover{background:var(--ds-bg-2);color:var(--ds-ink)}
.ds-btn .ds-i{flex:none;display:flex}
.ds-btn kbd{font-family:var(--ds-mono);font-size:11px;color:var(--ds-ink-3);border:1px solid var(--ds-line-2);border-radius:5px;padding:1px 5px}
.ds-search-btn{border:1px solid var(--ds-line-2);background:var(--ds-bg-2);min-width:172px;justify-content:flex-start;color:var(--ds-ink-3)}
.ds-search-btn .ds-search-label{margin-right:auto}
.ds-search-btn:hover{border-color:var(--ds-line-strong);background:var(--ds-bg-2);color:var(--ds-ink-2)}
.ds-btn[data-theme-toggle]{width:40px;height:40px;padding:0;justify-content:center;font-size:20px;line-height:1;color:var(--ds-ink-2)}
.ds-btn[data-theme-toggle]:hover{background:transparent;color:var(--ds-accent)}
.ds-menu{position:relative}
.ds-menu>summary{list-style:none;display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 13px;border:1px solid var(--ds-line-2);background:var(--ds-bg-2);color:var(--ds-ink);font-size:13px;font-weight:580;border-radius:9px;cursor:pointer}
.ds-menu>summary::-webkit-details-marker{display:none}
.ds-menu>summary::after{content:"▾";font-size:11px;color:var(--ds-ink-3)}
.ds-menu>summary:hover{border-color:var(--ds-line-strong);background:var(--ds-bg-3)}
.ds-menu-list{position:absolute;right:0;top:42px;min-width:206px;display:grid;padding:6px;background:var(--ds-bg);border:1px solid var(--ds-line-2);border-radius:12px;box-shadow:0 14px 38px rgba(20,16,40,.14);z-index:50}
.ds-menu-list button{justify-content:flex-start;width:100%;height:36px;padding:0 11px;color:var(--ds-ink);font-weight:520}
.ds-dirty-status{display:inline-flex;align-items:center;height:26px;padding:0 9px;border-radius:999px;background:var(--ds-accent-tint);color:var(--ds-accent);font-size:11.5px;font-weight:680;font-variant-numeric:tabular-nums;white-space:nowrap}
.ds-dirty-status[hidden]{display:none}
.ds-tool-modal{position:fixed;inset:0;z-index:85;display:flex;align-items:center;justify-content:center;padding:22px;background:rgba(15,14,20,.38)}
.ds-tool-modal[hidden]{display:none}
.ds-tool-card{width:min(760px,100%);max-height:88vh;display:grid;gap:14px;overflow:auto;background:var(--ds-bg);border:1px solid var(--ds-line-2);border-radius:14px;box-shadow:0 24px 80px rgba(0,0,0,.22);padding:16px}
.ds-tool-wide{width:min(1040px,100%)}
.ds-tool-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding-bottom:12px;border-bottom:1px solid var(--ds-line)}
.ds-tool-head strong{display:block;font-size:15px}
.ds-tool-head p,.ds-tool-note{margin:4px 0 0;color:var(--ds-ink-3);font-size:12.5px}
.ds-export-grid{display:flex;flex-wrap:wrap;gap:8px}
.ds-export-grid .ds-btn,.ds-tool-actions .ds-btn{justify-content:center;border:1px solid var(--ds-line-2);background:var(--ds-bg);color:var(--ds-ink-2)}
.ds-export-grid .ds-btn:not(.ds-btn-line),.ds-tool-actions .ds-btn:not(.ds-btn-line){background:var(--ds-bg-2);color:var(--ds-ink)}
.ds-export-grid .ds-btn:hover,.ds-tool-actions .ds-btn:hover{border-color:var(--ds-line-strong);background:var(--ds-bg-3);color:var(--ds-ink)}
.ds-export-preview-head{display:flex;align-items:center;justify-content:space-between;color:var(--ds-ink-2);font-size:12px}
.ds-export-preview{width:100%;min-height:220px;border:1px solid var(--ds-line-2);border-radius:10px;background:var(--ds-bg-2);color:var(--ds-ink);font:12px/1.55 var(--ds-mono);padding:12px;resize:vertical}
.ds-revision-result{min-height:96px}
.ds-file-btn{display:inline-flex;align-items:center;height:36px;padding:0 11px;border:1px solid var(--ds-line-2);border-radius:9px;background:var(--ds-bg);color:var(--ds-ink-2);font-size:13px;font-weight:560;cursor:pointer}
.ds-file-btn:focus-visible{outline:2px solid var(--ds-accent);outline-offset:2px;border-color:var(--ds-line-strong)}
.ds-file-btn input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.ds-blockedit-list{display:grid;gap:8px}
.ds-blockedit-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto auto;gap:8px;align-items:center;border:1px solid var(--ds-line-2);border-radius:10px;background:var(--ds-bg-2);padding:8px}
.ds-blockedit-row b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}
.ds-blockedit-row .ds-btn{height:30px}
.ds-tool-row{display:grid;grid-template-columns:160px minmax(0,1fr) auto;gap:8px;align-items:center}
.ds-tool-row input,.ds-tool-row select,.ds-field-grid input,.ds-field-grid select,.ds-field-grid textarea{width:100%;border:1px solid var(--ds-line-2);border-radius:8px;background:var(--ds-bg);color:var(--ds-ink);padding:8px 9px;font:13px var(--ds-font)}
.ds-field-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.ds-field-grid label{display:grid;gap:5px;color:var(--ds-ink-3);font-size:12px;font-weight:650}
.ds-field-grid .wide{grid-column:1/-1}
.ds-field-grid textarea{min-height:110px;resize:vertical;line-height:1.45}
.ds-tool-actions{display:flex;justify-content:flex-end}
.ds-lifecycle{display:inline-flex;align-items:center;gap:9px;margin:22px 0 0;padding:6px 13px;background:var(--ds-bg-2);border:1px solid var(--ds-line);border-radius:999px;color:var(--ds-ink-2);font-size:12.5px}
.ds-lifecycle b{display:inline-flex;align-items:center;gap:7px;color:var(--ds-ink);font-weight:600;text-transform:capitalize}
.ds-lifecycle b::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--ds-warn);box-shadow:0 0 0 3px var(--ds-warn-tint)}
.ds-lifecycle.stage-durable b::before{background:var(--ds-ok);box-shadow:0 0 0 3px var(--ds-ok-tint)}
.ds-lifecycle.stage-review b::before{background:var(--ds-accent);box-shadow:0 0 0 3px var(--ds-accent-tint)}
/* layout */
.ds-layout{display:grid;grid-template-columns:minmax(0,1fr) var(--ds-rail);gap:56px;padding:10px 0 96px;align-items:start}
.ds-layout.no-toc{grid-template-columns:1fr}
.ds-content{min-width:0;grid-column:1;counter-reset:sec}
.ds-toc{grid-column:2;position:sticky;top:74px;display:grid;gap:0;font-size:12.5px;align-self:start}
.ds-toc .ds-search{margin:0 0 14px}
.ds-toc .ds-search input{width:100%;height:34px;border:1px solid var(--ds-line-2);border-radius:9px;background:var(--ds-bg-2);padding:0 11px;font-size:13px;outline:0}
.ds-toc .ds-search input:focus{border-color:var(--ds-line-strong);background:var(--ds-bg)}
.ds-toc-head{color:var(--ds-ink-3);font-size:11px;font-weight:680;letter-spacing:.07em;text-transform:uppercase;margin-bottom:10px}
.ds-toc-link{display:block;padding:4px 0 4px 14px;color:var(--ds-ink-3);border-left:1.5px solid var(--ds-line);font-weight:520;transition:color .12s var(--ds-ease),border-color .12s var(--ds-ease)}
.ds-toc-link.lvl-2{padding-left:25px}
.ds-toc-link:hover{color:var(--ds-ink)}
.ds-toc-link.active{color:var(--ds-accent);border-left-color:var(--ds-accent)}
.ds-block{position:relative;min-width:0}
.ds-content>.ds-block+.ds-block{margin-top:34px}
.ds-content>.ds-block+.ds-section{margin-top:50px}
.ds-content>.ds-section{counter-increment:sec}
.ds-copy{position:absolute;top:8px;right:8px;z-index:2;display:inline-flex;align-items:center;justify-content:center;width:27px;height:27px;opacity:0;border:1px solid var(--ds-line);border-radius:8px;background:var(--ds-bg);color:var(--ds-ink-3);cursor:pointer;box-shadow:0 1px 2px rgba(20,16,40,.04);transition:opacity .12s var(--ds-ease),color .12s,background .12s,border-color .12s}
.ds-block:hover>.ds-copy{opacity:1}
.ds-copy:hover{color:var(--ds-ink);background:var(--ds-bg-2);border-color:var(--ds-line-strong)}
.ds-copy svg{display:block}
.ds-block[data-block="code"]>.ds-copy,.ds-block[data-block="diagram"]>.ds-copy{display:none}
/* in-place edit mode */
html.ds-editing .ds-btn[data-edit-toggle]{background:var(--ds-accent-tint);color:var(--ds-accent)}
.ds-editing [data-edit]{outline:1px dashed var(--ds-line-strong);outline-offset:3px;border-radius:4px;cursor:text}
.ds-editing [data-edit]:hover{outline-color:var(--ds-accent)}
.ds-editing [data-edit]:focus{outline:2px solid var(--ds-accent);outline-offset:3px}
/* theme studio */
.ds-swatch{width:34px;padding:0;justify-content:center}
.ds-swatch span{width:14px;height:14px;border-radius:50%;background:var(--ds-accent);box-shadow:0 0 0 1px var(--ds-line-2)}
.ds-studio{position:fixed;right:18px;top:62px;z-index:70;width:min(330px,calc(100vw - 28px));background:var(--ds-bg);border:1px solid var(--ds-line-2);border-radius:14px;box-shadow:0 18px 44px rgba(20,16,40,.18);padding:14px;display:grid;gap:10px}
.ds-studio[hidden]{display:none}
.ds-studio-head{display:flex;justify-content:space-between;align-items:center;font-size:13px}
.ds-studio-row{display:flex;justify-content:space-between;align-items:center;font-size:13px;font-weight:560;color:var(--ds-ink-2)}
.ds-studio-row input[type=color]{width:46px;height:28px;border:1px solid var(--ds-line-2);border-radius:7px;background:none;cursor:pointer;padding:2px}
.ds-studio-row input[type=text],.ds-studio-select,.ds-studio-json{border:1px solid var(--ds-line-2);border-radius:8px;background:var(--ds-bg-2);color:var(--ds-ink);font:12.5px var(--ds-mono);outline:0}
.ds-studio-row input[type=text]{width:92px;padding:6px 8px;text-align:right}
.ds-studio-presets{display:flex;flex-wrap:wrap;gap:8px}
.ds-studio-sw{width:26px;height:26px;border-radius:50%;border:1px solid var(--ds-line-2);cursor:pointer;padding:0;transition:transform .1s var(--ds-ease)}
.ds-studio-sw:hover{transform:scale(1.1)}
.ds-studio-select{width:100%;padding:7px 8px;font-family:inherit}
.ds-studio-json{width:100%;min-height:108px;resize:vertical;padding:9px;line-height:1.4}
.ds-studio-actions{display:grid;grid-template-columns:1fr 1fr;gap:7px}
.ds-studio-actions [data-studio-reset]{grid-column:1/-1}
.ds-studio-actions .ds-btn-line{justify-content:center}
mark{background:var(--ds-accent-tint);color:inherit;border-radius:3px;padding:0 2px}
/* hero, no background wash */
.ds-hero{padding:34px 0 4px}
.ds-eyebrow{display:inline-flex;align-items:center;margin:0 0 15px;padding:5px 12px;background:var(--ds-accent-tint);color:var(--ds-accent);font-size:12px;font-weight:600;letter-spacing:.02em;border-radius:999px}
.ds-hero h1{font-family:var(--ds-serif);font-weight:400;font-size:clamp(30px,4.2vw,44px);line-height:1.08;letter-spacing:-.022em;margin:0;max-width:20ch}
.ds-lede{max-width:62ch;margin:18px 0 0;color:var(--ds-ink-2);font-size:18px;line-height:1.5}
.ds-pillrow{display:flex;flex-wrap:wrap;gap:0;margin-top:20px;color:var(--ds-ink-3);font-size:12.5px;font-weight:520}
.ds-pill{position:relative;padding:0 14px}
.ds-pill:first-child{padding-left:0}
.ds-pill+.ds-pill::before{content:"";position:absolute;left:0;top:50%;width:3px;height:3px;border-radius:50%;background:var(--ds-line-strong);transform:translateY(-50%)}
.ds-meta{display:flex;flex-wrap:wrap;gap:30px;margin-top:24px;padding-top:20px;border-top:1px solid var(--ds-line)}
.ds-meta-item{display:grid;gap:3px}
.ds-meta-item .ds-label{color:var(--ds-ink-3);font-size:11px;font-weight:680;letter-spacing:.06em;text-transform:uppercase}
.ds-meta-item .ds-val{color:var(--ds-ink);font-size:14.5px;font-weight:560}
/* section */
.ds-section{padding-top:32px;border-top:1px solid var(--ds-line-2)}
.ds-section.unframed{border-top:0;padding-top:0}
.ds-section-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:18px}
.ds-section-titles{flex:1;min-width:0}
.ds-content>.ds-section .ds-section-titles h2::before{content:"§ " counter(sec,decimal-leading-zero);display:flex;align-items:center;width:fit-content;background:var(--ds-accent-tint);color:var(--ds-accent);font-family:var(--ds-mono);font-size:11.5px;font-weight:600;letter-spacing:.07em;padding:4px 10px;border-radius:999px;margin-bottom:12px}
.ds-section-titles .ds-muted{margin:7px 0 0;font-size:15px}
.ds-toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;border:0;background:transparent;color:var(--ds-ink-3);width:28px;height:28px;border-radius:8px;cursor:pointer;transition:background .12s,color .12s}
.ds-toggle:hover{background:var(--ds-bg-2);color:var(--ds-ink)}
.ds-toggle svg{transition:transform .2s var(--ds-ease)}
.ds-section[data-collapsed="1"] .ds-toggle svg{transform:rotate(-90deg)}
.ds-section-body{display:grid;gap:18px}
.ds-section-body>*{min-width:0}
.ds-section[data-collapsed="1"] .ds-section-body{display:none}
.ds-twocol{display:grid;grid-template-columns:1fr 1fr;gap:28px}
/* outlined cards (equal-size) */
.ds-cardgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px}
.ds-card{padding:17px 19px;border:1px solid var(--ds-line-2);border-radius:13px;background:var(--ds-bg);transition:border-color .14s var(--ds-ease),transform .14s var(--ds-ease)}
.ds-card h3{font-size:15.5px;margin:0 0 7px}
.ds-card p{margin:0;color:var(--ds-ink-2);font-size:14.5px}
.ds-statgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px}
.ds-stat{padding:16px 18px;border:1px solid var(--ds-line-2);border-radius:13px;background:var(--ds-bg)}
.ds-stat strong{display:block;font-size:30px;font-weight:600;letter-spacing:-.022em;line-height:1;font-variant-numeric:tabular-nums}
.ds-stat span{display:block;margin-top:8px;color:var(--ds-ink-2);font-size:13px}
.ds-stat-delta{display:block;margin-top:10px;color:var(--ds-ink-3);font-size:12px;font-weight:620;font-variant-numeric:tabular-nums}
.ds-stat-delta span{display:inline;margin:0;color:inherit;font-size:inherit}
.ds-stat-delta.tone-up,.ds-stat-delta.tone-positive,.ds-stat-delta.tone-good{color:var(--ds-ok)}
.ds-stat-delta.tone-down,.ds-stat-delta.tone-negative,.ds-stat-delta.tone-bad{color:var(--ds-danger)}
.ds-stat-delta.tone-warn,.ds-stat-delta.tone-warning{color:var(--ds-warn)}
/* flow */
.ds-flow{position:relative;display:grid;counter-reset:flow}
.ds-flow::before{content:"";position:absolute;left:15px;top:24px;bottom:24px;width:1px;background:var(--ds-line)}
.ds-flowstep{position:relative;display:grid;grid-template-columns:32px 1fr;gap:18px;padding:15px 0;border-top:1px solid var(--ds-line);align-items:start}
.ds-flowstep:first-child{border-top:0}
.ds-flowstep::before{position:relative;z-index:1;counter-increment:flow;content:counter(flow,decimal-leading-zero);display:inline-flex;align-items:center;justify-content:center;width:32px;height:24px;background:var(--ds-bg);font-family:var(--ds-mono);font-size:12.5px;color:var(--ds-accent);padding-top:3px}
.ds-flowstep-body strong{display:block;margin-bottom:3px;font-size:15.5px}
.ds-flowstep-body span{color:var(--ds-ink-2);font-size:15px}
/* timeline */
.ds-timeline{position:relative;display:grid}
.ds-timeline::before{content:"";position:absolute;left:131px;top:24px;bottom:24px;width:1px;background:var(--ds-line)}
.ds-phase{position:relative;display:grid;grid-template-columns:120px 1fr;gap:24px;padding:15px 0;border-top:1px solid var(--ds-line)}
.ds-phase:first-child{border-top:0}
.ds-phase::before{content:"";position:absolute;left:124px;top:24px;width:15px;height:15px;border-radius:50%;background:var(--ds-bg);border:1px solid var(--ds-line-strong)}
.ds-phase-id{display:flex;flex-direction:column;gap:7px;color:var(--ds-ink);font-weight:600;font-size:14.5px;align-items:flex-start}
.ds-date{color:var(--ds-ink-3);font-size:12px;font-weight:500}
.ds-phase>div:last-child{color:var(--ds-ink-2)}
/* tables (pan on narrow screens without exposing nested scroll chrome) */
.ds-tablewrap{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch}
table{width:100%;border-collapse:collapse;font-size:14.5px;margin:0}
th,td{text-align:left;padding:10px 16px 10px 0;border-bottom:1px solid var(--ds-line);vertical-align:top}
th{color:var(--ds-ink-3);font-size:11px;font-weight:680;letter-spacing:.05em;text-transform:uppercase;border-bottom-color:var(--ds-line-2);white-space:nowrap}
td{color:var(--ds-ink-2)}
td strong{color:var(--ds-ink)}
tr.ds-rec td{color:var(--ds-ink)}
/* chips */
.ds-status,.ds-lvl,.ds-akind,.ds-astatus,.ds-badge{display:inline-block;font-size:11px;font-weight:620;letter-spacing:.02em}
.ds-status{padding:2px 9px;border-radius:999px;background:var(--ds-bg-3);color:var(--ds-ink-2);text-transform:capitalize}
.s-done,.s-shipped{color:var(--ds-ok);background:var(--ds-ok-tint)} .s-in-progress,.s-doing{color:var(--ds-accent);background:var(--ds-accent-tint)} .s-blocked{color:var(--ds-danger);background:var(--ds-danger-tint)}
.ds-lvl{text-transform:capitalize}
.ds-lvl.l-high{color:var(--ds-danger)} .ds-lvl.l-medium{color:var(--ds-warn)} .ds-lvl.l-low{color:var(--ds-ok)}
/* callout */
.ds-callout{border-left:2px solid var(--ds-line-strong);padding:2px 0 2px 18px;color:var(--ds-ink-2)}
.ds-callout strong{color:var(--ds-ink)}
.ds-callout.tone-tip{border-left-color:var(--ds-accent)}
.ds-callout.tone-ok{border-left-color:var(--ds-ok)}
.ds-callout.tone-warn{border-left-color:var(--ds-warn)}
.ds-callout.tone-danger{border-left-color:var(--ds-danger)}
/* code */
.ds-code,.ds-diagram{border:1px solid var(--ds-line);border-radius:11px;overflow:hidden;background:var(--ds-bg-2)}
.ds-code-bar{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:8px 14px;font-family:var(--ds-mono);font-size:12px;color:var(--ds-ink-3);border-bottom:1px solid var(--ds-line)}
.ds-code-bar .ds-lang{color:var(--ds-accent);letter-spacing:.02em}
.ds-code-copy{border:1px solid var(--ds-line-2);background:var(--ds-bg);color:var(--ds-ink-3);font-family:var(--ds-font);font-size:11.5px;font-weight:560;border-radius:7px;padding:3px 10px;cursor:pointer;transition:color .12s,border-color .12s,transform .1s}
.ds-code-copy:hover{color:var(--ds-ink);border-color:var(--ds-line-strong)}
pre{margin:0;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;padding:15px;font-family:var(--ds-mono);font-size:13px;line-height:1.6;color:var(--ds-ink)}
pre code{background:transparent;border:0;padding:0;font-size:inherit}
/* Shiki dual-theme highlighting (build-time, no client JS) */
.ds-code .shiki{background:transparent!important;margin:0}
.ds-code .shiki,.ds-code .shiki span{color:var(--shiki-light)}
[data-theme="dark"] .ds-code .shiki,[data-theme="dark"] .ds-code .shiki span{color:var(--shiki-dark)}
/* Graphviz diagram, baked to inline SVG */
.ds-diagram-svg{display:flex;justify-content:center;padding:18px;background:#fff;border:0}
.ds-diagram-svg svg{max-width:100%;height:auto}
/* code editor */
.ds-codeedit{border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg);overflow:hidden;margin-top:12px}
.ds-codeedit.dirty{border-color:var(--ds-accent)}
.ds-codeedit-bar{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:9px 14px;border-bottom:1px solid var(--ds-line);background:var(--ds-bg-2);font-family:var(--ds-mono);font-size:12px;color:var(--ds-ink-3)}
.ds-codeedit-bar .ds-lang{color:var(--ds-accent)}
.ds-codeedit-bar .ds-lang,.ds-code-bar .ds-lang{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-codeedit-meta{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;font-family:var(--ds-font);min-width:0}
.ds-codeedit-meta span{border:1px solid var(--ds-line-2);border-radius:999px;padding:2px 8px;background:var(--ds-bg);font-size:11.5px;color:var(--ds-ink-2)}
.ds-codeedit-area{display:block;width:100%;min-height:220px;border:0;border-radius:0;background:var(--ds-bg);color:var(--ds-ink);font-family:var(--ds-mono);font-size:13px;line-height:1.55;padding:14px 16px;resize:vertical;tab-size:2;overflow:hidden}
.ds-codeedit-area:focus{outline:2px solid var(--ds-accent-tint);outline-offset:-2px}
.ds-codeedit-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end;padding:10px 12px;border-top:1px solid var(--ds-line);background:var(--ds-bg-2)}
.ds-codeedit-state{margin-right:auto;color:var(--ds-ink-3);font-size:12px;font-weight:680;letter-spacing:.04em;text-transform:uppercase}
.ds-codeedit.dirty .ds-codeedit-state{color:var(--ds-accent)}
/* process block family */
.ds-process-list{display:grid;gap:10px;margin-top:14px;min-width:0}
.ds-process-card{border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg);padding:14px 16px;min-width:0;overflow-wrap:anywhere}
.ds-process-card-head{display:flex;justify-content:space-between;gap:14px;align-items:flex-start}
.ds-process-card h4{margin:0 0 4px;font-size:15.5px}
.ds-gate{border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg);padding:14px 16px;margin-top:12px}
.ds-comments{margin:10px 0 0;padding-left:20px;color:var(--ds-ink-2)}
.ds-comments li+li{margin-top:8px}
.ds-comments p{margin:4px 0 0}
.ds-release-list{display:grid;gap:10px}
.ds-release-gate{display:grid;gap:8px}
.ds-release-gate textarea{min-height:58px}
.ds-finding .ds-chip{border-color:rgba(214,48,49,.26)}
.ds-vrun .ds-chip{border-color:rgba(18,161,104,.26)}
.ds-trust-sources{margin-top:14px}
.ds-trust-sources h4{margin:0 0 8px;color:var(--ds-ink)}
.ds-trust-sources table{font-size:13.5px}
.ds-trust-claims{margin-top:14px}
.ds-trust-claim{border-left:3px solid var(--ds-line-strong)}
.ds-trust-claim.status-verified,.ds-trust-claim.status-accepted{border-left-color:var(--ds-ok)}
.ds-trust-claim.status-disputed,.ds-trust-claim.status-rejected{border-left-color:var(--ds-danger)}
.ds-trust-claim.status-partial,.ds-trust-claim.status-unverified{border-left-color:var(--ds-warn)}
.ds-trust-refs{display:flex;flex-wrap:wrap;gap:7px;margin-top:10px;padding-top:10px;border-top:1px solid var(--ds-line)}
.ds-trust-link{text-decoration:none}
.ds-trust-missing{color:var(--ds-danger);border-color:rgba(214,48,49,.3)}
/* patch and diff blocks */
.ds-patchlist{display:grid;gap:12px;margin-top:14px}
.ds-patch{border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg);padding:15px 17px}
.ds-patch-head{display:flex;justify-content:space-between;gap:16px;align-items:flex-start}
.ds-patch h4{margin:0 0 4px;font-size:15.5px}
.ds-patch .ds-detailgrid{margin-top:12px}
.ds-patch-review,.ds-diff-review{display:grid;gap:9px;margin-top:12px}
.ds-patch-review label,.ds-diff-review label,.ds-hunk-head label{display:grid;gap:4px;color:var(--ds-ink-3);font-size:12px;font-weight:650}
.ds-patch-review select,.ds-diff-review select,.ds-hunk-head select{border:1px solid var(--ds-line-2);border-radius:7px;background:var(--ds-bg);color:var(--ds-ink);padding:5px 7px;font:12px var(--ds-font)}
.ds-patch-review textarea,.ds-diff-review textarea,.ds-diff-comment{width:100%;min-height:54px;border:1px solid var(--ds-line-2);border-radius:8px;background:var(--ds-bg);color:var(--ds-ink);padding:8px 9px;font:13px/1.45 var(--ds-font);resize:vertical}
.ds-diffview{margin-top:15px}
.ds-diffview.nested{border-top:1px solid var(--ds-line);padding-top:14px}
.ds-diff-summary{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0;color:var(--ds-ink-2);font-size:12.5px;font-weight:650;font-variant-numeric:tabular-nums}
.ds-diff-summary span{border:1px solid var(--ds-line-2);border-radius:999px;padding:3px 9px;background:var(--ds-bg)}
.ds-diff-summary .add{color:var(--ds-ok);border-color:rgba(18,161,104,.3)}
.ds-diff-summary .del{color:var(--ds-danger);border-color:rgba(214,48,49,.3)}
.ds-diff-files{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px}
.ds-diff-filelink{display:inline-flex;gap:8px;align-items:center;max-width:100%;border:1px solid var(--ds-line-2);border-radius:8px;padding:6px 9px;color:var(--ds-ink-2);font-size:12px;text-decoration:none}
.ds-diff-filelink span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:280px}
.ds-diff-filelink b{color:var(--ds-ink-3);font-weight:650;font-variant-numeric:tabular-nums}
.ds-diff-file{border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg);overflow:hidden;margin-top:10px}
.ds-diff-file summary{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:11px 14px;cursor:pointer;background:var(--ds-bg-2);font-weight:650}
.ds-diff-path{font-family:var(--ds-mono);font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-diff-stat{font-size:12px;color:var(--ds-ink-3);font-variant-numeric:tabular-nums}
.ds-diff-meta-lines{display:grid;gap:2px;padding:9px 14px;border-top:1px solid var(--ds-line);font-family:var(--ds-mono);font-size:12px;color:var(--ds-ink-3);background:var(--ds-bg)}
.ds-hunk{border-top:1px solid var(--ds-line)}
.ds-hunk-head{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:7px 14px;background:var(--ds-accent-tint);color:var(--ds-accent);font-family:var(--ds-mono);font-size:12px;font-weight:650}
.ds-hunk-head label{min-width:138px;color:var(--ds-ink-2);font-family:var(--ds-font)}
.ds-diff-comment{border-radius:0;border-left:0;border-right:0;border-top:0}
.ds-diff-lines{margin:0;overflow-x:auto;overflow-y:hidden;background:var(--ds-bg);font-family:var(--ds-mono);font-size:12.5px;line-height:1.5}
.ds-diff-line{display:grid;grid-template-columns:46px 46px 22px minmax(0,1fr);min-width:min(520px,100%)}
.ds-diff-line span{padding:0 7px}
.ds-diff-num{color:var(--ds-ink-3);text-align:right;border-right:1px solid var(--ds-line);user-select:none}
.ds-diff-mark{color:var(--ds-ink-3);text-align:center;user-select:none}
.ds-diff-code{white-space:pre}
.ds-diff-line.add{background:rgba(18,161,104,.1)}
.ds-diff-line.add .ds-diff-mark,.ds-diff-line.add .ds-diff-code{color:var(--ds-ok)}
.ds-diff-line.del{background:rgba(214,48,49,.09)}
.ds-diff-line.del .ds-diff-mark,.ds-diff-line.del .ds-diff-code{color:var(--ds-danger)}
.ds-diff-line.meta{color:var(--ds-ink-3);background:var(--ds-bg-2)}
.ds-diff-empty{padding:14px;overflow-x:auto;overflow-y:hidden;border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg);font-family:var(--ds-mono)}
/* figure */
.ds-figure{margin:0;display:grid;gap:9px}
.ds-figure img{display:block;max-width:100%;height:auto;border:1px solid var(--ds-line);border-radius:12px}
.ds-figure figcaption{color:var(--ds-ink-3);font-size:13px;text-align:center}
/* math (KaTeX MathML, native render) */
.ds-math{overflow-x:auto;overflow-y:hidden;text-align:center;font-size:1.05em;line-height:1.45;padding:6px 2px 8px}
.ds-math.inline{display:inline-block;text-align:left}
.ds-math math{font-size:1.15em}
/* footnotes */
.ds-fnref{font-size:.72em;line-height:0}
.ds-fnref a{padding:0 1px}
.ds-citeref{font-size:.72em;line-height:0}
.ds-citeref a{padding:0 2px;text-decoration:none}
.ds-footnotes{margin:0;padding-left:22px;color:var(--ds-ink-2);font-size:14.5px}
.ds-footnotes li{margin:6px 0}
.ds-footnotes li:target{background:var(--ds-accent-tint);border-radius:6px}
.ds-citations{margin:0;padding-left:24px;color:var(--ds-ink-2);font-size:14.5px}
.ds-citations li{margin:10px 0;padding-left:4px}
.ds-citations li:target{background:var(--ds-accent-tint);border-radius:6px}
.ds-cite-main{font-weight:750;color:var(--ds-ink)}
.ds-cite-meta{margin-top:2px;color:var(--ds-ink-3);font-size:13px}
.ds-citations blockquote{margin:8px 0 0;padding:6px 10px;border-left:2px solid var(--ds-line-strong);background:var(--ds-bg-2);border-radius:6px}
.ds-fnback{margin-left:4px;text-decoration:none}
/* charts (inline SVG) */
.ds-chart{border:1px solid var(--ds-line);border-radius:12px;background:var(--ds-bg);padding:14px 12px}
.ds-chart-svg{display:block;width:100%;height:auto}
.ds-chart-label,.ds-chart-tick,.ds-chart-value{font-family:var(--ds-font);font-size:11px}
.ds-chart-label,.ds-chart-tick{fill:var(--ds-ink-3)}
.ds-chart-value{fill:var(--ds-ink-2);font-weight:650;font-variant-numeric:tabular-nums}
.ds-chart-grid{stroke:var(--ds-line);stroke-width:1;stroke-dasharray:2 4}
.ds-chart-axis{stroke:var(--ds-line-2);stroke-width:1.2}
.ds-chart-zero{stroke:var(--ds-line-strong);stroke-width:1.2}
/* provenance receipt */
.ds-receipt{border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg-2);padding:16px 18px;font-size:14px}
.ds-receipt-head{font-weight:680;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ds-ink-3);margin-bottom:12px}
.ds-receipt .ds-detail{grid-template-columns:120px 1fr}
.ds-receipt-sources{margin-top:12px;padding-top:12px;border-top:1px solid var(--ds-line)}
.ds-receipt-sources ul{margin:6px 0 0;padding-left:20px;color:var(--ds-ink-2)}
/* plugin block fallback (Node string renderer injected into the React port) */
.ds-content>.ds-pluginblock{margin-top:34px}
.ds-content>.ds-pluginblock:first-child{margin-top:0}
/* tabs */
.ds-tabbar{display:flex;gap:22px;border-bottom:1px solid var(--ds-line);margin-bottom:20px;overflow-x:auto;overflow-y:hidden;padding-bottom:1px}
.ds-tab{border:0;background:transparent;padding:0 0 11px;color:var(--ds-ink-3);font-size:14px;font-weight:560;border-bottom:1.5px solid transparent;margin-bottom:-1px;cursor:pointer;white-space:nowrap}
.ds-tab.active{color:var(--ds-ink);border-bottom-color:var(--ds-accent)}
.ds-pane{display:none}
.ds-pane.active{display:grid;gap:20px}
/* faq */
details.ds-faq{border-bottom:1px solid var(--ds-line);padding:14px 0}
details.ds-faq summary{cursor:pointer;font-weight:560;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:16px}
details.ds-faq summary::-webkit-details-marker{display:none}
details.ds-faq summary::after{content:"+";color:var(--ds-ink-3);font-size:18px;flex:none}
details.ds-faq[open] summary::after{content:"-"}
details.ds-faq p{margin:12px 0 2px;color:var(--ds-ink-2)}
/* action items */
.ds-actions{list-style:none;padding:0;margin:0;display:grid}
.ds-action{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:13px 0;border-top:1px solid var(--ds-line)}
.ds-action:first-child{border-top:0}
.ds-action label{display:flex;align-items:center;gap:12px;cursor:pointer;flex:1;min-width:0}
.ds-action input{width:17px;height:17px;accent-color:var(--ds-accent);flex:none}
.ds-action.done .ds-action-title{text-decoration:line-through;color:var(--ds-ink-3)}
.ds-action-meta{display:flex;gap:12px;align-items:center;flex:none}
.ds-owner{font-size:12.5px;color:var(--ds-ink-3)}
/* assumptions */
.ds-assumptions{list-style:none;padding:0;margin:0;display:grid}
.ds-assumption{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:baseline;padding:12px 0;border-top:1px solid var(--ds-line)}
.ds-assumption:first-child{border-top:0}
.ds-akind{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--ds-ink-3)}
.ds-astatus{color:var(--ds-ink-3)}
.ds-assumption.a-verified .ds-astatus{color:var(--ds-ok)}
.ds-assumption.a-rejected .ds-astatus{color:var(--ds-danger)}
/* glossary */
.ds-glossary{display:grid;margin:0}
.ds-gterm{display:grid;grid-template-columns:200px 1fr;gap:24px;padding:13px 0;border-top:1px solid var(--ds-line)}
.ds-gterm:first-child{border-top:0}
.ds-gterm dt{font-weight:560}
.ds-gterm dd{margin:0;color:var(--ds-ink-2)}
.ds-term{border-bottom:1px dotted var(--ds-ink-3);cursor:help}
.ds-xlink{color:var(--ds-accent)}
/* review / triage list */
.ds-reviewboard .ds-review-bar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:16px 0 13px}
.ds-review-search{flex:1 1 170px;height:36px;border:1px solid var(--ds-line-2);border-radius:9px;background:var(--ds-bg-2);padding:0 12px;font-size:13.5px;outline:0}
.ds-review-search:focus{border-color:var(--ds-line-strong);background:var(--ds-bg)}
.ds-review-only{display:inline-flex;align-items:center;gap:8px;color:var(--ds-ink-2);font-size:13.5px;font-weight:520;cursor:pointer}
.ds-review-only input{width:16px;height:16px;accent-color:var(--ds-accent)}
.ds-review-count{color:var(--ds-ink-2);font-size:13.5px;font-weight:560;font-variant-numeric:tabular-nums}
.ds-btn-line{border:1px solid var(--ds-line-2);background:var(--ds-bg);color:var(--ds-ink-2);height:36px}
.ds-btn-line:hover{border-color:var(--ds-line-strong);background:var(--ds-bg-2);color:var(--ds-ink)}
.ds-rlist{display:grid;gap:9px}
.ds-ritem{border:1px solid var(--ds-line-2);border-radius:12px;background:var(--ds-bg);overflow:hidden;transition:border-color .14s var(--ds-ease)}
.ds-ritem:hover{border-color:var(--ds-line-strong)}
.ds-ritem.selected{border-color:var(--ds-accent)}
.ds-ritem.selected .ds-ritem-head{background:var(--ds-accent-tint)}
.ds-ritem-head{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:start;padding:15px 17px;cursor:pointer}
.ds-ritem-check{display:flex;align-items:center;padding-top:1px}
.ds-ritem-check input{width:18px;height:18px;accent-color:var(--ds-accent);cursor:pointer}
.ds-ritem-titles{min-width:0}
.ds-row-anchor{display:inline-flex;width:max-content;margin:0 0 5px;padding:2px 7px;border:1px solid var(--ds-line);border-radius:999px;background:var(--ds-bg-2);color:var(--ds-ink-3);font-family:var(--ds-mono);font-size:10.5px;font-weight:650;letter-spacing:.04em;text-decoration:none}
.ds-row-anchor:hover{border-color:var(--ds-line-strong);color:var(--ds-accent);text-decoration:none}
.ds-ritem:target{border-color:var(--ds-accent);box-shadow:0 0 0 3px var(--ds-accent-tint)}
.ds-ritem-titles h4{font-size:15.5px;margin:0 0 3px}
.ds-ritem-titles .ds-muted{margin:0;font-size:14px}
.ds-ritem-aside{display:flex;align-items:center;gap:11px;white-space:nowrap}
.ds-chev{color:var(--ds-ink-3);font-size:12px;transition:transform .22s var(--ds-ease)}
.ds-ritem.open .ds-chev{transform:rotate(180deg)}
.ds-chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:10px}
.ds-chip{padding:3px 10px;border:1px solid var(--ds-line-2);border-radius:999px;color:var(--ds-ink-2);font-size:11px;font-weight:560}
.ds-ritem-wrap{display:grid;grid-template-rows:0fr;transition:grid-template-rows .26s var(--ds-ease)}
.ds-ritem.open .ds-ritem-wrap{grid-template-rows:1fr}
.ds-ritem-body{overflow:hidden;min-height:0;padding:0 17px}
.ds-ref{padding-top:6px;border-top:1px solid var(--ds-line)}
.ds-ref>*{margin-top:15px}
.ds-notes{display:grid;gap:7px;padding:15px 0 17px}
.ds-notes span{color:var(--ds-ink-3);font-size:11.5px;font-weight:680;letter-spacing:.05em;text-transform:uppercase}
.ds-detailgrid{display:grid;margin:0}
.ds-detail{display:grid;grid-template-columns:120px 1fr;gap:16px;padding:8px 0;border-top:1px solid var(--ds-line)}
.ds-detail dt{color:var(--ds-ink-3);font-size:12px;text-transform:uppercase;letter-spacing:.04em}
.ds-detail dd{margin:0;color:var(--ds-ink-2);min-width:0;overflow-wrap:anywhere}
textarea{width:100%;min-height:80px;resize:vertical;border:1px solid var(--ds-line-2);border-radius:9px;background:var(--ds-bg);padding:10px 11px;font-size:14px;line-height:1.5;outline:0;overflow:hidden}
textarea:focus{border-color:var(--ds-line-strong)}
/* process boards */
.ds-pitem .ds-ritem-head{grid-template-columns:1fr auto}
.ds-pitem.verdict-approve{border-color:var(--ds-ok)}
.ds-pitem.verdict-approve .ds-ritem-head{background:rgba(18,161,104,.08)}
.ds-pitem.verdict-block{border-color:var(--ds-danger)}
.ds-pitem.verdict-block .ds-ritem-head{background:rgba(214,48,49,.08)}
.ds-pitem.verdict-revise,.ds-pitem.verdict-retry{border-color:var(--ds-warn)}
.ds-pitem.verdict-revise .ds-ritem-head,.ds-pitem.verdict-retry .ds-ritem-head{background:rgba(245,158,11,.09)}
.ds-process-verdict-wrap{display:flex;align-items:center;gap:7px;color:var(--ds-ink-3);font-size:11px;font-weight:680;letter-spacing:.04em;text-transform:uppercase;cursor:default}
.ds-process-verdict{height:32px;border:1px solid var(--ds-line-2);border-radius:8px;background:var(--ds-bg);color:var(--ds-ink);font:inherit;font-size:12px;font-weight:620;letter-spacing:0;text-transform:none;padding:0 26px 0 9px;cursor:pointer}
.ds-process-verdict:focus{outline:2px solid var(--ds-accent-tint);border-color:var(--ds-line-strong)}
.ds-footer{padding:24px 0 calc(24px + env(safe-area-inset-bottom));border-top:1px solid var(--ds-line);color:var(--ds-ink-3);font-size:12.5px}
/* palette + modals */
.ds-palette{position:fixed;inset:0;z-index:70;background:rgba(14,11,22,.42);display:flex;align-items:flex-start;justify-content:center;padding:13vh 16px 16px}
.ds-palette[hidden]{display:none}
.ds-palette-box{width:min(620px,100%);background:var(--ds-bg);border:1px solid var(--ds-line-2);border-radius:16px;box-shadow:0 30px 70px rgba(14,11,22,.3);overflow:hidden}
.ds-palette-input{width:100%;border:0;border-bottom:1px solid var(--ds-line);padding:18px 20px;font-size:16px;background:transparent;outline:0}
.ds-palette-list{max-height:52vh;overflow:auto;-webkit-overflow-scrolling:touch;padding:8px}
.ds-palette-item{display:flex;justify-content:space-between;gap:10px;padding:12px 14px;border-radius:10px;cursor:pointer;font-weight:520;font-size:14.5px}
.ds-palette-item.active{background:var(--ds-bg-2)}
.ds-palette-item small{color:var(--ds-ink-3)}
.ds-modal{position:fixed;inset:0;z-index:70;background:rgba(14,11,22,.42);display:flex;align-items:center;justify-content:center;padding:18px}
.ds-modal[hidden]{display:none}
.ds-modal-box{width:min(820px,100%);max-height:84vh;display:flex;flex-direction:column;background:var(--ds-bg);border:1px solid var(--ds-line-2);border-radius:16px;overflow:hidden;box-shadow:0 30px 70px rgba(14,11,22,.3)}
.ds-modal-head{display:flex;justify-content:space-between;align-items:center;padding:14px 16px;border-bottom:1px solid var(--ds-line)}
.ds-modal-box textarea{flex:1;min-height:54vh;border:0;border-radius:0;font-family:var(--ds-mono);font-size:13px}
.ds-shortcuts-box{width:min(520px,100%)}
.ds-shortcuts{display:grid;gap:8px;margin:0;padding:16px}
.ds-shortcuts div{display:grid;grid-template-columns:92px minmax(0,1fr);align-items:center;gap:12px;border:1px solid var(--ds-line);border-radius:10px;background:var(--ds-bg-2);padding:10px 12px}
.ds-shortcuts dt{display:flex;gap:4px;margin:0}
.ds-shortcuts dd{margin:0;color:var(--ds-ink-2);font-size:13.5px}
.ds-toast{position:fixed;right:18px;bottom:calc(18px + env(safe-area-inset-bottom));z-index:80;background:var(--ds-ink);color:var(--ds-bg);border-radius:11px;padding:11px 16px;font-size:13.5px;font-weight:560;box-shadow:0 16px 38px rgba(14,11,22,.32);opacity:0;transform:translateY(8px);transition:.18s var(--ds-ease);pointer-events:none}
.ds-toast.show{opacity:1;transform:none}
/* back to top */
.ds-totop{position:fixed;left:18px;bottom:calc(18px + env(safe-area-inset-bottom));z-index:50;display:flex;align-items:center;justify-content:center;width:42px;height:42px;border-radius:50%;border:1px solid var(--ds-line-2);background:var(--ds-bg);color:var(--ds-ink-2);font-size:17px;cursor:pointer;box-shadow:0 10px 28px rgba(20,16,40,.14);opacity:0;transform:translateY(10px) scale(.92);transition:.2s var(--ds-ease);pointer-events:none}
.ds-totop.show{opacity:1;transform:none;pointer-events:auto}
.ds-totop:hover{color:var(--ds-accent);border-color:var(--ds-line-strong)}
/* entrance reveal, JS-added, so no-JS markup stays visible */
.ds-reveal{opacity:0;transform:translateY(12px);transition:opacity .55s var(--ds-ease),transform .55s var(--ds-ease)}
.ds-reveal.in{opacity:1;transform:none}
/* hover lift + link underline + press feedback (pointer devices) */
@media (hover:hover){
.ds-card,.ds-stat{transition:border-color .14s var(--ds-ease),transform .14s var(--ds-ease)}
.ds-card:hover,.ds-stat:hover{transform:translateY(-2px);border-color:var(--ds-line-strong)}
.ds-content a:not(.ds-anchor){background:linear-gradient(currentColor 0 0) 0 100% / 0 1.5px no-repeat;transition:background-size .18s var(--ds-ease)}
.ds-content a:not(.ds-anchor):hover{background-size:100% 1.5px;text-decoration:none}
}
.ds-btn:active,.ds-menu>summary:active,.ds-toggle:active,.ds-totop:active,.ds-code-copy:active{transform:scale(.96)}
@media (prefers-contrast:more){
:root{--ds-line:#c5c0d0;--ds-line-2:#aaa3ba;--ds-line-strong:#7d738f;--ds-ink-3:#595164}
[data-theme="dark"]{--ds-line:#4f475f;--ds-line-2:#665d78;--ds-line-strong:#8c82a0;--ds-ink-3:#cac4d6}
}
/* heading anchors */
.ds-content h2,.ds-content h3{position:relative}
.ds-anchor{margin-left:9px;color:var(--ds-ink-3);font-weight:400;opacity:0;text-decoration:none;transition:opacity .12s var(--ds-ease),color .12s var(--ds-ease)}
.ds-content h2:hover .ds-anchor,.ds-content h3:hover .ds-anchor,.ds-anchor:focus-visible{opacity:1}
.ds-anchor:hover{color:var(--ds-accent)}
tbody tr{transition:color .12s var(--ds-ease)}
tbody tr:hover td{color:var(--ds-ink)}
.ds-action:hover .ds-action-title{color:var(--ds-ink)}
/* ============ responsive ============ */
@media (max-width:1040px){
.ds-shell{width:calc(100% - 40px)}
.ds-layout{grid-template-columns:1fr;gap:0;padding-bottom:80px}
.ds-toc{display:none}
}
@media (max-width:720px){
.ds-shell{width:calc(100% - 32px)}
.ds-topbar{height:52px;gap:10px}
.ds-tools{gap:6px;max-width:calc(100vw - 96px);overflow-x:auto;overscroll-behavior-x:contain;padding-bottom:2px;scrollbar-width:none}
.ds-tools::-webkit-scrollbar{display:none}
.ds-search-btn{min-width:0;width:40px;padding:0;justify-content:center}
.ds-search-btn .ds-search-label,.ds-search-btn kbd{display:none}
.ds-btn[data-theme-toggle]{width:38px;height:38px}
.ds-menu-list{right:0;min-width:220px}
.ds-tool-modal{align-items:flex-start;padding:12px}
.ds-tool-card{max-height:calc(100vh - 24px);border-radius:12px;padding:14px}
.ds-studio{right:12px;top:58px;max-height:calc(100vh - 76px);overflow:auto}
.ds-tool-head{align-items:flex-start;gap:10px}
.ds-export-grid{display:grid;grid-template-columns:1fr 1fr}
.ds-export-grid .ds-btn,.ds-file-btn{width:100%;justify-content:center}
.ds-tool-row,.ds-field-grid{grid-template-columns:1fr}
.ds-field-grid .wide{grid-column:auto}
.ds-hero{padding:24px 0 2px}
.ds-lede{font-size:16.5px;margin-top:15px}
.ds-meta{gap:20px}
.ds-content>.ds-block+.ds-block{margin-top:28px}
.ds-content>.ds-block+.ds-section{margin-top:40px}
.ds-section{padding-top:26px}
.ds-section-body{gap:16px}
h2{font-size:20px}
.ds-twocol{grid-template-columns:1fr;gap:18px}
.ds-phase,.ds-gterm,.ds-detail{grid-template-columns:1fr;gap:5px}
.ds-timeline::before,.ds-phase::before{display:none}
.ds-patch-head,.ds-process-card-head,.ds-hunk-head,.ds-diff-file summary{align-items:flex-start;flex-wrap:wrap}
.ds-ritem-head,.ds-pitem .ds-ritem-head{grid-template-columns:1fr}
.ds-ritem-aside{white-space:normal;flex-wrap:wrap}
.ds-codeedit-bar{align-items:flex-start;flex-direction:column}
.ds-codeedit-meta{justify-content:flex-start}
.ds-review-search{flex-basis:100%}
.ds-tablewrap{overflow:visible}
.ds-tablewrap table{min-width:0;table-layout:auto}
th,td{padding-right:10px;overflow-wrap:anywhere}
pre{white-space:pre-wrap;overflow-wrap:anywhere}
.ds-diff-line{grid-template-columns:28px 28px 16px minmax(0,1fr);min-width:0}
.ds-diff-line span{padding:0 4px}
.ds-diff-code{white-space:pre-wrap;overflow-wrap:anywhere}
.ds-copy{display:none}
}
@media (max-width:480px){
.ds-shell{width:calc(100% - 24px)}
.ds-crumbs{font-size:13.5px}
.ds-hero h1{font-size:27px}
.ds-lede{font-size:16px}
.ds-statgrid{grid-template-columns:1fr 1fr}
.ds-stat strong{font-size:26px}
.ds-ritem-head{padding:13px 14px;gap:11px}
.ds-ritem-body{padding:0 14px}
.ds-palette{padding-top:9vh}
.ds-shortcuts div{grid-template-columns:1fr;gap:6px}
.ds-export-grid{grid-template-columns:1fr}
.ds-blockedit-row{grid-template-columns:1fr 1fr 1fr}
.ds-blockedit-row b{grid-column:1/-1}
.ds-flowstep{grid-template-columns:26px 1fr;gap:13px}
.ds-flow::before{left:12px}
.ds-flowstep::before{width:26px}
}
/* print / PDF */
@media print{
@page{size:A4;margin:20mm 14mm 18mm}
:root{--ds-bg:#fff;--ds-bg-2:#fff;--ds-ink:#111;--ds-ink-2:#333;--ds-ink-3:#666;--ds-line:#ddd;--ds-line-2:#ccc}
*{-webkit-print-color-adjust:exact;print-color-adjust:exact}
html{font-size:11pt}
body{background:#fff!important;color:#111!important}
.ds-topbar,.ds-toc,.ds-totop,.ds-palette,.ds-modal,.ds-tool-modal,.ds-toast,.ds-studio,.ds-progress,.ds-skip,.ds-copy,.ds-review-bar,.ds-ritem-check,.ds-notes,.ds-toggle,.ds-code-copy,.ds-codeedit-actions,.ds-diff-files,.ds-process-verdict-wrap,.ds-release-gate textarea{display:none!important}
.ds-layout{display:block}
.ds-content{max-width:none}
.ds-shell{width:100%;background:#fff;box-shadow:none}
.ds-section[data-collapsed="1"] .ds-section-body{display:grid!important}
.ds-ritem-wrap{grid-template-rows:1fr!important}
.ds-section,.ds-block,.ds-hero,.ds-ritem,.ds-card,.ds-stat,.ds-chart,.ds-figure,.ds-codeedit,.ds-patch,.ds-diff-file,.ds-hunk,table,pre{break-inside:avoid-page;box-shadow:none}
.ds-section,.ds-block{border-color:#ddd}
.ds-block{margin-block:12pt}
.ds-hero{padding-top:0}
.ds-reveal{opacity:1!important;transform:none!important}
h1,h2,h3,h4{break-after:avoid;orphans:3;widows:3}
p,li,blockquote{orphans:3;widows:3}
pre,.ds-diff-line{white-space:pre-wrap;overflow:visible}
.ds-tablewrap{overflow:visible}
table{width:100%;page-break-inside:auto}
tr{break-inside:avoid-page}
img,svg,.ds-chart-svg{max-width:100%!important;height:auto}
a{color:inherit;text-decoration:none}
.ds-content a[href^="http"]::after{content:" (" attr(href) ")";font-size:.86em;color:#666;overflow-wrap:anywhere}
.ds-content .ds-citeref a::after,.ds-content .ds-fnref a::after{content:""}
}
</style>
</head>
<body>
<a class="ds-skip" href="#main">Skip to content</a>
<div class="ds-progress"><div class="ds-progress-bar"></div></div>
<div class="ds-shell">
<header class="ds-topbar">
<div class="ds-brand"><span class="ds-mark"></span><span class="ds-crumbs">Examples / Implementation packet</span></div>
<div class="ds-tools">
<button class="ds-btn ds-search-btn" type="button" data-palette-open><span class="ds-i"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><circle cx="11" cy="11" r="7"></circle><path d="m20 20-3.4-3.4"></path></svg></span><span class="ds-search-label">Search</span><kbd>⌘K</kbd></button>
<span class="ds-dirty-status" data-dirty-status hidden>state</span>
<button class="ds-btn" type="button" data-edit-toggle title="Edit text in place">Edit</button>
<button class="ds-btn" type="button" data-block-editor-open title="Edit block structure">Blocks</button>
<button class="ds-btn" type="button" data-evidence-open title="Attach evidence">Evidence</button>
<button class="ds-btn ds-swatch" type="button" data-studio-open title="Theme studio"><span></span></button>
<button class="ds-btn" type="button" data-theme-toggle aria-label="Toggle theme">◐</button>
<details class="ds-menu"><summary>Export</summary><div class="ds-menu-list">
<button class="ds-btn" type="button" data-action="open-export-center">Open Export Center</button>
<button class="ds-btn" type="button" data-action="copy-md">Copy Markdown</button>
<button class="ds-btn" type="button" data-action="copy-digest">Copy for AI (digest)</button>
<button class="ds-btn" type="button" data-action="download-md">Download Markdown</button>
<button class="ds-btn" type="button" data-action="download-json">Download source JSON</button>
<button class="ds-btn" type="button" data-action="download-state-json">Download state packet</button>
<button class="ds-btn" type="button" data-action="download-merged-json">Download merged JSON</button>
<button class="ds-btn" type="button" data-action="download-handoff-json">Download agent handoff</button>
<button class="ds-btn" type="button" data-action="copy-prompt">Copy AI prompt</button>
<button class="ds-btn" type="button" data-action="print-pdf">Print / save PDF</button>
<button class="ds-btn" type="button" data-action="view-source">View source</button>
</div></details>
</div>
</header>
<div class="ds-lifecycle stage-review"><b>review</b> A code-editing packet with proposed work, patch review, diff review, and verification.</div>
<div class="ds-layout">
<main class="ds-content" id="main" tabindex="-1">
<section class="ds-hero ds-block" data-block="hero" data-id="a-code-editing-handoff-that-agents-can-actually-consume-0"><p class="ds-eyebrow">Implementation packet</p><h1 id="a-code-editing-handoff-that-agents-can-actually-consume-0" data-edit="a-code-editing-handoff-that-agents-can-actually-consume-0:title">A code editing handoff that agents can actually consume</h1><p class="ds-lede" data-edit="a-code-editing-handoff-that-agents-can-actually-consume-0:lede">This example shows the process Dossier shape for coding work: work items, editable snippets, patch proposals, diff review, verification receipts, trust claims, and closeout.</p><div class="ds-pillrow"><span class="ds-pill">Work items</span><span class="ds-pill">Patch review</span><span class="ds-pill">Diff review</span><span class="ds-pill">MCP packets</span></div><div class="ds-meta"><div class="ds-meta-item"><span class="ds-label">Packet schemas</span><span class="ds-val">edits + process + trust</span></div><div class="ds-meta-item"><span class="ds-label">Human input</span><span class="ds-val">verdicts + notes</span></div><div class="ds-meta-item"><span class="ds-label">Agent readback</span><span class="ds-val">MCP tools</span></div></div></section>
<section class="ds-block ds-reviewboard ds-processboard" data-block="process-board" data-id="work-plan-1"><h2 id="work-plan-1">Work plan</h2><div class="ds-review-bar"><input class="ds-review-search" type="search" placeholder="Filter…" data-process-search aria-label="Filter process items"><label class="ds-review-only"><input type="checkbox" data-process-only> With verdict only</label><button class="ds-btn ds-btn-line" type="button" data-process-expand>Expand all</button><span class="ds-review-count" data-process-count>0 verdicts</span><button class="ds-btn ds-btn-line" type="button" data-export-process>Export process packet</button><button class="ds-btn ds-btn-line" type="button" data-import-process>Import</button></div><div class="ds-rlist"><article id="work-plan-1-filter-state" class="ds-ritem ds-pitem verdict-undecided" data-process-item="filter-state" data-text="persist selected filter save the active search filter in the url query so refresh and share links preserve state. frontend agent src/search/filter-state.ts src/search/searchpanel.tsx npm test npx tsc --noemit"><div class="ds-ritem-head" data-ptoggle><div class="ds-ritem-titles"><a class="ds-row-anchor" href="#work-plan-1-filter-state">ITEM-001</a><h4>Persist selected filter</h4><p class="ds-muted">Save the active search filter in the URL query so refresh and share links preserve state.</p><div class="ds-chips"><span class="ds-chip">Frontend</span><span class="ds-chip">Priority · P1</span><span class="ds-chip">Owner · agent</span><span class="ds-chip">Impact · Medium</span><span class="ds-chip">Effort · Small</span></div></div><div class="ds-ritem-aside"><span class="ds-status s-proposed">proposed</span><label class="ds-process-verdict-wrap" data-stop><span>Verdict</span><select class="ds-process-verdict" data-process-verdict="filter-state"><option value="undecided" selected>undecided</option><option value="approve">approve</option><option value="revise">revise</option><option value="skip">skip</option><option value="defer">defer</option><option value="split">split</option><option value="retry">retry</option><option value="block">block</option></select></label><span class="ds-chev" aria-hidden="true">▾</span></div></div><div class="ds-ritem-wrap"><div class="ds-ritem-body"><div class="ds-ref"><dl class="ds-detailgrid"><div class="ds-detail"><dt>Files</dt><dd>src/search/filter-state.ts, src/search/SearchPanel.tsx</dd></div><div class="ds-detail"><dt>Verification</dt><dd>npm test, npx tsc --noEmit</dd></div></dl></div><label class="ds-notes"><span>Notes</span><textarea data-process-notes="filter-state" placeholder="Verdict notes, constraints, follow-up instructions"></textarea></label></div></div></article><article id="work-plan-1-empty-state" class="ds-ritem ds-pitem verdict-undecided" data-process-item="empty-state" data-text="improve empty results state show the active filter and a clear reset action when no results match. ux agent src/search/searchresults.tsx"><div class="ds-ritem-head" data-ptoggle><div class="ds-ritem-titles"><a class="ds-row-anchor" href="#work-plan-1-empty-state">ITEM-002</a><h4>Improve empty results state</h4><p class="ds-muted">Show the active filter and a clear reset action when no results match.</p><div class="ds-chips"><span class="ds-chip">UX</span><span class="ds-chip">Priority · P2</span><span class="ds-chip">Owner · agent</span><span class="ds-chip">Impact · Medium</span><span class="ds-chip">Effort · Small</span></div></div><div class="ds-ritem-aside"><span class="ds-status s-proposed">proposed</span><label class="ds-process-verdict-wrap" data-stop><span>Verdict</span><select class="ds-process-verdict" data-process-verdict="empty-state"><option value="undecided" selected>undecided</option><option value="approve">approve</option><option value="revise">revise</option><option value="skip">skip</option><option value="defer">defer</option><option value="split">split</option><option value="retry">retry</option><option value="block">block</option></select></label><span class="ds-chev" aria-hidden="true">▾</span></div></div><div class="ds-ritem-wrap"><div class="ds-ritem-body"><div class="ds-ref"><dl class="ds-detailgrid"><div class="ds-detail"><dt>Files</dt><dd>src/search/SearchResults.tsx</dd></div></dl></div><label class="ds-notes"><span>Notes</span><textarea data-process-notes="empty-state" placeholder="Verdict notes, constraints, follow-up instructions"></textarea></label></div></div></article></div></section>
<section class="ds-block" data-block="code-editor" data-id="editable-helper-proposal-2"><button class="ds-copy" type="button" data-copy aria-label="Copy block" title="Copy"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button><h3 id="editable-helper-proposal-2">Editable helper proposal</h3><p class="ds-muted"><code>dossier serve</code> enhances this textarea with CodeMirror 6 while Dossier still exports plain <code>dossier.edits/v1</code>.</p><div class="ds-codeedit" data-editor-shell="editable-helper-proposal-2"><div class="ds-codeedit-bar"><span class="ds-lang">filter-state.ts</span><div class="ds-codeedit-meta"><span>ts</span><span>src/search/filter-state.ts</span><span>Work · filter-state</span></div></div><textarea class="ds-codeedit-area" data-code-editor="editable-helper-proposal-2" data-editor-lang="ts" data-editor-filename="filter-state.ts" data-editor-target="src/search/filter-state.ts" data-editor-title="Editable helper proposal" spellcheck="false" rows="13">export function readFilter(search: string): string {
const params = new URLSearchParams(search);
return params.get("filter") || "all";
}
export function writeFilter(search: string, filter: string): string {
const params = new URLSearchParams(search);
if (filter === "all") params.delete("filter");
else params.set("filter", filter);
return params.toString();
}
</textarea><div class="ds-codeedit-actions"><span class="ds-codeedit-state" data-editor-state="editable-helper-proposal-2">clean</span><button class="ds-btn ds-btn-line" type="button" data-editor-reset="editable-helper-proposal-2">Reset</button><button class="ds-btn ds-btn-line" type="button" data-export-editors>Export edits packet</button><button class="ds-btn ds-btn-line" type="button" data-import-editors>Import</button></div></div></section>
<section class="ds-block" data-block="patch-set" data-id="proposed-patches-3"><button class="ds-copy" type="button" data-copy aria-label="Copy block" title="Copy"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button><h3 id="proposed-patches-3">Proposed patches</h3><p class="ds-muted">A patch set groups intent, touched files, risk, verification, and optional unified diffs.</p><div class="ds-patchlist"><article class="ds-patch" data-patch="persist-filter"><div class="ds-patch-head"><div><h4>Persist filter in query string</h4><p class="ds-muted">Add a small helper and wire the search panel to update the URL.</p></div><div class="ds-chips"><span class="ds-chip">add</span><span class="ds-chip">proposed</span><span class="ds-chip risk-low">Risk · low</span></div></div><div class="ds-patch-review"><label><span>Patch verdict</span><select data-patch-verdict="persist-filter"><option value="undecided">undecided</option><option value="approve">approve</option><option value="revise">revise</option><option value="skip">skip</option><option value="defer">defer</option><option value="block">block</option></select></label><label><span>Review notes</span><textarea data-patch-notes="persist-filter" placeholder="Apply, revise, skip, or follow-up notes"></textarea></label></div><dl class="ds-detailgrid"><div class="ds-detail"><dt>Files</dt><dd>src/search/filter-state.ts, src/search/SearchPanel.tsx</dd></div><div class="ds-detail"><dt>Work items</dt><dd>filter-state</dd></div><div class="ds-detail"><dt>Verification</dt><dd>npm test, npx tsc --noEmit</dd></div></dl><section class="ds-diffview nested" data-block="diff-view" data-id="persist-filter-diff"><h4>Diff</h4><div class="ds-diff-summary"><span>1 file</span><span class="add">+4</span><span class="del">-0</span></div><nav class="ds-diff-files"><a href="#persist-filter-diff-src-search-filter-state-ts" class="ds-diff-filelink"><span>src/search/filter-state.ts</span><b>+4 -0</b></a></nav><div class="ds-diff-body"><details class="ds-diff-file" id="persist-filter-diff-src-search-filter-state-ts" data-diff-file="persist-filter-diff:src/search/filter-state.ts" open><summary><span class="ds-diff-path">src/search/filter-state.ts</span><span class="ds-diff-stat">+4 -0</span></summary><div class="ds-diff-review"><label><span>File verdict</span><select data-diff-file-verdict="persist-filter-diff:src/search/filter-state.ts"><option value="undecided" selected>undecided</option><option value="approve">approve</option><option value="revise">revise</option><option value="skip">skip</option><option value="defer">defer</option><option value="block">block</option></select></label><label><span>File comment</span><textarea data-diff-file-comment="persist-filter-diff:src/search/filter-state.ts" placeholder="File-level review note"></textarea></label></div><div class="ds-diff-meta-lines"><code>diff --git a/src/search/filter-state.ts b/src/search/filter-state.ts</code><code>new file mode 100644</code><code>--- /dev/null</code><code>+++ b/src/search/filter-state.ts</code></div><div class="ds-hunk" data-diff-hunk="persist-filter-diff:src/search/filter-state.ts:h1"><div class="ds-hunk-head"><span>@@ -0,0 +1,4 @@</span><label><span>Hunk verdict</span><select data-diff-hunk-verdict="persist-filter-diff:src/search/filter-state.ts:h1"><option value="undecided" selected>undecided</option><option value="approve">approve</option><option value="revise">revise</option><option value="skip">skip</option><option value="defer">defer</option><option value="block">block</option></select></label></div><textarea class="ds-diff-comment" data-diff-hunk-comment="persist-filter-diff:src/search/filter-state.ts:h1" placeholder="Hunk comment or requested change"></textarea><pre class="ds-diff-lines"><code><span class="ds-diff-line add"><span class="ds-diff-num"></span><span class="ds-diff-num">1</span><span class="ds-diff-mark">+</span><span class="ds-diff-code">export function readFilter(search: string): string {</span></span><span class="ds-diff-line add"><span class="ds-diff-num"></span><span class="ds-diff-num">2</span><span class="ds-diff-mark">+</span><span class="ds-diff-code"> const params = new URLSearchParams(search);</span></span><span class="ds-diff-line add"><span class="ds-diff-num"></span><span class="ds-diff-num">3</span><span class="ds-diff-mark">+</span><span class="ds-diff-code"> return params.get("filter") || "all";</span></span><span class="ds-diff-line add"><span class="ds-diff-num"></span><span class="ds-diff-num">4</span><span class="ds-diff-mark">+</span><span class="ds-diff-code">}</span></span></code></pre></div></details></div><div class="ds-codeedit-actions"><button class="ds-btn ds-btn-line" type="button" data-export-diff-review>Export diff review packet</button><button class="ds-btn ds-btn-line" type="button" data-import-diff-review>Import</button></div></section></article></div><div class="ds-codeedit-actions"><button class="ds-btn ds-btn-line" type="button" data-export-patch-review>Export patch review packet</button><button class="ds-btn ds-btn-line" type="button" data-import-patch-review>Import</button></div></section>
<section class="ds-block ds-diffview" data-block="diff-view" data-id="standalone-diff-review-4"><button class="ds-copy" type="button" data-copy aria-label="Copy block" title="Copy"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button><h3 id="standalone-diff-review-4">Standalone diff review</h3><p class="ds-muted">Diff review packets can capture file-level and hunk-level comments.</p><div class="ds-diff-summary"><span>1 file</span><span class="add">+1</span><span class="del">-1</span></div><nav class="ds-diff-files"><a href="#standalone-diff-review-4-src-search-searchresults-tsx" class="ds-diff-filelink"><span>src/search/SearchResults.tsx</span><b>+1 -1</b></a></nav><div class="ds-diff-body"><details class="ds-diff-file" id="standalone-diff-review-4-src-search-searchresults-tsx" data-diff-file="standalone-diff-review-4:src/search/SearchResults.tsx" open><summary><span class="ds-diff-path">src/search/SearchResults.tsx</span><span class="ds-diff-stat">+1 -1</span></summary><div class="ds-diff-review"><label><span>File verdict</span><select data-diff-file-verdict="standalone-diff-review-4:src/search/SearchResults.tsx"><option value="undecided" selected>undecided</option><option value="approve">approve</option><option value="revise">revise</option><option value="skip">skip</option><option value="defer">defer</option><option value="block">block</option></select></label><label><span>File comment</span><textarea data-diff-file-comment="standalone-diff-review-4:src/search/SearchResults.tsx" placeholder="File-level review note"></textarea></label></div><div class="ds-diff-meta-lines"><code>diff --git a/src/search/SearchResults.tsx b/src/search/SearchResults.tsx</code><code>--- a/src/search/SearchResults.tsx</code><code>+++ b/src/search/SearchResults.tsx</code></div><div class="ds-hunk" data-diff-hunk="standalone-diff-review-4:src/search/SearchResults.tsx:h1"><div class="ds-hunk-head"><span>@@ -8,6 +8,7 @@ export function SearchResults({ results, filter }) {</span><label><span>Hunk verdict</span><select data-diff-hunk-verdict="standalone-diff-review-4:src/search/SearchResults.tsx:h1"><option value="undecided" selected>undecided</option><option value="approve">approve</option><option value="revise">revise</option><option value="skip">skip</option><option value="defer">defer</option><option value="block">block</option></select></label></div><textarea class="ds-diff-comment" data-diff-hunk-comment="standalone-diff-review-4:src/search/SearchResults.tsx:h1" placeholder="Hunk comment or requested change"></textarea><pre class="ds-diff-lines"><code><span class="ds-diff-line ctx"><span class="ds-diff-num">8</span><span class="ds-diff-num">8</span><span class="ds-diff-mark"> </span><span class="ds-diff-code"> if (!results.length) {</span></span><span class="ds-diff-line add"><span class="ds-diff-num"></span><span class="ds-diff-num">9</span><span class="ds-diff-mark">+</span><span class="ds-diff-code"> return <EmptyResults activeFilter={filter} />;</span></span><span class="ds-diff-line del"><span class="ds-diff-num">9</span><span class="ds-diff-num"></span><span class="ds-diff-mark">-</span><span class="ds-diff-code"> return <p>No results</p>;</span></span><span class="ds-diff-line ctx"><span class="ds-diff-num">10</span><span class="ds-diff-num">10</span><span class="ds-diff-mark"> </span><span class="ds-diff-code"> }</span></span><span class="ds-diff-line ctx"><span class="ds-diff-num">11</span><span class="ds-diff-num">11</span><span class="ds-diff-mark"> </span><span class="ds-diff-code"> return <ResultList results={results} />;</span></span><span class="ds-diff-line ctx"><span class="ds-diff-num">12</span><span class="ds-diff-num">12</span><span class="ds-diff-mark"> </span><span class="ds-diff-code">}</span></span></code></pre></div></details></div><div class="ds-codeedit-actions"><button class="ds-btn ds-btn-line" type="button" data-export-diff-review>Export diff review packet</button><button class="ds-btn ds-btn-line" type="button" data-import-diff-review>Import</button></div></section>
<section class="ds-block" data-block="verification-run" data-id="verification-plan-5"><button class="ds-copy" type="button" data-copy aria-label="Copy block" title="Copy"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button><h3 id="verification-plan-5">Verification plan</h3><div class="ds-process-list"><article class="ds-process-card ds-vrun"><div class="ds-process-card-head"><div><h4>Unit tests</h4></div><div class="ds-chips"><span class="ds-chip">status · planned</span><span class="ds-chip">kind · planned</span></div></div><dl class="ds-detailgrid"><div class="ds-detail"><dt>command</dt><dd>npm test</dd></div><div class="ds-detail"><dt>expected</dt><dd>Filter helper and empty state tests pass.</dd></div></dl></article><article class="ds-process-card ds-vrun"><div class="ds-process-card-head"><div><h4>Typecheck</h4></div><div class="ds-chips"><span class="ds-chip">status · planned</span><span class="ds-chip">kind · planned</span></div></div><dl class="ds-detailgrid"><div class="ds-detail"><dt>command</dt><dd>npx tsc --noEmit</dd></div><div class="ds-detail"><dt>expected</dt><dd>No TypeScript errors.</dd></div></dl></article></div></section>
<section class="ds-block" data-block="trust-report" data-id="implementation-trust-6"><button class="ds-copy" type="button" data-copy aria-label="Copy block" title="Copy"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button><h3 id="implementation-trust-6">Implementation trust</h3><div class="ds-trust-sources"><h4>Sources</h4><div class="ds-tablewrap"><table><thead><tr><th>Source</th><th>Kind</th><th>Trust</th><th>License</th><th>Summary</th></tr></thead><tbody><tr id="implementation-trust-6-work-plan" data-trust-source="work-plan"><td>Work plan</td><td>dossier block</td><td>medium</td><td></td><td>Human-reviewed proposed work items.</td></tr><tr id="implementation-trust-6-verification" data-trust-source="verification"><td>Verification plan</td><td>command queue</td><td>pending</td><td></td><td>Commands still need to be run in the host repo.</td></tr></tbody></table></div></div><div class="ds-process-list ds-trust-claims"><article class="ds-process-card ds-trust-claim status-verified" data-trust-claim="ready-to-edit"><div class="ds-process-card-head"><div><h4>The packet contains enough information for an agent to start implementation.</h4></div><div class="ds-chips"><span class="ds-chip">status · verified</span><span class="ds-chip">confidence · medium</span></div></div><div class="ds-trust-refs"><a class="ds-chip ds-trust-link" href="#implementation-trust-6-work-plan">Work plan</a></div></article><article class="ds-process-card ds-trust-claim status-guardrail" data-trust-claim="not-merged"><div class="ds-process-card-head"><div><h4>The patch is not verified or merged until host commands pass.</h4></div><div class="ds-chips"><span class="ds-chip">status · guardrail</span><span class="ds-chip">confidence · high</span></div></div><div class="ds-trust-refs"><a class="ds-chip ds-trust-link" href="#implementation-trust-6-verification">Verification plan</a></div></article></div></section>
</main>
<aside class="ds-toc"><div class="ds-search"><input type="search" placeholder="Search…" data-search></div><div class="ds-toc-head">On this page</div><a class="ds-toc-link lvl-1" href="#a-code-editing-handoff-that-agents-can-actually-consume-0" data-toc="a-code-editing-handoff-that-agents-can-actually-consume-0">A code editing handoff that agents can actually consume</a><a class="ds-toc-link lvl-2" href="#work-plan-1" data-toc="work-plan-1">Work plan</a><a class="ds-toc-link lvl-2" href="#editable-helper-proposal-2" data-toc="editable-helper-proposal-2">Editable helper proposal</a><a class="ds-toc-link lvl-2" href="#proposed-patches-3" data-toc="proposed-patches-3">Proposed patches</a><a class="ds-toc-link lvl-2" href="#standalone-diff-review-4" data-toc="standalone-diff-review-4">Standalone diff review</a><a class="ds-toc-link lvl-2" href="#verification-plan-5" data-toc="verification-plan-5">Verification plan</a><a class="ds-toc-link lvl-2" href="#implementation-trust-6" data-toc="implementation-trust-6">Implementation trust</a></aside>
</div>
<footer class="ds-footer">2 min read · 425 words · Generated with Dossier · 2026-06-29</footer>
</div>
<button class="ds-totop" type="button" data-totop aria-label="Back to top">↑</button>
<div class="ds-palette" data-palette hidden><div class="ds-palette-box" role="dialog" aria-label="Command palette"><input type="text" placeholder="Jump to or run an action…" data-palette-input><div class="ds-palette-list" data-palette-list></div></div></div>
<div class="ds-modal" data-source-modal hidden><div class="ds-modal-box" role="dialog" aria-modal="true" aria-label="Markdown source"><div class="ds-modal-head"><strong>Markdown source</strong><button class="ds-btn" type="button" data-source-close>Close</button></div><textarea readonly data-source-text></textarea></div></div>
<div class="ds-modal" data-shortcuts-modal hidden><div class="ds-modal-box ds-shortcuts-box" role="dialog" aria-modal="true" aria-label="Keyboard shortcuts"><div class="ds-modal-head"><strong>Keyboard shortcuts</strong><button class="ds-btn" type="button" data-shortcuts-close>Close</button></div><dl class="ds-shortcuts"><div><dt><kbd>⌘K</kbd></dt><dd>Open command palette</dd></div><div><dt><kbd>/</kbd></dt><dd>Focus document search</dd></div><div><dt><kbd>?</kbd></dt><dd>Open shortcuts</dd></div><div><dt><kbd>T</kbd></dt><dd>Toggle theme</dd></div><div><dt><kbd>Esc</kbd></dt><dd>Close active panel</dd></div></dl></div></div>
<div class="ds-tool-modal" data-export-modal hidden><div class="ds-tool-card ds-tool-wide" role="dialog" aria-modal="true" aria-label="Export Center"><div class="ds-tool-head"><div><strong>Export Center</strong><p data-export-summary>Choose exactly what should leave this artifact.</p></div><button class="ds-btn ds-btn-line" type="button" data-tool-close>Close</button></div><div class="ds-export-grid"><button class="ds-btn ds-btn-line" type="button" data-export-kind="source">Preview source JSON</button><button class="ds-btn ds-btn-line" type="button" data-export-kind="state">Preview state packet</button><button class="ds-btn ds-btn-line" type="button" data-export-kind="merged">Preview merged JSON</button><button class="ds-btn ds-btn-line" type="button" data-export-kind="handoff">Preview agent handoff</button><button class="ds-btn ds-btn-line" type="button" data-export-kind="prompt">Preview AI prompt</button><label class="ds-file-btn" role="button" tabindex="0">Import state packet<input type="file" accept="application/json" data-state-file></label><label class="ds-file-btn" role="button" tabindex="0">Compare revision<input type="file" accept="application/json" data-revision-file></label></div><div class="ds-export-grid"><button class="ds-btn" type="button" data-export-download="source">Download source JSON</button><button class="ds-btn" type="button" data-export-download="state">Download state packet</button><button class="ds-btn" type="button" data-export-download="merged">Download merged JSON</button><button class="ds-btn" type="button" data-export-download="handoff">Download handoff</button><button class="ds-btn" type="button" data-export-download="prompt">Download prompt</button><button class="ds-btn ds-btn-line" type="button" data-action="print-pdf">Print / save PDF</button><button class="ds-btn ds-btn-line" type="button" data-export-copy>Copy preview</button></div><div class="ds-export-preview-head"><strong data-export-preview-title>Current state packet</strong></div><textarea class="ds-export-preview" readonly data-export-preview></textarea><textarea class="ds-export-preview ds-revision-result" readonly data-revision-result placeholder="Revision diff appears here after comparing another dossier JSON."></textarea></div></div>
<div class="ds-tool-modal" data-block-editor-modal hidden><div class="ds-tool-card" role="dialog" aria-modal="true" aria-label="Block editor"><div class="ds-tool-head"><div><strong>Block editor</strong><p>Reorder, delete, or add top-level blocks, then download merged JSON and rebuild.</p></div><button class="ds-btn ds-btn-line" type="button" data-tool-close>Close</button></div><div class="ds-blockedit-list" data-block-editor-list></div><div class="ds-tool-row"><select data-block-editor-type><option>prose</option><option>section</option><option>callout</option><option>table</option><option>code-editor</option><option>process-board</option><option>patch-set</option><option>verification-run</option><option>release-checklist</option></select><input type="text" data-block-editor-title placeholder="New block title"><button class="ds-btn" type="button" data-block-editor-add>Add block</button></div><p class="ds-tool-note" data-block-editor-status></p></div></div>
<div class="ds-tool-modal" data-evidence-modal hidden><div class="ds-tool-card" role="dialog" aria-modal="true" aria-label="Attach evidence"><div class="ds-tool-head"><div><strong>Attach evidence</strong><p>Add source material to the state packet and merged dossier.</p></div><button class="ds-btn ds-btn-line" type="button" data-tool-close>Close</button></div><div class="ds-field-grid"><label>Id<input type="text" data-evidence-id placeholder="auto-from-title"></label><label>Title<input type="text" data-evidence-title placeholder="Browser smoke"></label><label>Kind<input type="text" data-evidence-kind placeholder="manual"></label><label>Trust<select data-evidence-trust><option>medium</option><option>high</option><option>low</option></select></label><label class="wide">Source<input type="text" data-evidence-source placeholder="command, URL, person, file"></label><label class="wide">Body<textarea data-evidence-body placeholder="What was observed?"></textarea></label></div><div class="ds-tool-actions"><button class="ds-btn" type="button" data-evidence-add>Add evidence</button></div></div></div>
<div class="ds-toast" data-toast role="status" aria-live="polite"></div>
<div class="ds-studio" data-studio hidden role="dialog" aria-label="Theme studio">
<div class="ds-studio-head"><strong>Theme studio</strong><button class="ds-btn" type="button" data-studio-close>Close</button></div>
<label class="ds-studio-row">Accent <input type="color" data-studio-token="accent" data-studio-accent></label>
<label class="ds-studio-row">Canvas <input type="color" data-studio-token="bg"></label>
<label class="ds-studio-row">Surface <input type="color" data-studio-token="bg-2"></label>
<label class="ds-studio-row">Ink <input type="color" data-studio-token="ink"></label>
<label class="ds-studio-row">Frame <input type="text" data-studio-token="frame" placeholder="1120px"></label>
<div class="ds-studio-presets"><button class="ds-studio-sw" type="button" data-studio-preset="berry" title="berry" style="background:#c81e4a"></button><button class="ds-studio-sw" type="button" data-studio-preset="slate" title="slate" style="background:#4f5b6b"></button><button class="ds-studio-sw" type="button" data-studio-preset="forest" title="forest" style="background:#2f7d55"></button><button class="ds-studio-sw" type="button" data-studio-preset="ocean" title="ocean" style="background:#1f7a98"></button><button class="ds-studio-sw" type="button" data-studio-preset="midnight" title="midnight" style="background:#5b6ef5"></button><button class="ds-studio-sw" type="button" data-studio-preset="amber" title="amber" style="background:#c2790c"></button><button class="ds-studio-sw" type="button" data-studio-preset="plum" title="plum" style="background:#8a3ffc"></button></div>
<select class="ds-studio-select" data-studio-saved><option value="">Saved presets</option></select>
<textarea class="ds-studio-json" data-studio-json spellcheck="false"></textarea>
<div class="ds-studio-actions"><button class="ds-btn ds-btn-line" type="button" data-studio-copy>Copy JSON</button><button class="ds-btn ds-btn-line" type="button" data-studio-import>Import JSON</button><button class="ds-btn ds-btn-line" type="button" data-studio-save>Save preset</button><button class="ds-btn ds-btn-line" type="button" data-studio-download>Download theme</button><button class="ds-btn ds-btn-line" type="button" data-studio-reset>Reset</button></div>
</div>
<script type="application/json" id="ds-themes">{"default":{},"berry":{"accent":"#c81e4a","accent-2":"#a8183d","accent-tint":"rgba(200,30,74,.08)"},"slate":{"accent":"#4f5b6b","accent-2":"#3a4452","accent-tint":"rgba(79,91,107,.1)"},"forest":{"accent":"#2f7d55","accent-2":"#246342","accent-tint":"rgba(47,125,85,.1)"},"ocean":{"accent":"#1f7a98","accent-2":"#185f76","accent-tint":"rgba(31,122,152,.1)"},"midnight":{"accent":"#5b6ef5","accent-2":"#4654d4","accent-tint":"rgba(91,110,245,.12)"},"amber":{"accent":"#c2790c","accent-2":"#a06409","accent-tint":"rgba(194,121,12,.12)"},"plum":{"accent":"#8a3ffc","accent-2":"#722fd1","accent-tint":"rgba(138,63,252,.1)"}}</script>
<script type="application/json" id="dossier-model">{"$schema":"https://raw.githubusercontent.com/kylebegeman/dossier/next/schema/dossier.schema.json","dossierVersion":"1.0","kind":"implementation","meta":{"title":"Implementation Packet: Search Filter","slug":"implementation-packet","eyebrow":"Agent workflow example","crumbs":["Examples","Implementation packet"],"status":"review","owner":"Engineering","updated":"2026-06-29","tags":["example","implementation","agent"],"lifecycle":{"stage":"review","note":"A code-editing packet with proposed work, patch review, diff review, and verification."}},"blocks":[{"type":"hero","eyebrow":"Implementation packet","title":"A code editing handoff that agents can actually consume","lede":"This example shows the process Dossier shape for coding work: work items, editable snippets, patch proposals, diff review, verification receipts, trust claims, and closeout.","pills":["Work items","Patch review","Diff review","MCP packets"],"sideCards":[{"label":"Packet schemas","value":"edits + process + trust"},{"label":"Human input","value":"verdicts + notes"},{"label":"Agent readback","value":"MCP tools"}],"id":"a-code-editing-handoff-that-agents-can-actually-consume-0"},{"type":"process-board","title":"Work plan","items":[{"id":"filter-state","title":"Persist selected filter","summary":"Save the active search filter in the URL query so refresh and share links preserve state.","category":"Frontend","status":"proposed","owner":"agent","priority":"P1","impact":"Medium","effort":"Small","files":["src/search/filter-state.ts","src/search/SearchPanel.tsx"],"verification":["npm test","npx tsc --noEmit"]},{"id":"empty-state","title":"Improve empty results state","summary":"Show the active filter and a clear reset action when no results match.","category":"UX","status":"proposed","owner":"agent","priority":"P2","impact":"Medium","effort":"Small","files":["src/search/SearchResults.tsx"]}],"id":"work-plan-1"},{"type":"code-editor","title":"Editable helper proposal","summary":"`dossier serve` enhances this textarea with CodeMirror 6 while Dossier still exports plain `dossier.edits/v1`.","lang":"ts","filename":"filter-state.ts","targetPath":"src/search/filter-state.ts","workItems":["filter-state"],"code":"export function readFilter(search: string): string {\n const params = new URLSearchParams(search);\n return params.get(\"filter\") || \"all\";\n}\n\nexport function writeFilter(search: string, filter: string): string {\n const params = new URLSearchParams(search);\n if (filter === \"all\") params.delete(\"filter\");\n else params.set(\"filter\", filter);\n return params.toString();\n}\n","id":"editable-helper-proposal-2"},{"type":"patch-set","title":"Proposed patches","summary":"A patch set groups intent, touched files, risk, verification, and optional unified diffs.","patches":[{"id":"persist-filter","title":"Persist filter in query string","summary":"Add a small helper and wire the search panel to update the URL.","operation":"add","status":"proposed","risk":"low","files":["src/search/filter-state.ts","src/search/SearchPanel.tsx"],"workItems":["filter-state"],"verification":["npm test","npx tsc --noEmit"],"diff":"diff --git a/src/search/filter-state.ts b/src/search/filter-state.ts\nnew file mode 100644\n--- /dev/null\n+++ b/src/search/filter-state.ts\n@@ -0,0 +1,4 @@\n+export function readFilter(search: string): string {\n+ const params = new URLSearchParams(search);\n+ return params.get(\"filter\") || \"all\";\n+}"}],"id":"proposed-patches-3"},{"type":"diff-view","title":"Standalone diff review","summary":"Diff review packets can capture file-level and hunk-level comments.","diff":"diff --git a/src/search/SearchResults.tsx b/src/search/SearchResults.tsx\n--- a/src/search/SearchResults.tsx\n+++ b/src/search/SearchResults.tsx\n@@ -8,6 +8,7 @@ export function SearchResults({ results, filter }) {\n if (!results.length) {\n+ return \u003cEmptyResults activeFilter={filter} />;\n- return \u003cp>No results\u003c/p>;\n }\n return \u003cResultList results={results} />;\n }","id":"standalone-diff-review-4"},{"type":"verification-run","title":"Verification plan","runs":[{"id":"unit","title":"Unit tests","command":"npm test","status":"planned","expected":"Filter helper and empty state tests pass."},{"id":"typecheck","title":"Typecheck","command":"npx tsc --noEmit","status":"planned","expected":"No TypeScript errors."}],"id":"verification-plan-5"},{"type":"trust-report","title":"Implementation trust","sources":[{"id":"work-plan","label":"Work plan","kind":"dossier block","trust":"medium","summary":"Human-reviewed proposed work items."},{"id":"verification","label":"Verification plan","kind":"command queue","trust":"pending","summary":"Commands still need to be run in the host repo."}],"claims":[{"id":"ready-to-edit","claim":"The packet contains enough information for an agent to start implementation.","status":"verified","confidence":"medium","sources":["work-plan"]},{"id":"not-merged","claim":"The patch is not verified or merged until host commands pass.","status":"guardrail","confidence":"high","sources":["verification"]}],"id":"implementation-trust-6"}]}</script>
<script type="text/markdown" id="dossier-markdown">---
title: "Implementation Packet: Search Filter"
slug: "implementation-packet"
status: "review"
updated: "2026-06-29"
---
# A code editing handoff that agents can actually consume
This example shows the process Dossier shape for coding work: work items, editable snippets, patch proposals, diff review, verification receipts, trust claims, and closeout.
## Work plan
### Persist selected filter (proposed)
Save the active search filter in the URL query so refresh and share links preserve state.
- **Owner:** agent
- **Priority:** P1
- **Files:** src/search/filter-state.ts, src/search/SearchPanel.tsx
- **Verification:** npm test, npx tsc --noEmit
### Improve empty results state (proposed)
Show the active filter and a clear reset action when no results match.
- **Owner:** agent
- **Priority:** P2
- **Files:** src/search/SearchResults.tsx
## Editable helper proposal
`dossier serve` enhances this textarea with CodeMirror 6 while Dossier still exports plain `dossier.edits/v1`.
```ts
export function readFilter(search: string): string {
const params = new URLSearchParams(search);
return params.get("filter") || "all";
}
export function writeFilter(search: string, filter: string): string {
const params = new URLSearchParams(search);
if (filter === "all") params.delete("filter");
else params.set("filter", filter);
return params.toString();
}
```
## Proposed patches
A patch set groups intent, touched files, risk, verification, and optional unified diffs.
### Persist filter in query string
Add a small helper and wire the search panel to update the URL.
- **Operation:** add
- **Status:** proposed
- **Risk:** low
- **Files:** src/search/filter-state.ts, src/search/SearchPanel.tsx
- **Work items:** filter-state
- **Verification:** npm test, npx tsc --noEmit
```diff
diff --git a/src/search/filter-state.ts b/src/search/filter-state.ts
new file mode 100644
--- /dev/null
+++ b/src/search/filter-state.ts
@@ -0,0 +1,4 @@
+export function readFilter(search: string): string {
+ const params = new URLSearchParams(search);
+ return params.get("filter") || "all";
+}
```
## Standalone diff review
Diff review packets can capture file-level and hunk-level comments.
src/search/SearchResults.tsx (+1/-1)
```diff
diff --git a/src/search/SearchResults.tsx b/src/search/SearchResults.tsx
--- a/src/search/SearchResults.tsx
+++ b/src/search/SearchResults.tsx
@@ -8,6 +8,7 @@ export function SearchResults({ results, filter }) {
if (!results.length) {
+ return <EmptyResults activeFilter={filter} />;
- return <p>No results</p>;
}
return <ResultList results={results} />;
}
```
## Verification plan
### Unit tests (planned)
```sh
npm test
```
- **Expected:** Filter helper and empty state tests pass.
### Typecheck (planned)
```sh
npx tsc --noEmit
```
- **Expected:** No TypeScript errors.
## Implementation trust
### Sources
- **work-plan:** Work plan (medium)
Human-reviewed proposed work items.
- **verification:** Verification plan (pending)
Commands still need to be run in the host repo.
### Claims
- **The packet contains enough information for an agent to start implementation.** (verified), confidence: medium
- Sources: work-plan
- **The patch is not verified or merged until host commands pass.** (guardrail), confidence: high
- Sources: verification
</script>
<script type="text/plain" id="dossier-digest"># Implementation Packet: Search Filter [review]
SUMMARY: This example shows the process Dossier shape for coding work: work items, editable snippets, patch proposals, diff review, verification receipts, trust claims, and closeout.
- process-board: Work plan
- code-editor: Editable helper proposal
- patch-set: Proposed patches
- diff-view: Standalone diff review
- verification-run: Verification plan
- trust-report: Implementation trust</script>
<script>
(function(){
var $=function(s,r){return (r||document).querySelector(s)};
var $$=function(s,r){return Array.prototype.slice.call((r||document).querySelectorAll(s))};
var model={},mdSrc="",digestSrc="",slug="dossier";
try{model=JSON.parse($("#dossier-model").textContent);}catch(e){}
window.__DOSSIER_MODEL__=model;
mdSrc=(($("#dossier-markdown")||{}).textContent||"");
digestSrc=(($("#dossier-digest")||{}).textContent||"");
slug=(model.meta&&model.meta.slug)||"dossier";
var store="ds:"+slug;
var dirty=false;
function toast(msg){var t=$("[data-toast]");if(!t)return;t.textContent=msg;t.classList.add("show");setTimeout(function(){t.classList.remove("show")},1600);}
function copy(text,msg){if(navigator.clipboard){navigator.clipboard.writeText(text).then(function(){toast(msg||"Copied")});}else{var ta=document.createElement("textarea");ta.value=text;document.body.appendChild(ta);ta.select();try{document.execCommand("copy")}catch(e){}ta.remove();toast(msg||"Copied");}}
function download(name,text,type){var b=new Blob([text],{type:type||"text/plain"});var u=URL.createObjectURL(b);var a=document.createElement("a");a.href=u;a.download=name;a.click();URL.revokeObjectURL(u);}
function slugifyClient(s){return String(s||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)||"item";}
function clone(o){return JSON.parse(JSON.stringify(o||{}));}
function nowIso(){try{return new Date().toISOString();}catch(e){return "";}}
function countMap(m){return Object.keys(m||{}).length;}
function markDirty(){dirty=true;document.documentElement.classList.add("ds-dirty");updateDirtyStatus();}
function updateDirtyStatus(){var el=$("[data-dirty-status]");if(!el)return;var edits=state.editors||{},diff=state.diffReview||{files:{},hunks:{}};var n=countMap(state.actions)+countMap(state.decisions)+countMap(state.process)+Object.keys(edits).filter(function(id){return edits[id]&&edits[id].dirty!==false}).length+countMap(state.verdicts)+countMap(state.release)+countMap(state.patchReview)+countMap(diff.files)+countMap(diff.hunks)+countMap(state.evidence);el.hidden=!dirty&&!n;el.textContent=n?("state "+n):"edited";}
function walkBlocks(blocks,fn){(blocks||[]).forEach(function(b){if(!b||typeof b!=="object")return;fn(b);if(b.blocks)walkBlocks(b.blocks,fn);if(b.left)walkBlocks(b.left,fn);if(b.right)walkBlocks(b.right,fn);if(b.tabs)b.tabs.forEach(function(t){walkBlocks(t.blocks,fn)});if(b.candidates)b.candidates.forEach(function(c){walkBlocks(c.blocks,fn)});if(b.items)b.items.forEach(function(it){walkBlocks(it.blocks,fn)});});}
function applyById(items,map,fn){(items||[]).forEach(function(it,i){var id=it.id||String(i),u=map[id];if(u)fn(it,u);});}
function statefulJson(m){return JSON.stringify(m,null,2);}
function sourceModelJson(){return statefulJson(model);}
function collectActions(){var out={};$$(".ds-action").forEach(function(li){var id=li.getAttribute("data-action"),cb=$("[data-action-check]",li);if(id&&cb)out[id]=!!cb.checked;});state.actions=out;return out;}
function collectDecisions(){var out={};$$("[data-select]").forEach(function(cb){var id=cb.getAttribute("data-select");var ta=byAttr("[data-notes]","data-notes",id);out[id]={selected:!!cb.checked,notes:ta?ta.value:""};});state.decisions=out;return out;}
function collectEditorsMap(){var edits={};$$("[data-code-editor]").forEach(function(ta){var id=ta.getAttribute("data-code-editor");edits[id]={text:ta.value,lang:ta.getAttribute("data-editor-lang")||"",filename:ta.getAttribute("data-editor-filename")||"",targetPath:ta.getAttribute("data-editor-target")||"",title:ta.getAttribute("data-editor-title")||"",dirty:ta.value!==ta.__original};});state.editors=edits;return edits;}
function collectEvidence(){state.evidence=state.evidence||{};return state.evidence;}
function collectStatePacket(persist){if(persist!==false&&typeof save==="function")save();var packets={actions:collectActions(),decisions:collectDecisions(),process:typeof collectProcess==="function"?collectProcess():(state.process||{}),edits:collectEditorsMap(),verdicts:typeof collectVerdicts==="function"?collectVerdicts():(state.verdicts||{}),release:typeof collectRelease==="function"?collectRelease():(state.release||{}),patchReview:typeof collectPatchReview==="function"?collectPatchReview():(state.patchReview||{}),diffReview:typeof collectDiffReview==="function"?collectDiffReview():(state.diffReview||{files:{},hunks:{}}),evidence:collectEvidence()};return {schema:"dossier.state/v1",slug:slug,updatedAt:nowIso(),packets:packets};}
function mergeCurrentState(){var next=clone(model),packet=collectStatePacket(),p=packet.packets;walkBlocks(next.blocks||[],function(b){if(b.type==="action-items"){(b.items||[]).forEach(function(it,i){var id=b.id+":"+i;if(p.actions[id]!==undefined)it.status=p.actions[id]?"done":"todo";});}if(b.type==="review-board")applyById(b.candidates,p.decisions,function(it,u){it.selected=!!u.selected;if(u.notes!=null)it.notes=u.notes;});if(b.type==="process-board")applyById(b.items,p.process,function(it,u){if(u.verdict!=null)it.verdict=u.verdict;if(u.notes!=null)it.notes=u.notes;});if(b.type==="code-editor"){var id=b.id||slugifyClient(b.title||b.filename||b.targetPath||"code-editor"),u=p.edits[id];if(!u)Object.keys(p.edits).some(function(k){var e=p.edits[k];if(e&&((e.targetPath&&e.targetPath===b.targetPath)||(e.filename&&e.filename===b.filename)||(e.title&&e.title===b.title))){u=e;return true;}return false;});if(u&&u.text!=null)b.code=String(u.text);}if(b.type==="verdict-gate"){var gid=b.gateId||b.id||slugifyClient(b.title||"verdict-gate"),vu=p.verdicts[gid];if(vu){if(vu.verdict!=null)b.verdict=vu.verdict;if(vu.notes!=null)b.notes=vu.notes;}}if(b.type==="release-checklist")applyById(b.gates,p.release,function(g,u){if(u.done!=null)g.status=u.done?"done":"todo";if(u.notes!=null)g.evidence=u.notes;});if(b.type==="patch-set")applyById(b.patches,p.patchReview,function(pa,u){if(u.verdict!=null){pa.review=u.verdict;if(u.verdict==="approve")pa.status=pa.status==="applied"?"applied":"accepted";else if(u.verdict==="revise")pa.status="needs-revision";else if(u.verdict==="skip")pa.status="skipped";}if(u.notes!=null)pa.notes=u.notes;});if(b.type==="diff-view"&&(Object.keys(p.diffReview.files||{}).length||Object.keys(p.diffReview.hunks||{}).length))b.review=p.diffReview;});var evidence=Object.keys(p.evidence||{}).map(function(id){var e=p.evidence[id]||{};e.id=id;return e;});if(evidence.length){var log=null;walkBlocks(next.blocks||[],function(b){if(!log&&b.type==="evidence-log")log=b;});if(!log){log={type:"evidence-log",id:"state-evidence",title:"Attached evidence",items:[]};next.blocks=next.blocks||[];next.blocks.push(log);}var seen={};(log.items||[]).forEach(function(e){seen[e.id]=true;});log.items=(log.items||[]).concat(evidence.filter(function(e){return !seen[e.id];}));}next.meta=next.meta||{};next.meta.stateExportedAt=packet.updatedAt;return next;}
function handoffPacket(){var packet=collectStatePacket(),p=packet.packets;var dirtyEdits=Object.keys(p.edits).filter(function(id){return p.edits[id]&&p.edits[id].dirty!==false;}).map(function(id){var e=p.edits[id];return {id:id,targetPath:e.targetPath||e.filename||"",title:e.title||"",dirty:e.dirty!==false};});var release=Object.keys(p.release).map(function(id){var g=p.release[id]||{};g.id=id;return g;});return {schema:"dossier.handoff/v1",slug:slug,title:(model.meta&&model.meta.title)||"Dossier",kind:model.kind||"dossier",generatedAt:packet.updatedAt,totals:{decisions:Object.keys(p.decisions).length,selectedDecisions:Object.keys(p.decisions).filter(function(id){return p.decisions[id]&&p.decisions[id].selected;}).length,processItems:Object.keys(p.process).length,dirtyEdits:dirtyEdits.length,releaseGates:release.length,unresolvedReleaseGates:release.filter(function(g){return g.required&&!g.done;}).length,patchReviews:Object.keys(p.patchReview).length,diffFileReviews:Object.keys(p.diffReview.files||{}).length,diffHunkReviews:Object.keys(p.diffReview.hunks||{}).length,evidence:Object.keys(p.evidence).length},decisions:p.decisions,process:p.process,edits:dirtyEdits,release:{gates:release,unresolved:release.filter(function(g){return g.required&&!g.done;})},patchReview:p.patchReview,diffReview:p.diffReview,evidence:p.evidence,nextAgentInstruction:"Use selected and approved items first. Treat notes as constraints. Apply dirty edits only when target paths are unambiguous. Resolve release and trust gaps before closeout."};}
function promptText(){var h=handoffPacket();return "Create or update a Dossier JSON model for \""+h.title+"\".\n\nRequirements:\n- Use dossierVersion \"1.0\" and stable kebab-case ids for every block and nested packet item.\n- Kind should be \""+h.kind+"\". Use process blocks when work must round-trip to an agent.\n- Include a hero first, then sectioned blocks with concise titles and source-backed claims.\n- For implementation or review work, include process-board, patch-set or diff-view, verification-run, trust-report, and process-receipt blocks when relevant.\n- Add targetPath on every code-editor that should be applied back to files.\n- Keep export semantics clear: source JSON is the authored model; state packets are human changes; merged JSON applies state back into the model.\n\nCurrent handoff summary: "+JSON.stringify(h.totals);}
function diffModelsClient(a,z){var aa=(a.blocks||[]),zz=(z.blocks||[]),am={},zm={},added=[],removed=[],changed=[];aa.forEach(function(b,i){am[b.id||("index-"+i)]=b;});zz.forEach(function(b,i){zm[b.id||("index-"+i)]=b;});Object.keys(zm).forEach(function(id){if(!am[id])added.push(id);else if(JSON.stringify(zm[id])!==JSON.stringify(am[id]))changed.push(id);});Object.keys(am).forEach(function(id){if(!zm[id])removed.push(id);});return {schema:"dossier.diff/v1",slug:slug,added:added,removed:removed,changed:changed,metaChanged:JSON.stringify(a.meta||{})!==JSON.stringify(z.meta||{})};}
function validatePacket(d,name){var expect={process:"dossier.process/v1",edits:"dossier.edits/v1",verdicts:"dossier.verdicts/v1",release:"dossier.release/v1",patch:"dossier.patch-review/v1",diff:"dossier.diff-review/v1",state:"dossier.state/v1"}[name];if(expect&&d&&d.schema&&d.schema!==expect)throw new Error("expected "+expect);return d;}
function downloadState(){download(slug+".state.json",statefulJson(collectStatePacket()),"application/json");}
function downloadMerged(){download(slug+".merged.dossier.json",statefulJson(mergeCurrentState()),"application/json");}
function downloadHandoff(){download(slug+".handoff.json",statefulJson(handoffPacket()),"application/json");}
function printCurrent(){toast(dirty?"Print uses current visible state":"Opening print preview");setTimeout(function(){window.print();},60);}
var savedTheme=localStorage.getItem("ds:theme");
if(savedTheme)document.documentElement.setAttribute("data-theme",savedTheme);
var tt=$("[data-theme-toggle]");
function themeGlyph(){return document.documentElement.getAttribute("data-theme")==="dark"?"☀":"☾";}
function toggleTheme(){var cur=document.documentElement.getAttribute("data-theme")==="dark"?"light":"dark";document.documentElement.setAttribute("data-theme",cur);localStorage.setItem("ds:theme",cur);if(tt)tt.textContent=themeGlyph();}
if(tt){tt.textContent=themeGlyph();tt.addEventListener("click",toggleTheme);}
var bar=$(".ds-progress-bar");
function prog(){if(!bar)return;var h=document.documentElement.scrollHeight-window.innerHeight;bar.style.width=(h>0?(window.scrollY/h*100):0)+"%";}
window.addEventListener("scroll",prog,{passive:true});prog();
var links={};$$(".ds-toc-link").forEach(function(l){links[l.getAttribute("data-toc")]=l;});
if(window.IntersectionObserver){
var io=new IntersectionObserver(function(ents){ents.forEach(function(en){if(en.isIntersecting){var id=en.target.id;if(links[id]){Object.keys(links).forEach(function(k){links[k].classList.toggle("active",k===id);});}}});},{rootMargin:"-8% 0px -82% 0px"});
Object.keys(links).forEach(function(id){var el=document.getElementById(id);if(el)io.observe(el);});
}
$$("[data-copy]").forEach(function(btn){btn.addEventListener("click",function(e){e.stopPropagation();var blk=btn.closest(".ds-block");var txt=blk?blk.innerText.replace(/^Copy\s*/,""):"";copy(txt,"Block copied");});});
$$("[data-toggle]").forEach(function(btn){btn.addEventListener("click",function(){var sec=btn.closest(".ds-section");var c=sec.getAttribute("data-collapsed")==="1";sec.setAttribute("data-collapsed",c?"0":"1");});});
$$(".ds-tabs").forEach(function(w){var tabs=$$(".ds-tab",w),panes=$$(".ds-pane",w);tabs.forEach(function(tb){tb.addEventListener("click",function(){var i=tb.getAttribute("data-tab");tabs.forEach(function(x){x.classList.toggle("active",x===tb)});panes.forEach(function(p){p.classList.toggle("active",p.getAttribute("data-pane")===i)});});});});
var search=$("[data-search]");
if(search){search.addEventListener("input",function(){var q=search.value.trim().toLowerCase();$$(".ds-content > .ds-block").forEach(function(blk){var hit=!q||blk.innerText.toLowerCase().indexOf(q)>=0;blk.style.display=hit?"":"none";});});}
var focusableSel='a[href],button:not([disabled]),input:not([disabled]):not([type="file"]),select:not([disabled]),textarea:not([disabled]),[role="button"],[tabindex]:not([tabindex="-1"])';
function focusableIn(root){return $$(focusableSel,root).filter(function(el){return !el.closest("[hidden]")&&el.tabIndex!==-1;});}
function showLayer(m,focusEl){if(!m)return;m.__lastFocus=document.activeElement;m.hidden=false;var f=focusEl||focusableIn(m)[0];if(f&&f.focus)f.focus();}
function hideLayer(m){if(!m||m.hidden)return;m.hidden=true;var f=m.__lastFocus;if(f&&document.contains(f)&&f.focus)f.focus();}
function topLayer(){var open=$$(".ds-palette:not([hidden]),.ds-modal:not([hidden]),.ds-tool-modal:not([hidden]),.ds-studio:not([hidden])");return open.length?open[open.length-1]:null;}
function closeTopLayer(){var m=topLayer();if(!m)return false;hideLayer(m);return true;}
function trapFocus(e){if(e.key!=="Tab")return;var m=topLayer();if(!m)return;var list=focusableIn(m);if(!list.length){e.preventDefault();return;}var first=list[0],last=list[list.length-1];if(e.shiftKey&&document.activeElement===first){last.focus();e.preventDefault();}else if(!e.shiftKey&&document.activeElement===last){first.focus();e.preventDefault();}}
document.addEventListener("keydown",trapFocus,true);
function viewSource(){var m=$("[data-source-modal]");if(!m)return;$("[data-source-text]").value=mdSrc;showLayer(m,$("[data-source-close]",m));}
function openShortcuts(){var m=$("[data-shortcuts-modal]");if(m)showLayer(m,$("[data-shortcuts-close]",m));}
$$("[data-action]").forEach(function(b){b.addEventListener("click",function(){var a=b.getAttribute("data-action");if(a==="open-export-center")openExportCenter();else if(a==="copy-md")copy(mdSrc,"Markdown copied");else if(a==="copy-digest")copy(digestSrc,"Agent digest copied");else if(a==="copy-prompt")copy(promptText(),"Prompt copied");else if(a==="download-md")download(slug+".md",mdSrc,"text/markdown");else if(a==="download-json")download(slug+".source.dossier.json",sourceModelJson(),"application/json");else if(a==="download-state-json")downloadState();else if(a==="download-merged-json")downloadMerged();else if(a==="download-handoff-json")downloadHandoff();else if(a==="print-pdf")printCurrent();else if(a==="view-source")viewSource();});});
var sc=$("[data-source-close]");if(sc)sc.addEventListener("click",function(){hideLayer($("[data-source-modal]"));});
var shc=$("[data-shortcuts-close]");if(shc)shc.addEventListener("click",function(){hideLayer($("[data-shortcuts-modal]"));});
var pal=$("[data-palette]"),palIn=$("[data-palette-input]"),palList=$("[data-palette-list]");
var cmds=[];
$$(".ds-toc-link").forEach(function(l){cmds.push({label:l.textContent,hint:"Section",act:function(){location.hash="#"+l.getAttribute("data-toc");}});});
cmds.push({label:"Toggle theme",hint:"Action",act:toggleTheme});
cmds.push({label:"Copy Markdown",hint:"Action",act:function(){copy(mdSrc,"Markdown copied");}});
cmds.push({label:"Open Export Center",hint:"Action",act:openExportCenter});
cmds.push({label:"Download source JSON",hint:"Action",act:function(){download(slug+".source.dossier.json",sourceModelJson(),"application/json");}});
cmds.push({label:"Download merged JSON",hint:"Action",act:downloadMerged});
cmds.push({label:"Download agent handoff",hint:"Action",act:downloadHandoff});
cmds.push({label:"View Markdown source",hint:"Action",act:viewSource});
cmds.push({label:"Keyboard shortcuts",hint:"Action",act:openShortcuts});
var palIdx=0,palFiltered=cmds;
function renderPal(){if(!palList)return;palList.innerHTML="";palFiltered.forEach(function(c,i){var d=document.createElement("div");d.className="ds-palette-item"+(i===palIdx?" active":"");var s1=document.createElement("span");s1.textContent=c.label;var s2=document.createElement("small");s2.textContent=c.hint;d.appendChild(s1);d.appendChild(s2);d.addEventListener("click",function(){closePal();c.act();});palList.appendChild(d);});}
function openPal(){if(!pal)return;palIn.value="";palFiltered=cmds;palIdx=0;renderPal();showLayer(pal,palIn);}
function closePal(){if(pal)hideLayer(pal);}
function filterPal(){var q=palIn.value.toLowerCase();palFiltered=cmds.filter(function(c){return c.label.toLowerCase().indexOf(q)>=0;});palIdx=0;renderPal();}
var po=$("[data-palette-open]");if(po)po.addEventListener("click",openPal);
if(palIn){palIn.addEventListener("input",filterPal);palIn.addEventListener("keydown",function(e){if(e.key==="ArrowDown"){palIdx=Math.min(palIdx+1,palFiltered.length-1);renderPal();e.preventDefault();}else if(e.key==="ArrowUp"){palIdx=Math.max(palIdx-1,0);renderPal();e.preventDefault();}else if(e.key==="Enter"){if(palFiltered[palIdx]){var c=palFiltered[palIdx];closePal();c.act();}}else if(e.key==="Escape"){closePal();}});}
document.addEventListener("keydown",function(e){if((e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="k"){e.preventDefault();openPal();}});
if(pal)pal.addEventListener("click",function(e){if(e.target===pal)closePal();});
var state={};try{state=JSON.parse(localStorage.getItem(store)||"{}");}catch(e){}
function save(){localStorage.setItem(store,JSON.stringify(state));}
function byAttr(sel,attr,val,root){var s=String(val);var nodes=$$(sel,root);for(var i=0;i<nodes.length;i++){if(nodes[i].getAttribute(attr)===s)return nodes[i];}return null;}
function packetMap(packet,primary,alternate){var src=(packet&&packet[primary])||(packet&&alternate&&packet[alternate])||packet||{};if(Array.isArray(src)){var out={};src.forEach(function(entry,i){if(entry&&typeof entry==="object")out[entry.id||String(i)]=entry;});return out;}return src&&typeof src==="object"?src:{};}
function normalizeStatePacket(d){d=validatePacket(d,"state");var p=(d&&d.packets)||d||{};var dr=p.diffReview||{};return {actions:packetMap(p.actions||p.actionItems||{},"actions","items"),decisions:packetMap(p.decisions||{},"decisions","items"),process:packetMap(p.process||{},"process","items"),edits:packetMap(p.edits||p.editors||{},"edits","items"),verdicts:packetMap(p.verdicts||{},"verdicts","items"),release:packetMap(p.release||{},"release","gates"),patchReview:packetMap(p.patchReview||p.patches||{},"patches","items"),diffReview:{files:packetMap(dr.files||p.files||{},"files"),hunks:packetMap(dr.hunks||p.hunks||{},"hunks")},evidence:packetMap(p.evidence||{},"evidence","items")};}
function applyStatePacket(d){var p=normalizeStatePacket(d),applied=0;state.actions=p.actions;Object.keys(p.actions).forEach(function(id){var li=byAttr(".ds-action","data-action",id),cb=li?$("[data-action-check]",li):null;if(cb){cb.checked=!!p.actions[id];li.classList.toggle("done",cb.checked);applied++;}});state.decisions=p.decisions;Object.keys(p.decisions).forEach(function(id){var entry=p.decisions[id]||{},cb=byAttr("[data-select]","data-select",id),ta=byAttr("[data-notes]","data-notes",id);if(cb){cb.checked=!!entry.selected;var row=cb.closest(".ds-ritem");if(row)row.classList.toggle("selected",cb.checked);applied++;}if(ta&&entry.notes!=null)ta.value=entry.notes;});state.process=p.process;Object.keys(p.process).forEach(function(id){var entry=p.process[id]||{},sel=byAttr("[data-process-verdict]","data-process-verdict",id),ta=byAttr("[data-process-notes]","data-process-notes",id);if(sel&&entry.verdict){sel.value=entry.verdict;processVerdictClass(sel.closest(".ds-pitem"),sel.value);applied++;}if(ta&&entry.notes!=null)ta.value=entry.notes;});state.editors=p.edits;Object.keys(p.edits).forEach(function(id){var entry=p.edits[id]||{},ta=byAttr("[data-code-editor]","data-code-editor",id);if(ta&&entry.text!=null){ta.value=entry.text;editorMark(id,ta.value!==ta.__original);sizeEditor(ta);applied++;}});state.verdicts=p.verdicts;Object.keys(p.verdicts).forEach(function(id){var entry=p.verdicts[id]||{},sel=byAttr("[data-verdict-gate]","data-verdict-gate",id),ta=byAttr("[data-verdict-notes]","data-verdict-notes",id);if(sel&&entry.verdict){sel.value=entry.verdict;applied++;}if(ta&&entry.notes!=null)ta.value=entry.notes;});state.release=p.release;Object.keys(p.release).forEach(function(id){var entry=p.release[id]||{},cb=byAttr("[data-release-gate]","data-release-gate",id),ta=byAttr("[data-release-notes]","data-release-notes",id);if(cb&&entry.done!=null){cb.checked=!!entry.done;applied++;}if(ta&&entry.notes!=null)ta.value=entry.notes;});state.patchReview=p.patchReview;Object.keys(p.patchReview).forEach(function(id){var entry=p.patchReview[id]||{},sel=byAttr("[data-patch-verdict]","data-patch-verdict",id),ta=byAttr("[data-patch-notes]","data-patch-notes",id);if(sel&&entry.verdict){sel.value=entry.verdict;applied++;}if(ta&&entry.notes!=null)ta.value=entry.notes;});state.diffReview=p.diffReview;Object.keys(p.diffReview.files||{}).forEach(function(id){var entry=p.diffReview.files[id]||{},sel=byAttr("[data-diff-file-verdict]","data-diff-file-verdict",id),ta=byAttr("[data-diff-file-comment]","data-diff-file-comment",id);if(sel&&entry.verdict){sel.value=entry.verdict;applied++;}if(ta&&entry.comment!=null)ta.value=entry.comment;});Object.keys(p.diffReview.hunks||{}).forEach(function(id){var entry=p.diffReview.hunks[id]||{},sel=byAttr("[data-diff-hunk-verdict]","data-diff-hunk-verdict",id),ta=byAttr("[data-diff-hunk-comment]","data-diff-hunk-comment",id);if(sel&&entry.verdict){sel.value=entry.verdict;applied++;}if(ta&&entry.comment!=null)ta.value=entry.comment;});state.evidence=p.evidence;save();markDirty();if(typeof reviewCount==="function")reviewCount();if(typeof reviewFilter==="function")reviewFilter();if(typeof processCount==="function")processCount();if(typeof processFilter==="function")processFilter();setPreview("Imported state packet",statefulJson({schema:"dossier.state/v1",slug:slug,updatedAt:(d&&d.updatedAt)||nowIso(),packets:p}));toast("Imported state packet"+(applied?": "+applied+" controls":""));}
function setPreview(title,text){var head=$("[data-export-preview-title]"),ta=$("[data-export-preview]");if(head)head.textContent=title;if(ta)ta.value=text;}
function openExportCenter(){var m=$("[data-export-modal]");if(!m)return;var packet=collectStatePacket();setPreview("Current state packet",statefulJson(packet));var summary=$("[data-export-summary]");if(summary){var p=packet.packets;summary.textContent="State: "+Object.keys(p.decisions).length+" decisions, "+Object.keys(p.process).length+" process items, "+Object.keys(p.edits).length+" edits, "+Object.keys(p.evidence).length+" evidence records.";}showLayer(m,$("[data-export-kind]",m));}
function closeToolModal(sel){hideLayer($(sel));}
function emptyBlock(type,title){var b={type:type,title:title||type};if(type==="prose"){delete b.title;b.markdown=title||"New prose block.";}else if(type==="section"){b.blocks=[];}else if(type==="callout"){b.body=title||"New callout.";}else if(type==="table"){b.columns=["Column"];b.rows=[["Value"]];}else if(type==="code-editor"){b.code="";b.lang="text";}else if(type==="process-board"){b.items=[{id:"new-work-item",title:title||"New work item"}];}else if(type==="patch-set"){b.patches=[{id:"new-patch",title:title||"New patch"}];}else if(type==="verification-run"){b.runs=[{id:"new-run",title:title||"New run"}];}else if(type==="release-checklist"){b.gates=[{id:"new-gate",title:title||"New gate",required:true,status:"todo"}];}return b;}
function renderStaticBlockEditor(){var list=$("[data-block-editor-list]");if(!list)return;list.innerHTML="";(model.blocks||[]).forEach(function(b,i){var row=document.createElement("div");row.className="ds-blockedit-row";var label=document.createElement("b");label.textContent=(b.title||b.heading||b.type||"block")+" · "+(b.id||("index "+i));var up=document.createElement("button"),down=document.createElement("button"),del=document.createElement("button");[up,down,del].forEach(function(btn){btn.className="ds-btn ds-btn-line";btn.type="button";});up.textContent="Up";down.textContent="Down";del.textContent="Delete";up.disabled=i===0;down.disabled=i===(model.blocks||[]).length-1;row.appendChild(label);row.appendChild(up);row.appendChild(down);row.appendChild(del);up.addEventListener("click",function(){var x=model.blocks[i-1];model.blocks[i-1]=model.blocks[i];model.blocks[i]=x;markDirty();renderStaticBlockEditor();});down.addEventListener("click",function(){var x=model.blocks[i+1];model.blocks[i+1]=model.blocks[i];model.blocks[i]=x;markDirty();renderStaticBlockEditor();});del.addEventListener("click",function(){model.blocks.splice(i,1);markDirty();renderStaticBlockEditor();});list.appendChild(row);});var note=$("[data-block-editor-status]");if(note)note.textContent="Download merged JSON to persist structural changes, then rebuild.";window.__DOSSIER_MODEL__=model;}
function openBlockEditor(){var m=$("[data-block-editor-modal]");if(!m)return;renderStaticBlockEditor();showLayer(m,$("[data-tool-close]",m));}
function openEvidencePanel(){var m=$("[data-evidence-modal]");if(!m)return;showLayer(m,$("[data-evidence-title]",m));}
function addEvidenceFromForm(){state.evidence=state.evidence||{};var title=($("[data-evidence-title]")||{}).value||"Evidence";var id=slugifyClient(($("[data-evidence-id]")||{}).value||title);state.evidence[id]={title:title,kind:($("[data-evidence-kind]")||{}).value||"note",source:($("[data-evidence-source]")||{}).value||"",trust:($("[data-evidence-trust]")||{}).value||"medium",body:($("[data-evidence-body]")||{}).value||"",created:nowIso()};save();markDirty();toast("Evidence attached");closeToolModal("[data-evidence-modal]");}
function compareRevisionFile(file){var r=new FileReader();r.onload=function(){try{var other=JSON.parse(r.result),diff=diffModelsClient(other,mergeCurrentState());var out=$("[data-revision-result]");if(out)out.value=statefulJson(diff);setPreview("Revision diff",statefulJson(diff));toast("Revision compared");}catch(e){toast("Compare failed");}};r.readAsText(file);}
function importStateFile(file){var r=new FileReader();r.onload=function(){try{applyStatePacket(JSON.parse(r.result));}catch(e){toast("State import failed");}};r.readAsText(file);}
$$("[data-export-kind]").forEach(function(btn){btn.addEventListener("click",function(){var k=btn.getAttribute("data-export-kind");if(k==="source")setPreview("Source JSON",sourceModelJson());else if(k==="state")setPreview("Current state packet",statefulJson(collectStatePacket()));else if(k==="merged")setPreview("Merged Dossier JSON",statefulJson(mergeCurrentState()));else if(k==="handoff")setPreview("Agent handoff packet",statefulJson(handoffPacket()));else if(k==="prompt")setPreview("AI authoring prompt",promptText());});});