File size: 120,716 Bytes
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0dbbc41
2aa8b3a
 
 
 
0dbbc41
 
 
 
 
 
 
2aa8b3a
 
0dbbc41
 
 
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9535829
 
2aa8b3a
0dbbc41
 
 
 
 
 
 
2aa8b3a
0dbbc41
 
 
 
 
 
 
 
 
 
 
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38cbc41
 
 
0dbbc41
1d4a48e
 
 
 
 
0dbbc41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d4a48e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38cbc41
 
2aa8b3a
 
 
9535829
2aa8b3a
 
 
 
 
0dbbc41
 
 
 
 
 
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
0dbbc41
 
2aa8b3a
 
 
 
0dbbc41
 
 
 
 
 
2aa8b3a
0dbbc41
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
4d2b94b
2aa8b3a
 
 
 
10528d6
2aa8b3a
 
 
 
 
 
 
 
4d2b94b
2aa8b3a
 
 
10528d6
 
 
2aa8b3a
 
4d2b94b
0dbbc41
 
 
10528d6
0dbbc41
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
 
 
10528d6
2aa8b3a
 
 
 
10528d6
2aa8b3a
10528d6
 
2aa8b3a
 
 
 
 
 
 
10528d6
2aa8b3a
10528d6
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0dbbc41
 
 
4d2b94b
0dbbc41
9bb9cc0
 
 
 
 
dada16c
 
 
 
 
 
 
 
 
 
0dbbc41
10528d6
0dbbc41
9bb9cc0
2aa8b3a
10528d6
dada16c
 
 
 
2aa8b3a
9bb9cc0
10528d6
 
 
 
 
 
dada16c
 
2aa8b3a
10528d6
0dbbc41
9bb9cc0
 
 
 
2aa8b3a
10528d6
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
4d2b94b
2aa8b3a
 
10528d6
 
 
 
 
4d2b94b
2aa8b3a
 
 
 
 
 
 
 
 
 
10528d6
 
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
10528d6
2aa8b3a
10528d6
2aa8b3a
10528d6
4d2b94b
2aa8b3a
 
10528d6
2aa8b3a
10528d6
 
2aa8b3a
10528d6
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
10528d6
 
2aa8b3a
 
 
10528d6
2aa8b3a
 
10528d6
2aa8b3a
 
 
10528d6
4d2b94b
2aa8b3a
 
 
 
 
 
 
 
10528d6
 
2aa8b3a
0dbbc41
 
 
10528d6
2aa8b3a
 
10528d6
4d2b94b
2aa8b3a
 
 
4d2b94b
 
10528d6
2aa8b3a
0dbbc41
 
 
 
 
 
 
 
 
 
 
4d2b94b
0dbbc41
 
10528d6
0dbbc41
 
 
10528d6
0dbbc41
4d2b94b
0dbbc41
 
 
 
 
10528d6
0dbbc41
10528d6
0dbbc41
 
 
 
 
10528d6
0dbbc41
 
 
 
 
 
10528d6
0dbbc41
10528d6
 
0dbbc41
 
4d2b94b
0dbbc41
 
 
 
 
4d2b94b
0dbbc41
10528d6
0dbbc41
 
 
 
 
 
 
10528d6
 
 
0dbbc41
 
4d2b94b
0dbbc41
 
10528d6
0dbbc41
10528d6
0dbbc41
 
2aa8b3a
 
10528d6
2aa8b3a
 
 
 
 
 
 
10528d6
 
2aa8b3a
 
 
 
 
 
 
10528d6
 
2aa8b3a
 
10528d6
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
10528d6
 
 
2aa8b3a
26a7c18
 
 
 
 
10528d6
 
4d2b94b
2aa8b3a
10528d6
2aa8b3a
 
 
 
 
10528d6
2aa8b3a
 
 
4d2b94b
10528d6
2aa8b3a
10528d6
 
2aa8b3a
10528d6
2aa8b3a
10528d6
2aa8b3a
 
 
 
 
10528d6
2aa8b3a
 
 
 
 
 
10528d6
2aa8b3a
 
 
 
 
4d2b94b
 
2aa8b3a
 
 
 
 
 
10528d6
 
 
2aa8b3a
10528d6
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
4d2b94b
2aa8b3a
 
 
 
 
 
 
 
 
 
4d2b94b
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
4d2b94b
2aa8b3a
 
4d2b94b
2aa8b3a
 
10528d6
2aa8b3a
10528d6
2aa8b3a
10528d6
2aa8b3a
 
 
 
 
 
 
10528d6
2aa8b3a
 
 
 
4d2b94b
10528d6
2aa8b3a
 
 
 
 
 
 
4d2b94b
2aa8b3a
 
10528d6
 
2aa8b3a
 
 
 
 
 
4d2b94b
2aa8b3a
 
10528d6
 
 
 
 
2aa8b3a
 
10528d6
 
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
 
 
 
 
 
 
10528d6
 
2aa8b3a
 
10528d6
 
 
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
2aa8b3a
4d2b94b
2aa8b3a
10528d6
2aa8b3a
 
 
10528d6
4d2b94b
2aa8b3a
 
10528d6
 
9bb9cc0
fabf319
 
 
 
 
 
 
9bb9cc0
 
 
 
 
1d4a48e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9bb9cc0
 
 
 
 
 
 
 
 
10528d6
9bb9cc0
 
 
 
10528d6
9bb9cc0
2aa8b3a
 
4d2b94b
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d2b94b
2aa8b3a
 
 
10528d6
 
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d2b94b
2aa8b3a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0dbbc41
 
2aa8b3a
 
0dbbc41
 
2aa8b3a
 
 
 
 
 
 
3d4d5f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9bb9cc0
 
3d4d5f0
 
 
38cbc41
 
0dbbc41
 
 
 
 
 
 
10528d6
0dbbc41
10528d6
0dbbc41
 
10528d6
 
0dbbc41
 
 
10528d6
 
0dbbc41
 
38cbc41
0dbbc41
4d2b94b
0dbbc41
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
0dbbc41
 
 
10528d6
0dbbc41
 
9535829
 
 
 
 
 
38cbc41
9535829
 
1d4a48e
38cbc41
 
1d4a48e
 
 
 
 
0dbbc41
38cbc41
 
10528d6
 
 
38cbc41
10528d6
0dbbc41
10528d6
38cbc41
 
 
10528d6
38cbc41
1d4a48e
 
 
 
 
 
 
 
 
 
 
0dbbc41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38cbc41
 
 
 
 
 
 
 
0dbbc41
 
 
 
 
 
 
38cbc41
 
 
 
 
 
 
9bb9cc0
 
 
 
 
 
 
 
38cbc41
4d2b94b
38cbc41
0dbbc41
 
 
 
9bb9cc0
 
 
 
 
 
 
0dbbc41
10528d6
 
4d2b94b
 
 
 
 
 
 
 
 
9bb9cc0
 
 
 
 
 
 
38cbc41
 
 
 
 
 
ce6b652
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38cbc41
 
 
 
 
0dbbc41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d2b94b
0dbbc41
 
 
4d2b94b
0dbbc41
 
10528d6
0dbbc41
10528d6
0dbbc41
 
 
 
 
 
 
 
 
 
 
 
 
 
10528d6
0dbbc41
 
 
 
 
4d2b94b
0dbbc41
 
 
 
4d2b94b
0dbbc41
10528d6
 
0dbbc41
 
 
 
 
 
 
 
 
10528d6
0dbbc41
4d2b94b
10528d6
0dbbc41
38cbc41
9535829
 
 
 
38cbc41
0dbbc41
 
38cbc41
9535829
 
 
 
2aa8b3a
9535829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
"""The stylesheet and the palette. Markup lives in :mod:`distinct_server.render`.

One sheet, real tokens, semantic class names, no inline styles. Everything the
product looks like is decided here or in ``render.py``; nothing is decided by
Gradio's generated DOM, which is why the sheet opens by switching most of that
DOM off.

Two constraints outrank every aesthetic decision.

**1. Polish must not launder a missing measurement into a real one.**
An unmeasured run renders with a dash and the words "No data"; it can never
render as ``0`` or ``0.000 J``. An incomplete session total states how many runs
it covers. The two rubric boundaries are separate ``.c-panel`` surfaces, each
carrying an explicit "never added" line, because making them look like one tidy
summary is the exact misreading the rubric forbids. The same rule governs the
grade sheet: ``.c-grade--none`` is a dashed lozenge carrying words, never a
letter, because an absence drawn as a D is a measured poor result that nobody
measured.

**2. WCAG AA, computed rather than assumed.**
Contrast against the canvas ``#FAF9F5``:

===============  =========  ======  ==========================================
Colour           Ratio      AA?     Used for
===============  =========  ======  ==========================================
``#1F1E1A``      15.6:1     pass    body text
``#504D45``      7.6:1      pass    secondary text
``#6C6961``      4.6:1      pass    muted text
``#174F37``      9.3:1      pass    accent text
``#1E6E4B``      6.0:1*     pass    primary button (*white on it: 6.2:1)
``#4E7561``      4.2:1      FAIL    borders, strokes, 24px+ only
``#5E8A73``      3.2:1      FAIL    decorative fill only
===============  =========  ======  ==========================================

The two lighter greens fail AA for body text, so neither is ever used for
body text. Every neutral is warm-grey over ivory; green appears only where
it means something (the action, the selection, the focus).

**Layout: the shell decides its own height.**
The previous sheet locked ``.gradio-container`` and ``.c-shell`` to ``100vh``
with ``overflow:hidden``, then gave ``.c-main`` ``flex:1``. Every pixel of
unused viewport therefore drained into whichever child was allowed to grow,
which is why an empty transcript rendered as an 890px void with three lines of
type floating in the middle of it. Nothing was deciding a height; the viewport
was, and the layout absorbed the difference.

Now the shell is ``min-height:100vh`` in normal document flow, ``.c-main`` is a
two-column grid sized by its content, and the transcript carries an explicit
height range. Leftover viewport falls below the page where it belongs. Every
direct child of ``.c-shell`` shares one padding box, so the header, the notice,
both columns and the tail sit on a single pair of vertical edges rather than the
four the layout had grown.
"""

from __future__ import annotations

import re

PALETTE = {
    # A warm paper ground with exactly one accent. The previous sheet tinted
    # the canvas, the borders, the fills and the pills green all at once, and
    # four tinted neutrals beside one another read as a colour scheme fighting
    # itself. Now the neutrals are neutral (warm greys over an ivory ground)
    # and green appears only where it means something: the primary action,
    # the selected state, the focus ring.
    "canvas": "#FAF9F5",
    "surface": "#FFFFFF",
    "mint": "#E8F0EA",  # selection tint, the only coloured fill
    "sage": "#5E8A73",  # decorative strokes over 24px
    "sage_dark": "#4E7561",
    "border": "#D8D3C7",
    "text": "#1F1E1A",
    "muted": "#6C6961",
    # Accessible shades of the accent; see the table above.
    "sage_deep": "#174F37",
    "sage_button": "#1E6E4B",
    "text_secondary": "#504D45",
    "hairline": "#EAE7DF",
}

# Loaded via launch(head=...) so the font arrives before first paint rather than
# through Gradio's own font machinery.
#
# Both faces are variable and both carry an optical-size axis, which is the
# point: the splash sets its display line with ``font-optical-sizing:auto`` at a
# ``clamp()`` size, so the letterforms are redrawn for the size rather than
# photographically scaled up. Swap which ``--font-display`` line is live in the
# token block below to compare the two.
HEAD = """
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400..800&display=swap">
<link rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400..700&display=swap">

<script>
(function(){
  function card(el){return el && el.closest ? el.closest('.c-libcard') : null;}
  /* The preview machinery that lived here β€” hover to swap in a GIF, press and
     hold to do the same on a phone, plus the flag that stopped a long press
     also counting as a tap β€” went with the GIFs. Each card now draws what its
     member makes, so there is nothing to reveal and nothing to time. */

  /* THE CARD IS THE CONTROL, and the way it saves is by forwarding its click
     to the framework's own box for that member. Writing a hidden field's
     value and dispatching an input event was tried first: it updates the DOM
     and never reaches the server, because the framework listens to its own
     binding rather than to the element. Clicking its control cannot drift
     from it. The boxes are labelled with the bare reference, so the mapping
     is an exact string rather than a position two lists could disagree on. */
  function boxFor(ref){
    var group = document.getElementById('library-choice');
    if(!group) return null;
    var labels = group.querySelectorAll('label');
    for(var i=0;i<labels.length;i++){
      if((labels[i].textContent||'').trim() === ref){
        return labels[i].querySelector('input[type=checkbox]');
      }
    }
    return null;
  }
  document.addEventListener('click', function(e){
    var c = card(e.target);
    if(!c || !c.hasAttribute('data-ref')) return;
    if(e.target.closest && e.target.closest('a')) return;
    var box = boxFor(c.getAttribute('data-ref'));
    if(!box) return;   /* no transport, no pretend selection */
    /* Paint first so the card answers the tap immediately; the count catches
       up when the save returns. */
    c.classList.toggle('is-on');
    c.setAttribute('aria-pressed', c.classList.contains('is-on') ? 'true' : 'false');
    box.click();
  });
  document.addEventListener('keydown', function(e){
    if(e.key !== ' ' && e.key !== 'Enter') return;
    var c = card(e.target);
    if(!c || e.target !== c) return;
    e.preventDefault(); c.click();
  });
  /* COPY BUTTONS ON THE SETUP COMMANDS.
     The text comes out of the <pre> the button sits with, never out of an
     attribute written by the server. Two copies of a command line, one to
     read and one to copy, is one escaping mistake away from a clipboard that
     disagrees with the screen, and a command that looks right and pastes
     wrong is worse than no button at all. */
  function commandOf(btn){
    var block = btn.closest ? btn.closest('.c-cmd') : null;
    var src = block ? block.querySelector('pre, code') : null;
    return src ? (src.textContent || '').trim() : '';
  }
  /* execCommand is deprecated and is still the only thing that copies on a
     page that is not on a secure origin, which is where this panel is read:
     a worker joins a server on 192.168.x.x over plain http, and there
     navigator.clipboard does not exist. */
  function legacyCopy(text){
    var box = document.createElement('textarea');
    box.value = text; box.setAttribute('readonly','');
    box.style.position='fixed'; box.style.top='0'; box.style.opacity='0';
    document.body.appendChild(box);
    box.select(); box.setSelectionRange(0, text.length);
    var ok = false;
    try{ ok = document.execCommand('copy'); }catch(err){ ok = false; }
    box.remove();
    return ok;
  }
  /* A press that copied and a press that did nothing look identical unless
     the button says which happened, so it says, and it says "Copy failed"
     when it did rather than claiming a clipboard it never wrote. The command
     stays selectable by hand either way. */
  function flash(btn, word){
    var slot = btn.querySelector('.c-cmd__word') || btn;
    if(!btn.hasAttribute('data-word')) btn.setAttribute('data-word', slot.textContent);
    slot.textContent = word;
    btn.classList.add('is-copied');
    clearTimeout(btn.copyTimer);
    btn.copyTimer = setTimeout(function(){
      slot.textContent = btn.getAttribute('data-word');
      btn.classList.remove('is-copied');
    }, 1600);
  }
  document.addEventListener('click', function(e){
    var btn = e.target.closest ? e.target.closest('.c-cmd__copy') : null;
    if(!btn) return;
    e.preventDefault();
    var text = commandOf(btn);
    if(!text) return;
    if(navigator.clipboard && navigator.clipboard.writeText){
      navigator.clipboard.writeText(text).then(
        function(){ flash(btn, 'Copied'); },
        function(){ flash(btn, legacyCopy(text) ? 'Copied' : 'Copy failed'); });
    } else {
      flash(btn, legacyCopy(text) ? 'Copied' : 'Copy failed');
    }
  });
})();
</script>
"""


_SHEET = """
/* ========================================================================
   TOKENS
   ==================================================================== */
:root{
  /* colour */
  --c-canvas:#FAF9F5; --c-surface:#FFFFFF; --c-mint:#E8F0EA;
  --c-sage:#5E8A73; --c-sage-dark:#4E7561; --c-sage-deep:#174F37;
  --c-accent:#1E6E4B; --c-accent-hover:#185C3E;
  --c-text:#1F1E1A; --c-text-2:#504D45; --c-muted:#6C6961;
  --c-hairline:#EAE7DF; --c-border:#D8D3C7; --c-fill:#F4F1EA;
  --c-warn-bg:#FBF6E8; --c-warn-rule:#7A6420;

  /* spacing: 4px base, no value outside this scale */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px;
  --s7:48px; --s8:64px;

  /* type scale: five steps, each visibly distinct from its neighbours */
  --t-display:21px; --t-lg:17px; --t-body:15px; --t-label:13px; --t-micro:11.5px;
  --lh-body:1.55; --lh-tight:1.3;

  /* radius: two values across the whole app, plus the pill */
  --r-md:12px; --r-lg:16px; --r-pill:999px;

  /* elevation: two levels */
  --e1:0 1px 2px rgba(35,32,26,.05);
  --e2:0 8px 28px -12px rgba(35,32,26,.16);

  --font:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* DISPLAY FACE. Option B is live: the serif display over a warm paper
     ground is what carries the editorial, Anthropic-adjacent register; the
     sans stays for everything set smaller than a title. Swap the live line
     to compare; nothing else in the sheet changes. */
  /* --font-display:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; */ /* A */
  --font-display:'Fraunces','Iowan Old Style',Georgia,serif;                           /* B */

  --c-focus:rgba(30,110,75,.4);
  --measure:68ch;

  /* One shell geometry, referenced by every top-level block so there is
     exactly one left edge and one right edge on the page. */
  --shell-max:1140px;
  --shell-pad:var(--s5);
  /* Three columns, in the order a chat product reads. The leftmost rail is
     conversations and nothing else, which is the whole point of it: mixing
     the run controls in there made it a settings panel that happened to
     contain a history. */
  --rail-col:224px;
  --side-col:312px;
  --col-gap:var(--s5);
}

/* ========================================================================
   SWITCH OFF GRADIO'S CHROME
   ==================================================================== */
html,body{margin:0;}
.gradio-container,.gradio-container *{font-family:var(--font);}
.gradio-container{
  max-width:none !important; padding:0 !important;
  background:var(--c-canvas) !important; color:var(--c-text) !important;
  font-size:var(--t-body); line-height:var(--lh-body);
  letter-spacing:-.006em;
}
.gradio-container>.main,.gradio-container>.main>.wrap,.gradio-container .contain{
  max-width:none !important;
}
.gradio-container .block,.gradio-container .form,.gradio-container .panel,
.gradio-container .gradio-group,.gradio-container .gradio-box{
  background:transparent !important; border:none !important;
  box-shadow:none !important; border-radius:0 !important; padding:0 !important;
}
.gradio-container .gap,.gradio-container .form{gap:var(--s2) !important;}
footer,.gradio-container footer{display:none !important;}
.gradio-container label>span:empty{display:none !important;}

/* ========================================================================
   APP SHELL
   One padding box, shared by every direct child. Normal document flow: the
   shell fills the viewport at minimum and grows past it when the content
   needs to, rather than clipping at 100vh and pushing the difference into
   whichever child happened to be allowed to stretch.
   ==================================================================== */
.c-shell{
  max-width:var(--shell-max) !important; width:100% !important;
  margin:0 auto !important; min-height:100vh !important;
  padding:var(--s5) var(--shell-pad) var(--s7) !important;
  display:flex !important; flex-direction:column !important;
  gap:var(--s5) !important;
}
.c-shell>*{margin:0 !important; width:100% !important;}

/* Content-sized, not viewport-sized. This single declaration is what stops
   the transcript inheriting every spare pixel on a tall screen. */
.c-main{
  flex:0 0 auto !important;
  display:grid !important;
  grid-template-columns:var(--rail-col) minmax(0,1fr) var(--side-col) !important;
  gap:var(--col-gap) !important;
  align-items:stretch !important;
}

/* ========================================================================
   CONVERSATION RAIL
   Conversations, and only conversations, down the left.
   ==================================================================== */
.c-rail{
  order:1 !important;
  min-width:0 !important; align-self:stretch !important;
  display:flex !important; flex-direction:column !important;
  gap:var(--s2) !important;
  border-right:1px solid var(--c-hairline) !important;
  padding-right:var(--s4) !important;
}
.c-rail__list{flex:1 1 auto !important; min-height:0 !important;
              overflow-y:auto !important; margin:0 -4px !important;
              padding:0 4px var(--s3) !important;}
.c-rail__list::-webkit-scrollbar{width:6px;}
.c-rail__list::-webkit-scrollbar-thumb{background:var(--c-border); border-radius:3px;}
.c-rail__list::-webkit-scrollbar-track{background:transparent;}

/* ========================================================================
   TYPE
   ==================================================================== */
.c-eyebrow{
  display:flex; align-items:baseline; justify-content:space-between; gap:var(--s2);
  font-size:var(--t-micro); font-weight:600; letter-spacing:.09em;
  text-transform:uppercase; color:var(--c-muted) !important;
  margin:var(--s4) 0 var(--s2); padding-bottom:var(--s2);
  border-bottom:1px solid var(--c-hairline) !important;
}
.c-side>*:first-child .c-eyebrow,.c-eyebrow:first-child{margin-top:0;}
.c-eyebrow__note{text-transform:none; letter-spacing:0; font-weight:400;}
.c-note{display:flex; align-items:flex-start; gap:var(--s2); flex-wrap:wrap;
        margin:0; font-size:var(--t-micro); color:var(--c-muted) !important;}
.c-note__text{max-width:var(--measure); line-height:1.5;}

/* ========================================================================
   HEADER
   ==================================================================== */
.c-header{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--s4); min-height:34px;
  padding-bottom:var(--s3); border-bottom:1px solid var(--c-hairline) !important;
}
.c-header__brand{display:flex; align-items:baseline; gap:var(--s3); min-width:0;}
.c-wordmark{font-size:var(--t-display); font-weight:700; letter-spacing:-.045em;
            line-height:1; color:var(--c-text) !important; white-space:nowrap;}
.c-wordmark__dot{color:var(--c-sage-dark) !important;}
.c-tagline{font-size:var(--t-label); font-weight:400; color:var(--c-text-2) !important;
           line-height:1; white-space:nowrap; overflow:hidden;
           text-overflow:ellipsis; padding-left:var(--s3);
           border-left:1px solid var(--c-hairline) !important;}
/* Who you are, said quietly. This was a floating white pill with a shadow,
   which gave the top of the page a second object competing with the
   wordmark for the eye; it is a caption, so it is set like one. */
.c-identity{font-size:var(--t-micro); color:var(--c-muted) !important; white-space:nowrap;
            overflow:hidden; text-overflow:ellipsis; max-width:38ch;}
.c-identity--link{text-decoration:underline; cursor:pointer;}

/* ========================================================================
   SPLASH
   Two columns on a wide screen, image first on a narrow one. The display
   line is set at a fluid size with the browser choosing the optical size,
   so the letterforms are drawn for the size rather than scaled to it.
   ==================================================================== */
.c-splash-view{
  max-width:var(--shell-max) !important; width:100% !important;
  margin:0 auto !important; padding:var(--s7) var(--shell-pad) var(--s6) !important;
  min-height:100vh !important;
  display:flex !important; flex-direction:column !important;
  justify-content:center !important;
}
/* Two real grid tracks with a zero minimum, for the same reason the app shell
   uses them: a track that cannot be overflowed cannot push the page sideways. */
.c-splash{
  display:grid !important; gap:var(--s8) var(--s7) !important;
  grid-template-columns:minmax(0,1.05fr) minmax(0,1fr) !important;
  align-items:center !important; flex-wrap:nowrap !important;
}
.c-splash__copy{display:flex !important; flex-direction:column !important;
                align-items:flex-start !important; gap:var(--s4) !important;
                min-width:0 !important;}
.c-splash__plate{min-width:0 !important;}
.c-splash__head{display:flex; flex-direction:column; align-items:flex-start;
                gap:var(--s4);}
.c-splash__mark{margin:0; font-size:var(--t-display); font-weight:700;
                letter-spacing:-.045em; line-height:1; color:var(--c-text) !important;}
.c-splash__display{
  margin:0; font-family:var(--font-display);
  font-size:clamp(2.6rem,1.1rem + 4.6vw,4.6rem);
  line-height:1.02; letter-spacing:-.035em; color:var(--c-text) !important;
  font-weight:680; font-optical-sizing:auto; text-wrap:balance;
}
/* The second line carries the claim, so it is the one that changes colour and
   weight. Sage-deep at 9.2:1 clears AA comfortably at any size. */
.c-splash__display-2{color:var(--c-sage-deep) !important; font-weight:560;}
.c-splash__lede{margin:0; max-width:46ch; font-size:var(--t-lg);
                line-height:1.5; color:var(--c-text-2) !important;}
.c-splash__meta{margin:0; font-size:var(--t-micro); color:var(--c-muted) !important;
                letter-spacing:.02em;}
.c-splash__figure{margin:0; display:flex; flex-direction:column; gap:var(--s3);
                  min-width:0;}
.c-splash__img{display:block; width:100%; height:auto; border-radius:var(--r-lg);
               box-shadow:var(--e2);}
/* The credit sits beside the image it belongs to and is never collapsed
   behind a control. It is a licence condition, not a caption. */
.c-splash__credit{font-size:var(--t-micro); line-height:1.5; color:var(--c-muted) !important;
                  max-width:52ch;}
.c-splash__credit a{color:var(--c-sage-deep) !important; text-decoration:underline;}
.c-splash__copy button.primary{
  min-width:190px !important; padding:12px 22px !important;
  font-size:var(--t-body) !important; flex:0 0 auto !important;
}
@media (max-width:900px){
  .c-splash{grid-template-columns:minmax(0,1fr) !important; gap:var(--s6) !important;}
  .c-splash__plate{order:-1;}
}
/* One settle on the display line, and nothing else moves. Removed entirely
   under a reduced-motion preference by the block at the end of the sheet. */
@keyframes c-settle{from{opacity:0; transform:translateY(6px);} to{opacity:1; transform:none;}}
.c-splash__display,.c-splash__lede{animation:c-settle .5s cubic-bezier(.22,.61,.36,1) both;}
.c-splash__lede{animation-delay:.08s;}

/* ========================================================================
   NOTICE
   ==================================================================== */
/* A caution, not an alarm: paper surface and a hairline, with the mark the
   only saturated pixel. The previous amber flood shouted over the page and
   was the loudest colour on it. */
.c-notice{background:var(--c-surface); border:1px solid var(--c-hairline) !important;
          border-radius:var(--r-md); padding:var(--s3) var(--s4);}
/* The mark belongs to the sentence, so it must never be able to wrap away
   from it. On a phone the row wrapped into three lines and left a bare "!"
   floating above the text like a rendering fault. The mark and the sentence
   are now one non-breaking pair that shrinks together; only the "What is
   kept" toggle is allowed to drop to its own line. */
/* `display` IS `!important` HERE, AND THAT IS NOT LAZINESS.
   Gradio ships `.gradio-container-6-24-0 summary{display:list-item}` β€” an
   element selector inside a version-stamped class, which outranks any single
   class of ours and whose name changes with every release, so it cannot be
   matched or overridden by specificity that survives an upgrade. Until this
   was forced, this rule had simply never applied: the row was never a flex
   container at all. It went unnoticed while the children happened to be
   inline, and became visible the moment the mark was given a box of its own,
   which a non-flex parent then put on a line of its own. */
.c-notice__summary{display:flex !important; align-items:flex-start; gap:var(--s3);
                   flex-wrap:wrap; cursor:pointer; list-style:none;
                   font-size:var(--t-label); color:var(--c-text-2) !important;
                   line-height:1.5;}
.c-notice__summary>span:nth-child(2){flex:1 1 180px; min-width:0;}
.c-notice__summary::-webkit-details-marker{display:none;}
.c-notice__summary strong{color:var(--c-text) !important; font-weight:600 !important;}
/* inline-grid, not grid: a block-level box in a row that failed to become a
   flex container takes the whole line to itself, which is exactly how this
   mark ended up stranded above its own sentence. Inline-grid centres the
   glyph just as well and cannot claim a line. */
.c-notice__mark{flex:none; width:16px; height:16px; border-radius:50%;
                margin-top:2px;
                border:1.5px solid var(--c-warn-rule) !important;
                /* Forced for the same reason as the border: gradio paints
                   everything inside `.prose` with the body ink at a
                   specificity ours cannot reach, which left an ochre ring
                   around a black glyph. */
                color:var(--c-warn-rule) !important;
                font-size:10px; font-weight:700;
                display:inline-grid; place-items:center;}
.c-notice__toggle{margin-left:auto; white-space:nowrap; font-size:var(--t-micro);
                  color:var(--c-muted) !important; text-decoration:underline;
                  text-underline-offset:2px; padding-left:var(--s3);}
@media (max-width:700px){
  /* Its own line, aligned with the sentence it opens rather than the mark. */
  .c-notice__toggle{flex:1 0 100%; margin:var(--s2) 0 0 28px; padding-left:0;}
}
.c-notice__body{margin:var(--s3) 0 var(--s1) 28px; font-size:var(--t-micro);
                line-height:1.6; color:var(--c-text-2) !important; max-width:var(--measure);}
.c-notice__summary:focus-visible{outline:3px solid var(--c-sage); outline-offset:3px;
                                 border-radius:var(--r-md);}

/* ========================================================================
   SIDEBAR
   A grid item, so its box is the full height of the row. The credit is
   pinned to the bottom of that box, which is what closes the gap that used
   to sit under the energy panel and aligns the two columns' bottom edges.
   ==================================================================== */
/* Third column. The DOM keeps the rail and the side panel adjacent because
   they are both chrome; the grid puts the conversation between them, which is
   where a reader expects it. */
.c-side{
  order:3 !important;
  min-width:0 !important; align-self:stretch !important;
  display:flex !important; flex-direction:column !important;
  gap:var(--s2) !important;
}
/* THE HOLE IN THE RIGHT COLUMN.

   Gradio puts ``auto-margin`` on most blocks, which resolves to ``margin:auto``.
   On a flex item that is not a neutral default: free space along the main axis
   is handed to auto margins before it is handed to anything else, and this
   column is a flex column, so every block took a share of whatever the taller
   middle column had left over. The symptom was a gap that moved: about 8px on
   an empty page, and about 200px of nothing between the worker picker and the
   worker card once a conversation had made the middle column tall. Nothing was
   missing and nothing was broken, which is why it read as sloppiness rather
   than as a fault.

   The gap between blocks is this column's own ``gap``, and it is the same
   whatever is beside it. The credit keeps its ``margin-top:auto`` because
   pinning it to the bottom is deliberate. */
.c-side>*,.c-rail>*{margin-top:0 !important; margin-bottom:0 !important;}
.c-side__credit{margin-top:auto !important; padding-top:var(--s5) !important;}

/* ========================================================================
   CHIPS
   ==================================================================== */
.c-chips{display:flex; flex-wrap:wrap; gap:6px; align-items:center;}
.c-chip{
  display:inline-flex; align-items:center; gap:5px;
  height:22px; padding:0 9px; border-radius:var(--r-pill);
  font-size:var(--t-micro); line-height:1; white-space:nowrap;
  background:var(--c-fill); color:var(--c-text-2) !important;
  border:1px solid transparent !important;
}
.c-chip__glyph{font-size:8px; line-height:1;}
.c-chip--ok{background:var(--c-mint); color:#22402C !important;}
.c-chip--work{background:#E7EFE2; color:var(--c-sage-deep) !important;}
.c-chip--warn{background:#F5EDDB; color:#5A4512 !important;}
.c-chip--off{background:#ECEDEA; color:#454A45 !important;}
.c-chip--outline{background:transparent; color:var(--c-muted) !important;
                 border:1px dashed var(--c-border) !important;}

/* ========================================================================
   WORKER CARDS
   ==================================================================== */
.c-workers{display:flex; flex-direction:column; gap:var(--s2);}
.c-worker{background:var(--c-surface); border-radius:var(--r-md);
          padding:var(--s3); box-shadow:var(--e1);}
.c-worker--offline{opacity:.7;}
.c-worker__name{display:flex; align-items:baseline; gap:var(--s2); flex-wrap:wrap;
                margin:0 0 var(--s2); font-size:var(--t-label); font-weight:600;
                color:var(--c-text) !important; min-width:0; overflow-wrap:anywhere;}
.c-worker__id{font-family:var(--mono); font-size:10.5px; color:var(--c-muted) !important;
              font-weight:400; overflow-wrap:anywhere;}
/* An agent name, hostname or model id is chosen on someone else's machine. It
   is escaped on the way in by render.esc, which stops it becoming markup, but
   a 400-character unbroken name would still be able to widen the column and
   push the layout sideways. It cannot set the width of anything. */
.c-worker,.c-workers{min-width:0; max-width:100%;}
.c-chip{max-width:100%; overflow:hidden; text-overflow:ellipsis;}

/* ========================================================================
   PANELS: one rubric boundary each, never summed
   ==================================================================== */
.c-panel{background:var(--c-surface); border-radius:var(--r-md);
         padding:var(--s4); box-shadow:var(--e1);}
.c-panel__head{display:flex; align-items:baseline; justify-content:space-between;
               gap:var(--s2); margin:0 0 var(--s3);}
.c-panel__title{font-size:var(--t-label); font-weight:600; color:var(--c-text) !important;}
.c-panel__boundary{font-size:10.5px; font-weight:600; letter-spacing:.07em;
                   text-transform:uppercase; color:var(--c-muted) !important; white-space:nowrap;}
.c-panel__caveat{margin:var(--s3) 0 0; font-size:var(--t-micro); line-height:1.5;
                 color:var(--c-muted) !important;}
.c-panel__never{margin:var(--s3) 0 0; padding-top:var(--s3); font-size:var(--t-micro);
                line-height:1.5; color:var(--c-muted) !important;
                border-top:1px dashed var(--c-border) !important;}
.c-energy{display:flex; flex-direction:column; gap:var(--s1);}
.c-energy__value{margin:0; font-size:var(--t-body); font-weight:600;
                 color:var(--c-text) !important; font-variant-numeric:tabular-nums;}
/* An absence is marked, never numeric. */
.c-energy__value--absent{color:var(--c-text-2) !important; font-weight:500;}
.c-energy__dash{font-family:var(--mono); color:var(--c-muted) !important; padding-right:6px;}
.c-energy__line{margin:0; font-size:var(--t-micro); line-height:1.5;
                color:var(--c-text-2) !important;}

/* ========================================================================
   GRADE SHEET
   A letter and an absence must not be confusable at a glance, so they differ
   in shape, fill, case and wording. Every letter renders identically to
   every other: there is no green A and no red D, because colour-coding the
   letters would say "high letter, low impact", which is the exact misreading
   the legend exists to prevent.
   ==================================================================== */
.c-rubric{display:flex; flex-direction:column; gap:var(--s4);}
.c-legend{background:var(--c-fill); border-radius:var(--r-md); padding:var(--s4);}
.c-legend__title{margin:0 0 var(--s2); font-size:var(--t-label); font-weight:600;
                 color:var(--c-text) !important;}
.c-legend__body{margin:0; font-size:var(--t-label); line-height:1.55;
                color:var(--c-text-2) !important; max-width:var(--measure);}
.c-legend__body strong{color:var(--c-text) !important; font-weight:600;}
.c-legend__example{display:flex; gap:var(--s2); align-items:flex-start;
                   margin:var(--s3) 0 0; padding:var(--s3);
                   background:var(--c-surface); border-radius:var(--r-md);
                   font-size:var(--t-micro); line-height:1.55; color:var(--c-text-2) !important;
                   max-width:var(--measure);}
.c-legend__example-mark{flex:none; width:16px; height:16px; border-radius:50%;
                        background:var(--c-sage-dark); color:#fff !important; font-size:11px;
                        font-weight:700; display:grid; place-items:center;
                        margin-top:1px;}
.c-legend__never{margin:var(--s3) 0 0; padding-top:var(--s3); font-size:var(--t-micro);
                 line-height:1.5; color:var(--c-muted) !important;
                 border-top:1px dashed var(--c-border) !important;}

.c-grade-cards{display:grid; gap:var(--s3);
               grid-template-columns:repeat(auto-fit,minmax(300px,1fr));}
.c-grade-card{background:var(--c-surface); border-radius:var(--r-md);
              padding:var(--s4); box-shadow:var(--e1);
              display:flex; flex-direction:column; gap:var(--s3);}
.c-grade-card__head{display:flex; align-items:baseline; justify-content:space-between;
                    gap:var(--s2); margin:0; flex-wrap:wrap;}
.c-grade-card__name{font-size:var(--t-body); font-weight:600; color:var(--c-text) !important;}
.c-grade-card__link{font-size:var(--t-micro); color:var(--c-sage-deep) !important;
                    text-decoration:underline; white-space:nowrap;}
/* Coverage sits in the card head, beside the name, because it qualifies the
   whole card. "three of six areas published" is not a score and must never be
   read as one, so it is set as quiet metadata rather than as a result. */
.c-grade-card__coverage{font-size:var(--t-micro); color:var(--c-text-2) !important;
                        font-variant-numeric:tabular-nums;}
.c-grade-card__note{margin:0; padding-top:var(--s3); font-size:var(--t-micro);
                    line-height:1.5; color:var(--c-muted) !important;
                    border-top:1px solid var(--c-hairline) !important;}
.c-grade-rows{display:flex; flex-direction:column; gap:var(--s1);}
.c-grade-row{display:flex; align-items:center; justify-content:space-between;
             gap:var(--s3); margin:0; padding:var(--s1) 0;
             border-bottom:1px solid var(--c-hairline) !important;}
.c-grade-row:last-child{border-bottom:none !important;}
.c-grade-row__label{font-size:var(--t-label); color:var(--c-text-2) !important;}

/* ONE TOKEN, NOT A NUMBER WITH A CAPTION.
   The figure and the method that produced it share a single border and a single
   overflow context, so there is no crop, no skim and no line break that can
   separate them. "54 MWh" metered at the socket and "54 MWh" inferred from a
   chip's rated wattage are different claims, and the word that tells them apart
   is inside the box rather than beside it.

   Method is told apart three ways at once: the word itself, the fill, and the
   border. Three signals because one is a heading away from being lost, and the
   palette has a single hue so colour cannot carry it alone. */
.c-fig{display:inline-flex; align-items:stretch; flex:none; line-height:1;
       border:1px solid var(--c-border) !important; border-radius:8px; overflow:hidden;
       font-variant-numeric:tabular-nums;}
.c-fig__value{display:flex; align-items:center; padding:6px 9px;
              font-size:var(--t-label); font-weight:600; color:#22402C !important;
              background:var(--c-mint); white-space:nowrap;}
.c-fig__method{display:flex; align-items:center; padding:0 8px;
               font-size:9.5px; font-weight:600; letter-spacing:.08em;
               text-transform:uppercase; color:var(--c-muted) !important;
               background:var(--c-surface);
               border-left:1px solid var(--c-border) !important; white-space:nowrap;}
/* A measured figure is the only one that gets the filled value. A modelled one
   is the same shape unfilled, because it is a real published number arrived at
   by calculation rather than by metering, and the difference should read at a
   glance without either being dressed as a fault. */
.c-fig--modelled .c-fig__value,
.c-fig--proxy .c-fig__value{background:var(--c-fill); color:var(--c-text) !important;}
.c-fig--unknown{border-style:dotted;}
.c-fig--unknown .c-fig__value{background:transparent; color:var(--c-text-2) !important;}
/* An absence is dashed, wordy and unfilled: it differs from a figure in shape,
   fill and content, because an absence drawn as a small number asserts a light
   result that nobody measured. */
.c-fig--none{border-style:dashed; background:transparent;}
.c-fig__word{display:flex; align-items:center; padding:6px 10px;
             font-size:var(--t-micro); font-weight:500; color:var(--c-muted) !important;
             white-space:nowrap;}

/* The card's own prose. Summary sits above the figures because a reader who
   stops after one paragraph should stop having read the caveat, not the
   headline number. */
.c-grade-card__summary{margin:0; font-size:var(--t-label); line-height:1.6;
                       color:var(--c-text-2) !important;}
.c-grade-card__covers{margin:0; font-size:var(--t-micro); line-height:1.55;
                      color:var(--c-muted) !important;}
.c-grade-card__covers strong{color:var(--c-text-2) !important; font-weight:600;}
.c-grade-card__links{display:flex; flex-wrap:wrap; gap:var(--s3); margin:0;
                     padding-top:var(--s3);
                     border-top:1px solid var(--c-hairline) !important;}

/* THE WORKING, ONE CLICK AWAY.
   Six notes and six citations on the face of the card bury the figures; hiding
   them makes the figures unverifiable. A disclosure is the only arrangement
   that is both complete and readable. */
.c-sources{border-top:1px solid var(--c-hairline) !important; padding-top:var(--s3);}
.c-sources__summary{cursor:pointer; font-size:var(--t-micro); font-weight:600;
                    letter-spacing:.04em; color:var(--c-sage-deep) !important;}
.c-sources__summary:focus-visible{outline:2px solid var(--c-sage);
                                  outline-offset:2px; border-radius:3px;}
.c-sources__body{display:flex; flex-direction:column; gap:var(--s2);
                 margin-top:var(--s3);}
.c-source{display:grid; grid-template-columns:minmax(88px,auto) 1fr;
          gap:var(--s1) var(--s3); margin:0; font-size:var(--t-micro);
          line-height:1.55;}
.c-source__label{color:var(--c-text-2) !important; font-weight:600;}
.c-source__body{color:var(--c-muted) !important;}
.c-source__link{color:var(--c-sage-deep) !important; text-decoration:underline;
                white-space:nowrap;}

.c-reading{padding-top:var(--s3); border-top:1px dashed var(--c-border) !important;}
.c-reading__title{margin:0 0 var(--s2); font-size:var(--t-micro); font-weight:600;
                  letter-spacing:.06em; text-transform:uppercase;
                  color:var(--c-muted) !important;}
.c-reading__links{display:flex; flex-direction:column; gap:var(--s1); margin:0;}
.c-reading__link{font-size:var(--t-micro); color:var(--c-sage-deep) !important;
                 text-decoration:underline;}

.c-rubric__warning{margin:0; padding:var(--s3); background:var(--c-mint);
                   border-radius:var(--r-md); font-size:var(--t-micro);
                   line-height:1.55; color:var(--c-text) !important;}

.c-legend__pair{display:grid; gap:var(--s3); margin:var(--s3) 0 0;
                grid-template-columns:repeat(auto-fit,minmax(260px,1fr));}
.c-legend__scale{display:flex; flex-direction:column; align-items:flex-start;
                 gap:var(--s2); padding:var(--s3); background:var(--c-surface);
                 border-radius:var(--r-md);}
.c-legend__scale-body{margin:0; font-size:var(--t-micro); line-height:1.55;
                      color:var(--c-text-2) !important;}
.c-legend__scale-body strong{color:var(--c-text) !important; font-weight:600;}

/* ========================================================================
   EMPTY STATES: no dashed drop-zone rectangles
   ==================================================================== */
.c-empty{display:flex; flex-direction:column; align-items:flex-start;
         justify-content:center; text-align:left; gap:var(--s2);
         padding:var(--s5) var(--s4); height:100%;}
.c-empty__glyph{font-size:16px; color:var(--c-sage-dark) !important; opacity:.75; line-height:1;}
.c-empty__title{margin:0; font-size:var(--t-lg); font-weight:600; color:var(--c-text) !important;
                letter-spacing:-.015em;}
.c-empty__body{margin:0; font-size:var(--t-label); line-height:1.55;
               color:var(--c-text-2) !important; max-width:44ch;}
.c-empty--compact{padding:var(--s4) 0; height:auto;}
.c-empty--compact .c-empty__body{max-width:32ch; font-size:var(--t-micro);}

/* ========================================================================
   CONVERSATION LIST
   A list, because a conversation history is a list. It was a dropdown, which
   hides every conversation but one behind a click and gives no sense of how
   much history exists. The component underneath is a Radio group: one
   selected item, keyboard reachable, announced correctly. Only its skin is
   a list.
   ==================================================================== */
.c-convlist{padding:0 !important; border:none !important; background:transparent !important;}
.c-convlist .wrap,.c-convlist fieldset{border:none !important; background:transparent !important;
                                       padding:0 !important; gap:2px !important;
                                       display:flex !important; flex-direction:column !important;}
.c-convlist label{
  display:flex !important; align-items:center !important; gap:var(--s2) !important;
  width:100% !important; margin:0 !important;
  padding:7px var(--s3) !important;
  border:1px solid transparent !important; border-radius:var(--r-md) !important;
  background:transparent !important; box-shadow:none !important;
  font-size:var(--t-micro) !important; color:var(--c-text) !important;
  cursor:pointer !important; transition:background .14s ease-out !important;
  overflow:hidden !important;
}
.c-convlist label>span{overflow:hidden !important; text-overflow:ellipsis !important;
                       white-space:nowrap !important; font-weight:400 !important;}
.c-convlist label:hover{background:var(--c-fill) !important;}
/* The radio dot is removed, not hidden from assistive technology: the input
   keeps its role and its focus ring, so the list is still a radio group to
   anything that is not a pair of eyes. */
.c-convlist input[type="radio"]{position:absolute !important; opacity:0 !important;
                                width:1px !important; height:1px !important;}
/* Fill alone marks the current conversation. It used to also take a green
   border, which gave it the same weight as the New conversation button
   directly above it, so the rail read as two buttons rather than as a control
   and a list. */
.c-convlist label:has(input:checked){background:var(--c-mint) !important;
                                     font-weight:500 !important;}

/* STATE IN THE RAIL.

   A list of conversations that all look alike tells you nothing about which
   one is still working. Each row takes a pastel wash for its state, written
   by :func:`distinct_server.render.conversation_tones` into a small style
   block that is re-rendered with the list itself, because the component
   offers no per-option hook to hang a class on.

   The tone is always a second signal. Every option's label begins with a
   shape, and the two states that are not at rest also carry their word, both
   as real text inside the label. These washes are faint on purpose: this is
   peripheral information about rows you are not reading, and a saturated
   list is a list nobody scans. Nothing here is the only carrier of anything.

   The glyph is set smaller than the title it precedes so it reads as a mark
   rather than as the first character of the name. */
.c-convlist label>span{display:inline-block !important;}
.c-convlist label>span::first-letter{font-size:9px;}
.c-railtones{display:none !important;}
.c-convlist label:has(input:focus-visible){outline:2px solid var(--c-sage-dark) !important;
                                           outline-offset:1px !important;}
/* Grows with the history and stops at 42vh, rather than reserving the space
   whether or not there is anything to put in it. A single conversation should
   not push the run controls half a screen down. */
.c-convlist-scroll{flex:0 1 auto !important; min-height:0 !important;
                   max-height:42vh !important; overflow-y:auto !important;
                   margin:0 -4px !important; padding:0 4px var(--s3) !important;}
/* A quiet scrollbar, so a long history does not put a grey bar down the side
   of a calm page. */
.c-convlist-scroll::-webkit-scrollbar{width:6px;}
.c-convlist-scroll::-webkit-scrollbar-thumb{background:var(--c-border);
                                            border-radius:3px;}
.c-convlist-scroll::-webkit-scrollbar-track{background:transparent;}

/* ========================================================================
   SIDEBAR RUN CONTROLS
   Worker and model sit together, in the sidebar, because they are the same
   decision: which machine, running which weights. They used to be split
   between the sidebar and the composer row, which put half of one choice
   next to the thing you type into.
   ==================================================================== */
.c-runsetup{display:flex !important; flex-direction:column !important;
            gap:var(--s2) !important;}
.c-runsetup>*{width:100% !important; min-width:0 !important;}

/* ========================================================================
   ELECTRICITY USED
   Figure, then what it equates to, then the small print. The order is the
   design: this panel used to open with scope and boundary and run counts,
   every one of them true, arranged so the number came last.
   ==================================================================== */
.c-usage-panel{display:flex; flex-direction:column; gap:var(--s4);}
.c-usage{display:flex; flex-direction:column; gap:1px;}
.c-usage__label{margin:0; font-size:var(--t-micro); font-weight:600;
                letter-spacing:.04em; color:var(--c-muted) !important;}
.c-usage__figure{margin:2px 0 0; font-size:22px; line-height:1.15; font-weight:600;
                 color:var(--c-text) !important; font-variant-numeric:tabular-nums;}
.c-usage--absent .c-usage__figure{color:var(--c-muted) !important; font-size:18px;}
.c-usage__means{margin:2px 0 0; font-size:var(--t-micro); color:var(--c-sage-dark) !important;
                line-height:1.45;}
/* The exact span sits under the familiar comparison, quieter than it: the
   first line is what a reader takes away, the second is what they check it
   against. */
.c-usage__span{margin:0; font-size:var(--t-micro); color:var(--c-muted) !important;
               line-height:1.45;}
.c-usage--absent .c-usage__means{color:var(--c-muted) !important; font-style:italic;}
.c-usage__detail{margin:3px 0 0; font-size:11px; color:var(--c-muted) !important; line-height:1.45;}
.c-usage__more{margin-top:var(--s3); border-top:1px solid var(--c-hairline) !important;
               padding-top:var(--s3);}
.c-usage__moretoggle{cursor:pointer; font-size:var(--t-micro); color:var(--c-muted) !important;
                     list-style:none;}
.c-usage__moretoggle::-webkit-details-marker{display:none;}
.c-usage__moretoggle::after{content:" +"; opacity:.7;}
details[open] .c-usage__moretoggle::after{content:" -";}
.c-usage__morebody{margin-top:var(--s2); font-size:11px; line-height:1.5;
                   color:var(--c-muted) !important;}

/* The worker's own figures, on the card for the machine they describe. */
.c-worker__energy{margin:var(--s3) 0 0; display:flex; flex-direction:column; gap:1px;
                  padding-top:var(--s3); border-top:1px solid var(--c-hairline) !important;}
.c-worker__energy-figure{font-size:15px; font-weight:600; color:var(--c-text) !important;
                         font-variant-numeric:tabular-nums;}
.c-worker__energy-means{font-size:var(--t-micro); color:var(--c-sage-dark) !important;}
.c-worker__energy-total{margin-top:3px; font-size:11px; color:var(--c-muted) !important;
                        line-height:1.45;}
.c-worker__energy-note{margin-top:2px; font-size:11px; color:var(--c-muted) !important;
                       font-style:italic;}
.c-worker__energy--absent{font-size:var(--t-micro); color:var(--c-muted) !important;
                          line-height:1.45; font-style:italic;}

/* Scope headings inside the energy panel. Small and quiet: they label the
   figure, they are not the figure. */
.c-energy__scope{font-size:var(--t-micro); font-weight:600; letter-spacing:.04em;
                 color:var(--c-muted) !important; margin:var(--s3) 0 2px;}
.c-energy>.c-energy__scope:first-child{margin-top:0;}

/* An explanation under a worker card, for a state the chips cannot carry
   alone. Used by "unapproved", where the useful information is what the
   operator has to do next. */
.c-worker__note{margin:var(--s2) 0 0; font-size:var(--t-micro); line-height:1.45;
                color:var(--c-muted) !important; max-width:44ch;}

/* ========================================================================
   LIVE ACTIVITY
   ==================================================================== */
.c-activity{
  background:var(--c-surface); border:1px solid var(--c-border) !important;
  border-left:3px solid var(--c-sage) !important;
  border-radius:var(--r-md); padding:var(--s3) var(--s4);
  box-shadow:var(--e1); font-size:var(--t-micro);
}
.c-activity--wait{border-left-color:#C8A24A;}
.c-activity--done{border-left-color:var(--c-sage-dark);}
.c-activity__head{display:flex; align-items:center; gap:var(--s2); margin:0;}
.c-activity__headline{font-weight:600; color:var(--c-text) !important; font-size:var(--t-body);}
.c-activity__dot{color:var(--c-sage-dark) !important;}
.c-activity__detail{margin:6px 0 0; color:var(--c-muted) !important; line-height:1.5;
                    max-width:var(--measure); overflow-wrap:anywhere;}
.c-activity__timing,.c-activity__note{margin:6px 0 0; color:var(--c-muted) !important;
                                      font-size:var(--t-micro);}
.c-activity__note{font-style:italic;}
.c-activity__bar{margin-top:var(--s3); height:4px; border-radius:2px;
                 background:var(--c-fill); overflow:hidden;}
.c-activity__fill{display:block; height:100%; background:var(--c-sage);
                  transition:width .4s linear;}

/* The spinner is the only animation in the product, and it is switched off
   for anyone who has asked for less motion. A run that is working must still
   look like it is working, so the reduced-motion fallback is a steady mark
   rather than nothing. */
.c-spin{
  display:inline-block; width:13px; height:13px; flex:0 0 13px;
  border:2px solid var(--c-border) !important; border-top-color:var(--c-sage-dark);
  border-radius:50%; animation:c-spin .8s linear infinite;
}
@keyframes c-spin{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion:reduce){
  .c-spin{animation:none; border-top-color:var(--c-sage-dark);
          border-right-color:var(--c-sage-dark);}
  .c-activity__fill{transition:none;}
}
.c-visually-hidden{position:absolute; width:1px; height:1px; padding:0;
                   margin:-1px; overflow:hidden; clip:rect(0 0 0 0);
                   white-space:nowrap; border:0 !important;}

/* ========================================================================
   RUN RECEIPTS
   What each answer cost, beside the conversation rather than inside it.
   ==================================================================== */
/* One card holding a list, not a stack of cards.

   Each receipt is a single line of fact: a turn number, a figure and what the
   figure is like. Three of them drawn as three bordered white boxes gave a
   one-line fact the visual weight of a panel, and three answers turned the
   space under the transcript into a wall. They are rows now, separated by a
   hairline, inside one surface. */
.c-receipts{margin-top:var(--s3); background:var(--c-surface);
            border:1px solid var(--c-hairline) !important; border-radius:var(--r-md);
            padding:0 var(--s4);}
.c-receipts .c-eyebrow{margin:0; padding:var(--s3) 0 var(--s2);}
.c-receipt{padding:var(--s3) 0; border-top:1px solid var(--c-hairline) !important;}
.c-receipt__head{margin:0; display:flex; align-items:baseline; gap:var(--s2);
                 flex-wrap:wrap;}
.c-receipt__turn{font-size:var(--t-micro); font-weight:600; color:var(--c-muted) !important;
                 letter-spacing:.04em;}
.c-receipt__cost{font-size:16px; font-weight:600; color:var(--c-text) !important;
                 font-variant-numeric:tabular-nums;}
.c-receipt__means{font-size:var(--t-micro); color:var(--c-sage-dark) !important;}
.c-receipt .c-chips{margin-top:2px;}
.c-receipt .c-steps{margin-top:var(--s2); padding-top:var(--s2);}

/* WHAT THE AGENT DID, kept after the run rather than only streamed during it.
   Folded away by default: the trace above already says which tools ran, and
   this is for the moment you want to know why. */
.c-turns{margin-top:var(--s2); font-size:var(--t-micro);}
.c-turns__toggle{cursor:pointer; color:var(--c-muted) !important; list-style:none;
                 padding:2px 0; user-select:none;}
.c-turns__toggle::-webkit-details-marker{display:none;}
.c-turns__toggle::after{content:" +"; opacity:.7;}
details[open]>.c-turns__toggle::after{content:" -";}
.c-turns .c-steps{margin-top:var(--s1); border-top:1px solid var(--c-hairline) !important;}
.c-step__lead{color:var(--c-muted) !important; margin-right:5px;}

/* A run that ended without an answer. It is not a message and it is not a
   cost, so it is neither a bubble nor a receipt: one line, attached to the
   turn it belongs to, in the column that reports runs. */
.c-outcomes{list-style:none; margin:var(--s3) 0 0; padding:0;
            display:flex; flex-direction:column; gap:var(--s2);}
.c-outcome{display:flex; align-items:baseline; gap:var(--s2);
           background:#FDF8EA; border-left:2px solid var(--c-warn-rule) !important;
           border-radius:0 var(--r-md) var(--r-md) 0;
           padding:var(--s2) var(--s3); font-size:var(--t-micro);
           color:var(--c-text-2) !important;}
.c-outcome__turn{flex:0 0 auto; font-weight:600; color:#5A4512 !important;}
.c-outcome__text{min-width:0; overflow-wrap:anywhere;}

/* ========================================================================
   LIVE STEPS
   ==================================================================== */
.c-steps{list-style:none; margin:var(--s3) 0 0; padding:var(--s3) 0 0;
         border-top:1px solid var(--c-hairline) !important;
         display:flex; flex-direction:column; gap:5px;}
.c-step{display:flex; align-items:flex-start; gap:var(--s2);
        font-size:var(--t-micro); line-height:1.45; color:var(--c-muted) !important;}
.c-step__mark{flex:0 0 12px; text-align:center; color:var(--c-muted) !important;}
.c-step--ok .c-step__mark{color:var(--c-sage-dark) !important;}
.c-step--warn .c-step__mark{color:#A8541F !important;}
.c-step--work .c-step__mark{color:var(--c-text) !important;}
.c-step__body{min-width:0; overflow-wrap:anywhere;}
.c-step__tool{background:var(--c-fill); border-radius:4px; padding:1px 5px;
              margin-right:6px; font-size:11px; color:var(--c-text) !important;}
.c-step__timing{margin-left:auto; flex:0 0 auto; color:var(--c-muted) !important;
                font-variant-numeric:tabular-nums;}

/* ========================================================================
   CONVERSATION COLUMN
   ==================================================================== */
.c-conversation{
  order:2 !important;
  min-width:0 !important; align-self:stretch !important;
  display:flex !important; flex-direction:column !important; gap:var(--s3) !important;
}
/* An explicit range, so the box is sized by design rather than by whatever
   the viewport had left over. It grows with the conversation and then
   scrolls internally. */
/* THE TRANSCRIPT THAT NEVER MOVED.

   This block used to set ``max-height`` and ``overflow-y:auto`` here, which
   made the outer block the scroll container. The component's own scroller
   then held its full natural height and could not scroll at all, so the
   component scrolled it faithfully to the newest turn on every message, to
   no effect, while the box the user was looking at stayed at the top. Three
   answers in, the visible content was still the first question and the newest
   one was bisected by the bottom edge.

   The height range now belongs to the component, in ui.py, where the
   scrolling behaviour is also configured. What is left here is appearance. */
.c-chat{
  /* Sized by its content between the component's own minimum and maximum,
     not by whatever the row had spare. With ``flex:1 1 auto`` it stretched to
     match the taller right-hand column, so an empty conversation rendered as
     a 560px white void with three lines of type adrift in the middle of it. */
  flex:0 0 auto !important;
  background:var(--c-surface) !important; border:none !important;
  border-radius:var(--r-lg) !important; padding:var(--s4) !important;
  box-shadow:var(--e1) !important;
}
.c-chat>*{max-width:100% !important;}
.c-chat .bubble-wrap::-webkit-scrollbar{width:6px;}
.c-chat .bubble-wrap::-webkit-scrollbar-thumb{background:var(--c-border); border-radius:3px;}
.c-chat .bubble-wrap::-webkit-scrollbar-track{background:transparent;}
/* THE OVERFLOW BUG, AND WHY IT DESTROYED TEXT RATHER THAN SCROLLING.
   `max-width:68ch` on a bubble is a *lower bound on width* the moment the
   column is narrower than 68ch: the bubble stays 68ch, the flex row centres
   it, and it hangs off both sides of a box that an ancestor had set to
   `overflow:hidden`. Overflow to the right is at least reachable by scrolling;
   overflow to the left of a centred box is not reachable at all, which is how
   a run's error message got cut to "o execution failed: RunnerError:".
   `min()` makes the measure a preference rather than a floor, so the bubble
   can never be wider than the box that holds it. */
.c-chat .message{border:none !important; box-shadow:none !important;
                 border-radius:var(--r-lg) !important;
                 padding:var(--s3) var(--s4) !important;
                 font-size:var(--t-body) !important; line-height:var(--lh-body) !important;
                 max-width:min(var(--measure),100%) !important;
                 min-width:0 !important; box-sizing:border-box !important;}
/* ONE SPEAKER GETS A BUBBLE, NOT BOTH.

   Both turns used to be green rectangles: ``--c-mint`` for the question and
   ``--c-fill`` for the answer. Those two greens are four percent apart in
   lightness, so at a glance a conversation was a stack of near-identical
   blocks and you had to read a sentence to learn who had said it. Alignment
   was carrying the whole distinction on its own, and the bubbles were wide
   enough that it could not.

   The question keeps its bubble and sits right. The answer loses its bubble
   entirely and sits left as plain text on the surface, which is both the
   convention every chat product has converged on and the honest hierarchy:
   the answer is the content of this page, and content does not need a
   container to prove it is content. */
.c-chat .user{background:var(--c-mint) !important; color:var(--c-text) !important;
              margin-left:auto !important;}
.c-chat .bot{background:transparent !important; color:var(--c-text) !important;
             padding-left:0 !important; padding-right:var(--s4) !important;
             margin-right:auto !important;}
/* Gradio's own conversation toolbar: share, delete, copy, floating unlabelled
   over the first turn. Deleting a conversation belongs in the rail that lists
   conversations, and an unlabelled destructive icon hovering over a transcript
   is the kind of chrome that makes a product feel unfinished. */
.c-chat button[title="Share" i],.c-chat .share-button,
.c-chat button[aria-label="Delete conversation" i],
.c-chat button[title="Clear" i],.c-chat .icon-button-wrapper.top-panel{
  display:none !important;}
/* The copy control, returned to the margin it belongs in.

   It is a sibling of the turn, not a child, so it took a 30px row of its own
   between every question and answer and drew itself as a bordered card. Six
   turns meant six small floating boxes down the middle of the transcript,
   each one competing with the text it belonged to. It stays, because copying
   an answer is worth having; it is now a quiet glyph that only resolves when
   the pointer is over the transcript. */
.gradio-container .c-chat [class*="message-buttons"]{
  min-height:0 !important; margin:0 !important; opacity:0 !important;
  transition:opacity .15s ease-out !important;}
.gradio-container .c-chat .message-wrap:hover [class*="message-buttons"]{opacity:.6 !important;}
.gradio-container .c-chat [class*="message-buttons"]:hover,
.gradio-container .c-chat [class*="message-buttons"]:focus-within{opacity:1 !important;}
.gradio-container .c-chat [class*="message-buttons"] button{
  border:none !important; background:none !important; box-shadow:none !important;
  padding:2px !important;}
/* Model output is arbitrary text and will eventually contain a long unbroken
   token: a base64 blob, a stack frame, a URL, a hash. None of them may be
   allowed to set the width of the page. Worker-supplied names get the same
   treatment for the same reason, one directory up. */
.c-chat .message,.c-chat .message *{overflow-wrap:anywhere !important;}
.c-chat pre,.c-chat code{white-space:pre-wrap !important; overflow-wrap:anywhere !important;
                         max-width:100% !important;}

/* ========================================================================
   COMPOSER: the container IS the field
   ==================================================================== */
.c-composer{
  flex:0 0 auto !important;
  background:var(--c-surface) !important;
  border:1.5px solid var(--c-border) !important;
  border-radius:var(--r-lg) !important;
  box-shadow:var(--e1) !important;
  padding:var(--s4) !important;
  transition:border-color .18s ease-out,box-shadow .18s ease-out !important;
}
/* Four controls, 27, 28 and 36 pixels apart, in a box that had asked for 8.
   The column carries its own gap from the framework's layout variable, which
   this sheet was overriding for ``.gap`` and ``.form`` but not for a column
   that is neither. Stated here, once, in the same scale as everything else. */
.c-composer{gap:var(--s2) !important;}
.c-composer>*{margin-top:0 !important; margin-bottom:0 !important;}
/* The row is a pill and two checkboxes. It was 91px tall because the upload
   block keeps the height of the panel it used to draw. */
.c-composer-tools,.c-composer-tools>*{min-height:0 !important;}
.c-undernote,.c-undernote>*{min-height:0 !important;}
.c-composer:hover{border-color:var(--c-sage-dark) !important;}
.c-composer:focus-within{border-color:var(--c-sage-dark) !important;
                         box-shadow:0 0 0 3px rgba(110,155,118,.26) !important;}
.c-composer textarea{
  border:none !important; background:transparent !important; box-shadow:none !important;
  font-size:var(--t-body) !important; line-height:var(--lh-body) !important;
  resize:none !important; padding:0 !important; min-height:44px !important;
  color:var(--c-text) !important;
}
.c-composer textarea:focus{outline:none !important; box-shadow:none !important;}
.c-composer textarea::placeholder{color:#93A399 !important;}
/* The selector takes the row's slack instead of a fixed 300px, so the model
   label has room to render whole. The ellipsis stays as the fallback for
   narrow viewports: a truncation that reads as truncation is fine, a word
   severed mid-character is not. */
.c-composer-row{display:flex !important; align-items:center !important;
                gap:var(--s3) !important; flex-wrap:nowrap !important;
                padding:var(--s3) 0 0 !important;}
.c-composer-row>*{min-width:0 !important;}
.c-composer-row>*:first-child{flex:1 1 auto !important; max-width:none !important;}
.c-composer-row>*:nth-last-child(1){flex:0 0 auto !important; margin-left:auto !important;}
/* Attachments and library selection live on the message. Both are choices
   about this request, and a control that changes per message belongs beside
   the message rather than in a sidebar that describes the session. */
/* THE COMPOSER WAS FOUR HUNDRED PIXELS TALL FOR THREE CONTROLS.

   Every part of it had been given room to breathe independently: the field a
   48px floor plus the wrapper's own padding, the tool row 12px above it, the
   library label its own line, the disclosure another, the acknowledgement a
   rule and 12px more. Each decision was defensible and the sum was a box
   taller than the transcript above it, with the button that sends the request
   below the fold on an empty page.

   The controls now sit on one row: attach on the left, the library beside it,
   and the row is centred rather than top-aligned so the pill and the
   checkboxes share a baseline instead of stepping down the box. */
.c-composer-tools{display:flex !important; align-items:center !important;
                  gap:var(--s4) !important; flex-wrap:wrap !important;
                  padding:var(--s2) 0 0 !important;}
.c-composer-tools>*{min-width:0 !important;}
/* The library's own label repeated what the checkboxes already say, on a line
   of its own, inside a box that was already too tall. */
.c-composer-tools .c-tools-label,
.c-composer-tools fieldset>span[data-testid="block-info"]{display:none !important;}
.c-composer-tools fieldset{flex-direction:row !important; flex-wrap:wrap !important;
                           align-items:center !important; gap:var(--s3) !important;}
.c-composer-tools .wrap,.c-composer-tools fieldset{gap:4px !important;}
.c-composer-tools label{font-size:var(--t-micro) !important;}
/* The upload control is a pill, not a panel.

   Left alone the component draws a dashed box the height of the message field
   and captions it "Drop File Here - or - Click to Upload", with its own
   floating label landing on top of that caption. Beside a composer it reads as
   the main thing on offer, which it is not: it is one affordance among three.

   The caption is text nodes rather than elements, so it cannot be selected and
   hidden. Zeroing the font size on the container collapses every text node at
   once, and the wanted word is restored on the pseudo-element at a real size.
   The icon is an element and gets its size back explicitly. Dropping still
   works: only the invitation is quieter, not the target.

   Every rule below is scoped to the drop target itself, keyed on the
   ``aria-dropeffect`` the component puts there. The first attempt scoped them
   to the whole control, which also caught the preview's own undo and clear
   buttons: they inherited the zeroed font size, their icons are sized in em,
   and both collapsed into blank pills. A file was attached and the control to
   remove it had become invisible. */
.c-attach{flex:0 0 auto !important; border:none !important; background:none !important;
          box-shadow:none !important; padding:0 !important; overflow:visible !important;}
.c-attach button[aria-dropeffect]:not(.icon-mode){
  height:auto !important; min-height:0 !important; width:fit-content !important;
  padding:7px 13px !important; border:1px solid var(--c-border) !important;
  border-radius:999px !important; background:var(--c-surface) !important;
  transition:border-color .18s ease-out,background .18s ease-out !important;}
.c-attach button[aria-dropeffect]:not(.icon-mode):hover{border-color:var(--c-sage-dark) !important;
                                        background:var(--c-fill) !important;}
.c-attach button[aria-dropeffect]:not(.icon-mode) .wrap{
  font-size:0 !important; flex-direction:row !important; align-items:center !important;
  gap:7px !important; padding:0 !important; min-height:0 !important;}
.c-attach button[aria-dropeffect]:not(.icon-mode) .wrap .or{display:none !important;}
.c-attach button[aria-dropeffect]:not(.icon-mode) .wrap .icon-wrap{
  flex:0 0 15px !important; width:15px !important; height:15px !important;
  margin:0 !important; color:var(--c-muted) !important;}
.c-attach button[aria-dropeffect]:not(.icon-mode) .wrap::after{
  content:"Attach files"; font-size:var(--t-micro) !important;
  color:var(--c-muted) !important; white-space:nowrap !important;}
/* Once a file is attached the component shows its name, which is the one
   state where its own text is worth reading. */
.c-attach .file-preview{font-size:var(--t-micro) !important; min-height:0 !important;}

/* File names in the session panel, readable rather than clipped.

   The component splits a name into a stem and an extension and ellipsises the
   stem, so in a 312px column "cupcakes.pdf" rendered as "cupca... .pdf". The
   stem wraps instead: a two-line name is legible and a truncated one is not.
   Artifacts are stored under their own names now, so these are short. */
.c-side .file-preview td.filename{white-space:normal !important;
                                  overflow:visible !important; padding:2px 0 !important;}
.c-side .file-preview .stem{overflow:visible !important; text-overflow:clip !important;
                            white-space:normal !important; overflow-wrap:anywhere !important;}
.c-side .file-preview tr.file{vertical-align:middle !important;}

/* What the offered library members actually do, one click from the picker. */
.c-libhelp{margin:var(--s2) 0 0; font-size:var(--t-micro);}
.c-libhelp__toggle{cursor:pointer; color:var(--c-muted) !important; list-style:none;}
.c-libhelp__toggle::-webkit-details-marker{display:none;}
.c-libhelp__toggle::after{content:" +"; opacity:.7;}
details[open] .c-libhelp__toggle::after{content:" -";}
.c-libhelp__list{list-style:none; margin:var(--s2) 0 0; padding:0;
                 display:flex; flex-direction:column; gap:6px;}
.c-libhelp__item{display:flex; flex-wrap:wrap; align-items:baseline; gap:6px;
                 line-height:1.45;}
.c-libhelp__name{font-weight:600; color:var(--c-text) !important;}
.c-libhelp__kind{font-size:11px; color:var(--c-muted) !important; text-transform:uppercase;
                 letter-spacing:.06em;}
.c-libhelp__ref{background:var(--c-fill); border-radius:4px; padding:1px 5px;
                font-size:11px; color:var(--c-muted) !important;}
.c-libhelp__what{flex:1 1 100%; color:var(--c-muted) !important; max-width:var(--measure);}
.c-libhelp__note{margin:var(--s2) 0 0; color:var(--c-muted) !important; font-style:italic;}

.c-composer-foot{display:flex !important; align-items:center !important;
                 justify-content:space-between !important; gap:var(--s3) !important;
                 margin-top:var(--s2) !important; padding:var(--s2) 0 0 !important;
                 border-top:1px solid var(--c-hairline) !important;}
.c-composer-foot label span{font-size:var(--t-micro) !important;
                            color:var(--c-muted) !important; font-weight:400 !important;}
/* The acknowledgement takes the row's slack rather than a token width. It was
   being squeezed to about a hundred pixels and wrapping onto four lines, with
   the last one clipped, so the sentence the user has to agree to was the least
   readable thing on the page. */
.c-composer-foot>div.block:first-of-type{flex:1 1 auto !important; min-width:0 !important;}
.c-composer-foot .checkbox-container{align-items:center !important; gap:8px !important;}
/* The helper note under the composer shares the composer's own left edge.
   It used to sit 17px inboard of it, which put a fourth vertical edge on a
   page that should have had one. */
.c-undernote{padding:0 !important;}

/* ========================================================================
   CONTROLS
   ==================================================================== */
.gradio-container select,.gradio-container input[type="text"],
.gradio-container .wrap-inner{
  background:var(--c-fill) !important; border:1px solid transparent !important;
  border-radius:var(--r-pill) !important; color:var(--c-text) !important;
  box-shadow:none !important; font-size:var(--t-label) !important;
  transition:background-color .18s ease-out,border-color .18s ease-out !important;
}
/* THE WHITE AROUND THE SELECTORS.

   A dropdown is four nested boxes. The pill is ``.wrap-inner``; directly
   behind it sits ``.wrap``, which the framework paints white with an 8px
   radius. A 999px pill on a white 8px rectangle shows the rectangle at all
   four corners, so both selectors had a pale square halo that belonged to
   neither the control nor the page. It is the parent's fill showing past its
   child, not a border, which is why it survived every attempt to remove a
   border.

   ``.secondary-wrap``, one level inside the pill, was also being given the
   pill's own background and border, painting the same shape twice. One box
   is visible now and the other three carry nothing. */
.gradio-container .wrap:has(>.wrap-inner){
  background:transparent !important; border:none !important;
  box-shadow:none !important; border-radius:var(--r-pill) !important;}
.gradio-container .secondary-wrap{
  background:transparent !important; border:none !important;
  box-shadow:none !important;}
.gradio-container .wrap-inner{padding-right:28px !important; position:relative;}
.gradio-container .wrap-inner input,
.gradio-container .wrap-inner span,
.gradio-container select{
  overflow:hidden !important; text-overflow:ellipsis !important;
  white-space:nowrap !important; max-width:100% !important;
}
.gradio-container .wrap-inner:hover,.gradio-container select:hover{
  background:#E9F0E5 !important;
}
.gradio-container button{
  border-radius:var(--r-pill) !important; font-weight:600 !important;
  font-size:var(--t-label) !important; letter-spacing:-.004em !important;
  transition:background-color .18s ease-out,box-shadow .18s ease-out !important;
}
.gradio-container button.primary{
  background:var(--c-accent) !important; border:1px solid var(--c-accent) !important;
  color:#FFF !important;
}
.gradio-container button.primary:hover{background:var(--c-accent-hover) !important;}
.c-composer-row button.primary{max-width:140px !important; min-width:104px !important;
                               padding:9px 16px !important; white-space:nowrap !important;}
.gradio-container button.secondary{
  background:var(--c-surface) !important; border:1px solid var(--c-border) !important;
  color:var(--c-sage-deep) !important; font-size:var(--t-micro) !important;
  padding:6px 12px !important;
}
.c-composer button.stop,.gradio-container button.stop{
  background:transparent !important; border:none !important; box-shadow:none !important;
  color:var(--c-muted) !important; font-weight:500 !important;
  font-size:var(--t-micro) !important; padding:4px 10px !important;
}
.gradio-container button.stop:hover{color:var(--c-text-2) !important;
                                    background:var(--c-fill) !important;}
.gradio-container button:disabled{opacity:.5 !important; cursor:not-allowed !important;}

/* Focus: always visible, never colour alone. */
.gradio-container *:focus-visible{
  outline:3px solid var(--c-sage) !important; outline-offset:2px !important;
  border-radius:var(--r-md);
}
/* The skip link is off-screen until focused, but its Gradio wrapper still
   claimed 28px of column, which is why the page opened with a band of nothing
   above the masthead. Zero height until it is wanted. */
.c-shell>*:has(.c-skip){height:0 !important; min-height:0 !important;
                        overflow:visible !important;}
.c-skip{position:absolute; left:-9999px; top:0; background:var(--c-surface);
        color:var(--c-sage-deep) !important; padding:var(--s3) var(--s4);
        border-radius:var(--r-md); z-index:100; font-weight:600;}
.c-skip:focus{left:var(--s4); top:var(--s4);}

/* ========================================================================
   TAIL: accordions and attribution
   Both live inside the shell's padding box and therefore share its edges.
   Gradio's own chevron glyph pointed left in both states, so it is replaced
   with a drawn one whose direction is derived from the open state rather
   than from whatever glyph the toolkit shipped.
   ==================================================================== */
.c-tail{display:flex !important; flex-direction:column !important;
        gap:var(--s2) !important;}
/* JOINING THIS SERVER: the address, filled in.
   The address and the code are the two things a person copies, so they are
   the two things drawn as copyable blocks rather than as prose. */
.c-join{display:flex; flex-direction:column; gap:var(--s2); max-width:var(--measure);}
.c-join__lead{margin:var(--s2) 0 0; font-size:var(--t-micro); color:var(--c-muted) !important;}
.c-join__address,.c-join__code{
  display:block; background:var(--c-fill); border:1px solid var(--c-hairline) !important;
  border-radius:var(--r-md); padding:var(--s3); font-family:var(--mono);
  font-size:var(--t-label); color:var(--c-text) !important; word-break:break-all;
  user-select:all;}
.c-join__alts{list-style:none; margin:0; padding:0; display:flex;
              flex-direction:column; gap:4px;}
.c-join__alt{font-family:var(--mono); font-size:var(--t-micro); color:var(--c-muted) !important;}
.c-join__cmd{margin:0; background:var(--c-surface); border:1px solid var(--c-hairline) !important;
             border-radius:var(--r-md); padding:var(--s3); font-family:var(--mono);
             font-size:11.5px; line-height:1.6; overflow-x:auto; white-space:pre;
             color:var(--c-text-2) !important; user-select:all;}
.c-join__note{margin:0; font-size:var(--t-micro); color:var(--c-muted) !important;
              line-height:1.55; max-width:56ch;}
/* The one outbound link in the setup panel. Underlined, because Gradio's own
   prose rules strip underlines from anchors inside its container and a link
   that reads as body text is a link nobody clicks -- and this one is the
   difference between a worker that runs models and one that does not. */
.c-join__link{color:var(--c-accent) !important; text-decoration:underline !important;
              text-underline-offset:2px; font-weight:600;}
.c-join__link:hover{color:var(--c-sage-deep) !important;}
.c-join__note code{font-family:var(--mono); font-size:11px;
                   background:var(--c-fill); border-radius:4px; padding:1px 5px;}
.c-join__note .c-join__code{display:inline-block; padding:2px 8px;
                            font-size:11.5px; margin-top:4px;}

/* ONE COMMAND PER BLOCK, AND A BUTTON THAT COPIES THAT ONE COMMAND.
   `cd distinct` and the install line used to share a <pre>. A <pre> is copied
   whole or not at all, so taking one of the two meant selecting a line by
   hand, which is fiddly with a mouse and impossible with a thumb. Each
   command is now its own block with its own button, and the bar above the
   command carries the button plus, where the command differs by platform, the
   name of the platform it is for. */
.c-cmd{display:flex; flex-direction:column; gap:4px;}
.c-cmd__bar{display:flex; align-items:center; gap:var(--s2); min-height:24px;}
.c-cmd__for{font-size:var(--t-micro); font-weight:650; letter-spacing:.01em;
            color:var(--c-text-2) !important;}
.c-cmd__copy{margin-left:auto; flex:none; cursor:pointer; appearance:none;
             font-family:var(--font) !important; font-size:var(--t-micro) !important;
             font-weight:600 !important; line-height:1.5 !important;
             padding:3px 10px !important; border-radius:var(--r-md) !important;
             background:var(--c-surface) !important; color:var(--c-text-2) !important;
             border:1px solid var(--c-border) !important;}
.c-cmd__copy:hover{border-color:var(--c-accent) !important;
                   color:var(--c-sage-deep) !important;}
/* The confirmation is the button itself for a moment. A toast somewhere else
   on the page is a second thing to find, and the question being answered
   ("did that press do anything?") is asked about this button. */
.c-cmd__copy.is-copied{background:var(--c-mint) !important;
                       border-color:var(--c-sage-dark) !important;
                       color:var(--c-sage-deep) !important;}

/* WHICH MACHINE, AS TWO RADIOS AND NO SCRIPT.
   Neither is checked when the panel renders, so both platforms' commands are
   visible and labelled until somebody chooses. A checked default would be
   silently wrong for half the readers, and a volunteer pasting a Windows
   command into a Mac terminal is exactly the failure this switch exists to
   prevent. Choosing hides the other platform's blocks. */
.c-os{display:flex; flex-wrap:wrap; align-items:center; gap:var(--s2);}
.c-os__ask{font-size:var(--t-micro); color:var(--c-muted) !important;}
.c-os__radio{position:absolute; width:1px; height:1px; opacity:0;
             margin:0; pointer-events:none;}
.c-os__tab{display:inline-flex; align-items:center; cursor:pointer;
           padding:4px 12px; border-radius:var(--r-pill);
           border:1px solid var(--c-border); background:var(--c-surface);
           font-size:var(--t-micro); font-weight:600;
           color:var(--c-text-2) !important;}
.c-os__tab:hover{border-color:var(--c-accent);}
#distinct-os-win:checked ~ .c-os label[for="distinct-os-win"],
#distinct-os-nix:checked ~ .c-os label[for="distinct-os-nix"]{
  background:var(--c-mint); border-color:var(--c-sage-dark);
  color:var(--c-sage-deep) !important;}
#distinct-os-win:focus-visible ~ .c-os label[for="distinct-os-win"],
#distinct-os-nix:focus-visible ~ .c-os label[for="distinct-os-nix"]{
  outline:3px solid var(--c-focus); outline-offset:2px;}
#distinct-os-win:checked ~ .c-steps-num .c-cmd--nix,
#distinct-os-nix:checked ~ .c-steps-num .c-cmd--win{display:none;}

/* SETTING UP A WORKER, AS NUMBERED STEPS.
   Three things happen in order and each can fail on its own, so each is
   drawn as its own step with its own command. Told as one paragraph, a
   volunteer who got half way could not tell which half they were in. */
.c-steps-num{list-style:none; margin:0; padding:0; display:flex;
             flex-direction:column; gap:var(--s5);}
.c-step-num{display:flex; gap:var(--s3); align-items:flex-start;}
.c-step-num__n{flex:none; width:24px; height:24px; border-radius:50%;
               display:grid; place-items:center; margin-top:1px;
               background:var(--c-mint); color:var(--c-sage-deep) !important;
               font-size:12px; font-weight:700;}
.c-step-num__body{flex:1 1 auto; min-width:0; display:flex;
                  flex-direction:column; gap:var(--s2);}
.c-step-num__head{margin:0; font-size:var(--t-body); font-weight:650;
                  color:var(--c-text) !important; letter-spacing:-.01em;}

.c-join__qr{margin-top:var(--s3);}
.c-join__qr svg{width:160px; height:160px; display:block;
                border:1px solid var(--c-hairline) !important; border-radius:var(--r-md);
                background:#fff; padding:var(--s2);}

.c-tail__row{max-width:760px !important; align-items:flex-end !important;
             gap:var(--s3) !important;}
/* Prose in the tail obeys the same measure as prose everywhere else. A
   paragraph 1090px wide is one line the eye cannot track back from. */
.c-tail p,.c-tail .prose p{max-width:var(--measure) !important;}
.gradio-container .label-wrap{
  background:transparent !important; padding:var(--s3) 0 !important;
  box-shadow:none !important; font-size:var(--t-label) !important;
  font-weight:600 !important; color:var(--c-text-2) !important;
  border-top:1px solid var(--c-hairline) !important;
  display:flex !important; align-items:center !important;
  justify-content:space-between !important; cursor:pointer !important;
}
.gradio-container .label-wrap span{color:var(--c-text-2) !important;}
.gradio-container .label-wrap .icon{display:none !important;}
.gradio-container .label-wrap::after{
  content:""; flex:none; width:7px; height:7px; margin-right:3px;
  border-right:1.5px solid var(--c-muted); border-bottom:1.5px solid var(--c-muted);
  transform:rotate(45deg) translateY(-2px);
  transition:transform .18s ease-out;
}
.gradio-container .label-wrap.open::after{transform:rotate(-135deg) translateY(-2px);}
.c-footer{display:flex; align-items:center; gap:var(--s3);
          padding:var(--s3) 0 0; border-top:1px solid var(--c-hairline) !important;}
.c-credit{display:flex; align-items:flex-start; gap:var(--s3); margin:0; max-width:100%;}
.c-credit__img{width:56px; height:36px; object-fit:cover; border-radius:6px;
               display:block; flex:none;}
.c-credit__text{font-size:10.5px; line-height:1.45; color:var(--c-muted) !important;}
.c-credit__text a{color:var(--c-sage-deep) !important; text-decoration:underline;}
.c-credit--compact{gap:var(--s2);}
.c-credit--compact .c-credit__img{width:44px; height:28px;}

/* ========================================================================
   NARROW VIEWPORTS
   Mobile is a layout, not a squeeze. The two-column grid collapses and the
   order changes to match what a phone user actually does: read the answer,
   write the next request, and only then look at which worker ran it and what
   it cost. Controls they need *before* sending stay above the composer;
   readouts they consult *after* move below it.
   ==================================================================== */
@media (max-width:960px){
  .c-main{grid-template-columns:minmax(0,1fr) !important; gap:var(--s5) !important;}
  .c-rail{order:3; border-right:none !important; padding-right:0 !important;
          border-top:1px solid var(--c-hairline) !important;
          padding-top:var(--s4) !important;}
  .c-rail__list{max-height:40vh !important;}
  /* Transcript and composer first, sidebar readouts after. Conversation
     switching goes below the fold, which is the trade: most sessions are one
     conversation, and burying the composer under a worker card would cost
     every session rather than a few. */
  .c-conversation{order:1;}
  .c-side{order:2;}
  .c-side__credit{margin-top:var(--s4) !important; padding-top:var(--s4) !important;}
  .c-grade-cards{grid-template-columns:minmax(0,1fr);}
  .c-legend__pair{grid-template-columns:minmax(0,1fr);}
}

@media (max-width:640px){
  :root{
    --shell-pad:var(--s4);
    --col-gap:var(--s4);
    /* 16px is not a taste decision. iOS Safari zooms the whole page when a
       text field smaller than 16px takes focus, which throws the layout
       sideways mid-sentence and is the single most common way a mobile chat
       composer breaks. */
    --t-body:16px;
  }
  .c-shell{padding:var(--s4) var(--shell-pad) var(--s6) !important;
           gap:var(--s4) !important;}
  /* dvh rather than vh: with an on-screen keyboard open, vh keeps reporting
     the full screen height, so a vh-sized shell pushes the composer under the
     keyboard. dvh tracks the visible viewport. */
  .c-shell,.c-splash{min-height:100dvh !important;}

  .c-header{flex-wrap:wrap; gap:var(--s2); min-height:0;}
  .c-tagline{white-space:normal; border-left:none !important; padding-left:0; line-height:1.4;
             flex-basis:100%; order:3;}
  .c-identity{order:2;}

  /* The composer stays reachable with the keyboard up. Sticky rather than
     fixed: fixed positioning is taken out of flow and lands underneath the
     keyboard on both iOS and Android, whereas sticky stays inside the
     scrolling document and rides above the fold of the visual viewport. */
  .c-composer{position:sticky !important; bottom:0 !important; z-index:20 !important;
              padding:var(--s3) !important;
              margin-bottom:env(safe-area-inset-bottom,0px) !important;
              box-shadow:0 -6px 20px -14px rgba(32,49,39,.35) !important;}
  .c-composer textarea{min-height:40px !important; font-size:16px !important;}
  .c-composer-row{flex-wrap:wrap !important; gap:var(--s2) !important;}
  .c-composer-row>*:first-child{flex:1 1 100% !important;}
  .c-composer-row>*:nth-last-child(1){margin-left:0 !important; flex:1 1 auto !important;}
  .c-composer-row button.primary{max-width:none !important; width:100% !important;
                                 padding:12px 16px !important;}
  .c-composer-foot{flex-wrap:wrap !important; gap:var(--s2) !important;}
  .c-chat{min-height:220px !important; max-height:52dvh !important;
          padding:var(--s3) !important;}
  .c-chat .message{max-width:100% !important;}

  /* The plate is a portrait photograph. At full width on a phone it would be
     roughly one and a half screens tall, so it becomes a band and the copy
     stays above the fold. */
  .c-splash{padding:var(--s6) var(--shell-pad) var(--s5) !important;}
  .c-splash__grid{gap:var(--s5);}
  .c-splash__img{max-height:38dvh; object-fit:cover; object-position:center;}
  .c-splash__display{font-size:clamp(2.1rem,1.2rem + 5vw,3rem);}
  .c-splash__lede{font-size:var(--t-body);}
  .c-splash-view .c-splash__slot button.primary{width:100% !important;
                                                min-width:0 !important;}
  .c-splash__slot{flex-wrap:wrap;}

  .c-grade-card,.c-panel,.c-legend{padding:var(--s3);}
  .c-grade-row{flex-wrap:wrap; gap:var(--s2);}
}

/* The figure token never breaks up, at any width. The method word sharing a
   border with its number is the whole design, so the cells are explicitly not
   allowed to wrap and the token is not allowed to shrink below its content.
   The row around it wraps instead. */
.c-fig{flex-wrap:nowrap !important; flex:none !important;}
.c-fig__value,.c-fig__method,.c-fig__word{white-space:nowrap; flex:none;}
.c-grade-row__label{min-width:0; overflow-wrap:anywhere;}

@media (prefers-reduced-motion:reduce){
  .gradio-container *{transition:none !important; animation:none !important;}
  .c-splash__display,.c-splash__lede{animation:none !important; opacity:1 !important;
                                     transform:none !important;}
}

/* ---- Mobile: reading order, scroll origin, and overflow ---------------
   On phones the DOM order put the plate photograph above the copy, and the
   centered splash column clipped its own top above the scroll origin once
   content grew taller than the viewport. Say the order explicitly, start-
   align where overflow is possible, and let long command lines wrap. */
@media (max-width:900px){
  .c-splash__copy{order:1 !important;}
  .c-splash__plate{order:2 !important;}
  .c-splash-view{justify-content:flex-start !important;}
}
@media (max-width:640px){
  .c-splash{min-height:0 !important; align-items:start !important;}
  .gradio-container{max-width:100vw !important;}
  .c-shell,.c-splash-view{overflow-x:clip !important;}
  /* The agent command carries the full Space URL on HuggingFace: wrap it
     rather than force the panel wider than the screen. */
  .c-join__cmd{white-space:pre-wrap !important; overflow-wrap:anywhere !important;}
  .c-join__code{overflow-wrap:anywhere;}
  .c-steps-num{gap:var(--s4);}
  .c-step-num{gap:var(--s2);}
  .c-panel code,.c-panel pre{overflow-wrap:anywhere;}
  .c-join__qr svg{width:128px; height:128px;}
}


/* ---- Library page ------------------------------------------------------
   Its own page, reached from the quick nav. One control: the card. Clicking
   or tapping a card makes that member a default and the page saves at once;
   there is no separate list of tick boxes to reconcile with the grid. The
   selected state has to survive a squint test: accent border, filled check,
   tinted wash β€” three signals, any one of which is enough. */
.c-libpage{max-width:var(--shell-max); margin:0 auto; padding:var(--s5) var(--shell-pad) var(--s8);}
.c-libpage__back{font-size:var(--t-label); color:var(--c-text-2) !important; text-decoration:none;
                 display:inline-flex; align-items:center; gap:6px;}
.c-libpage__back:hover{color:var(--c-text) !important;}
.c-libpage__title{margin:var(--s3) 0 4px; font-family:var(--font-display);
                  font-weight:600; font-size:clamp(26px,4vw,34px); letter-spacing:-.015em;
                  color:var(--c-text) !important;}
.c-libpage__lede{margin:0 0 var(--s5); max-width:var(--measure); color:var(--c-text-2) !important;}
.c-libsave{position:sticky; top:0; z-index:9; display:flex; align-items:center; gap:var(--s3);
           background:color-mix(in srgb, var(--c-canvas) 88%, transparent);
           backdrop-filter:blur(6px); padding:var(--s2) 0; margin-bottom:var(--s2);}
.c-libsave__count{font-size:var(--t-label); color:var(--c-text-2) !important;}
.c-libsave__count strong{color:var(--c-sage-deep) !important; font-weight:650;}

.c-libgrid{display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr));
           gap:var(--s4); margin:var(--s4) 0;}
.c-libcard{position:relative; background:var(--c-surface);
           border:1.5px solid var(--c-hairline) !important; border-radius:var(--r-lg);
           padding:var(--s4); cursor:pointer; -webkit-tap-highlight-color:transparent;
           display:flex; flex-direction:column; gap:6px; text-align:left;
           transition:border-color .15s ease, box-shadow .15s ease, background .15s ease;}
.c-libcard:hover{border-color:var(--c-border); box-shadow:var(--e1);}
.c-libcard:focus-visible{outline:3px solid var(--c-focus, rgba(30,110,75,.4)); outline-offset:2px;}
.c-libcard.is-on{border-color:var(--c-accent); background:color-mix(in srgb, var(--c-mint) 38%, var(--c-surface));}
.c-libcard.is-on:hover{box-shadow:var(--e1);}
/* The check is a real mark, not a decoration: absent = a quiet plus, present
   = a filled tick. It is what makes the card legible as a control at all. */
.c-libcard__check{position:absolute; top:10px; right:10px; z-index:2;
                  width:24px; height:24px; border-radius:50%;
                  display:flex; align-items:center; justify-content:center;
                  font-size:14px; line-height:1;
                  border:1.5px solid var(--c-border) !important; color:var(--c-muted) !important;
                  background:var(--c-surface);
                  transition:all .15s ease;}
.c-libcard.is-on .c-libcard__check{border-color:var(--c-accent);
                  background:var(--c-accent); color:#fff !important;}
.c-libcard__check::before{content:"+";}
.c-libcard.is-on .c-libcard__check::before{content:"βœ“";}
/* THE PLATE IS THE SHAPE OF THE DRAWING ON IT.
   The mockups are drawn on a 160x104 viewBox and scale to fit, so a 16/9 plate
   letterboxed every one of them: bars of fill down both sides of a picture that
   had been sized to the card. Matching the ratio removes the bars. The cap stops
   a single-column phone layout turning a 460px card into a 300px picture with
   four lines of type under it. */
.c-libcard__media{margin:calc(var(--s4)*-1) calc(var(--s4)*-1) var(--s2);
                  aspect-ratio:160/104; max-height:200px;
                  border-radius:calc(var(--r-lg) - 2px) calc(var(--r-lg) - 2px) 0 0;
                  background:var(--c-fill);
                  display:flex; align-items:center; justify-content:center;
                  overflow:hidden; position:relative;}
/* The drawing of what this member makes. It sits still and says its piece;
   there is nothing to hover, nothing to wait for, and nothing to fetch. */
.c-libcard__mock{width:100%; height:100%; display:block;}
.c-libcard.is-on .c-libcard__media{background:color-mix(in srgb, var(--c-mint) 55%, var(--c-fill));}

.c-libcard__head{display:flex; align-items:center; gap:var(--s2); padding-right:28px;}
.c-libcard__kind{font-size:var(--t-micro); letter-spacing:.06em; text-transform:uppercase;
                 padding:2px 8px; border-radius:999px; background:var(--c-fill);
                 color:var(--c-text-2) !important; flex:none;}
.c-libcard__kind--skill{background:var(--c-mint); color:var(--c-sage-deep) !important;}
.c-libcard__name{margin:0; font-size:var(--t-body); font-weight:650; color:var(--c-text) !important;
                 text-transform:capitalize;}
.c-libcard__author{margin:0; font-size:var(--t-micro); color:var(--c-muted) !important;}
.c-libcard__desc{margin:2px 0 0; font-size:13px; line-height:1.5;
                 color:var(--c-text-2) !important;
                 display:-webkit-box; -webkit-line-clamp:4; -webkit-box-orient:vertical;
                 overflow:hidden;}
.c-libcard__ref{margin-top:auto; padding-top:var(--s2); font-family:var(--mono);
                font-size:11px; color:var(--c-muted) !important;}

/* Deleting a conversation is a quiet control, not a red one. It sits under
   the list it acts on, at the size of the thing it removes, and says which
   conversation it means by acting on the selected one. */
.c-rail__delete button,button.c-rail__delete{
  width:100% !important; margin-top:var(--s2) !important;
  background:transparent !important; border:1px solid var(--c-hairline) !important;
  color:var(--c-muted) !important; font-size:var(--t-micro) !important;
  font-weight:550 !important; padding:5px 10px !important; min-height:0 !important;}
.c-rail__delete button:hover,button.c-rail__delete:hover{
  border-color:var(--c-border) !important; color:var(--c-text-2) !important;}

/* ---- Navigation, in the header band -----------------------------------
   A button (the library, which navigates) beside a link (a section of this
   page). They must look like one row of controls, so the button is styled to
   match the link rather than the other way round.
   
   The row is pulled up against the header rule and the sign-in control sits
   with it, because a site's navigation belongs to its header. Left where it
   was, the page opened with a rule, a band of nothing, two floating pills,
   another band of nothing, and only then the product. */
.c-quicknav{display:flex !important; flex-wrap:wrap !important; gap:var(--s2) !important;
            justify-content:flex-end !important; align-items:center !important;
            /* Pulled tight against the header rule on both sides. The shell
               puts a 24px gap between every child, which around a 34px row of
               pills left the page opening on a band of nothing; these margins
               spend that gap rather than adding to it. */
            margin:calc(var(--s4)*-1) 0 calc(var(--s2)*-1) !important;
            min-height:0 !important;}
/* The row hugs its controls. Gradio wraps the anchor in a block that keeps a
   60px minimum, which made a 32px row of pills reserve twice its own height;
   the wrapper is told to be the size of what it contains. */
.c-quicknav>*{min-height:0 !important; margin:0 !important; align-self:center !important;}
.c-quicknav .block,.c-quicknav .prose,.c-quicknav nav{min-height:0 !important;
  padding:0 !important; margin:0 !important; display:flex !important;
  align-items:center !important;}
.c-quicknav .prose p{margin:0 !important;}
/* The wrapper keeps a 60px floor that no rule on it reaches, so the row is
   given the height of its own controls and allowed to overflow it. On a
   narrow screen the pills wrap, so the height goes back to automatic. */
@media (min-width:701px){
  .c-quicknav{height:34px !important; overflow:visible !important;}
}
/* The Hugging Face control keeps company with the nav rather than spanning
   the page as a full-width slab. */
.c-shell>.gradio-button.huggingface,
.c-shell button.huggingface{width:auto !important; max-width:280px;
  margin-left:auto !important; margin-top:calc(var(--s3)*-1) !important;}
.c-quicknav>*{flex:0 0 auto !important; width:auto !important; min-width:0 !important;}
.c-quicknav__link,
.c-quicknav .c-quicknav__btn button,
.c-quicknav button.c-quicknav__btn{
  display:inline-flex !important; align-items:center !important;
  font-size:var(--t-label) !important; text-decoration:none; font-weight:550 !important;
  color:var(--c-text-2) !important; border:1px solid var(--c-hairline) !important;
  background:var(--c-surface) !important; padding:5px 14px !important;
  border-radius:999px !important; min-height:0 !important; height:auto !important;
  line-height:1.5 !important;
  transition:border-color .15s ease, color .15s ease;}
.c-quicknav__link:hover,
.c-quicknav .c-quicknav__btn button:hover,
.c-quicknav button.c-quicknav__btn:hover{
  border-color:var(--c-accent) !important; color:var(--c-sage-deep) !important;}

/* The library page's own way back, set as a quiet control at the top left. */
.c-libpage .c-libpage__backbtn button,
.c-libpage button.c-libpage__backbtn{
  background:transparent !important; border:none !important; padding:0 !important;
  color:var(--c-text-2) !important; font-size:var(--t-label) !important;
  font-weight:550 !important; min-height:0 !important;}
.c-libpage .c-libpage__backbtn button:hover,
.c-libpage button.c-libpage__backbtn:hover{color:var(--c-text) !important;}
.c-libpage .c-librarysearch input,
.c-libpage .c-librarysearch textarea{max-width:420px;}
/* The transport, present in the document and not on the page.
   ``display:none`` rather than the usual clip-to-1px trick: a clipped
   element still occupies a box the browser hit-tests, so a stray box landed
   in the corner of the page and could take a click meant for something else.
   A synthetic ``click()`` β€” which is how a card forwards its selection β€”
   dispatches on a hidden element exactly as it does on a shown one, so
   nothing is lost by removing it from the layout entirely. It must never
   become ``visible=False`` in Python: gradio 6 leaves that out of the DOM. */
.c-hiddenfield{display:none !important;}

/* ---- The no-agents veil ----------------------------------------------- */
/* Shown only while somebody is signed in (the identity span has text) and
   the worker panel is in its empty state. Pure CSS state: no events. */
.c-veil{display:none;}
.c-conversation{position:relative;}
.c-shell:has(.c-identity:not(:empty)):has(.c-noworker-hook) .c-veil{
  display:flex; position:absolute; inset:0; z-index:12;
  /* Aligned to the top of the column rather than its centre. Centred, the
     panel sat across the privacy notice above the conversation and read as
     a modal over the whole page instead of an explanation of this column. */
  align-items:flex-start; justify-content:center;
  padding:var(--s7) var(--s5) var(--s5);
  background:color-mix(in srgb, var(--c-canvas) 72%, transparent);
  backdrop-filter:blur(2px); border-radius:var(--r-lg);
  /* The veil informs; it does not imprison. Pointer events pass through
     everywhere except its own panel, so a transient no-worker blip (a poll
     gap, a mode change) can never trap a click mid-flow. */
  pointer-events:none;}
.c-veil__panel{pointer-events:auto;}
.c-shell:has(.c-identity:not(:empty)):has(.c-noworker-hook) .c-conversation > *:not(.c-veil):not(:first-child){
  opacity:.45; filter:saturate(.7);}
/* THE VEIL REPLACES THE EMPTY STATE, IT DOES NOT SIT ON TOP OF IT.
   "No agents available" and "No runs yet Β· pick a model and a worker" are the
   same news told twice, and on a phone the panel landed across the second
   one and cut a sentence in half. While the veil is up the transcript's own
   placeholder stands down. It is hidden rather than removed, so the column
   keeps its height and nothing jumps when a worker appears. */
.c-shell:has(.c-identity:not(:empty)):has(.c-noworker-hook) .c-chat .c-empty{
  visibility:hidden;}
.c-veil__panel{max-width:380px; text-align:center; background:var(--c-surface);
               border:1px solid var(--c-hairline) !important; border-radius:var(--r-lg);
               box-shadow:var(--e2); padding:var(--s5);}
@media (max-width:700px){
  .c-shell:has(.c-identity:not(:empty)):has(.c-noworker-hook) .c-veil{
    padding:var(--s5) var(--s4);}
  .c-veil__panel{padding:var(--s4);}
  /* With the placeholder stood down there is nothing behind the veil, and a
     transcript sized for a conversation it cannot yet hold left a phone
     screen of blank card under the panel. It keeps only the height the panel
     needs until a worker arrives. `!important` because the minimum is an
     inline style the component writes for itself. */
  .c-shell:has(.c-identity:not(:empty)):has(.c-noworker-hook) .c-chat{
    min-height:300px !important; max-height:300px !important;}
}
.c-veil__title{margin:0 0 6px; font-weight:650; font-size:var(--t-lg); color:var(--c-text) !important;}
.c-veil__body{margin:0 0 var(--s4); color:var(--c-text-2) !important; line-height:1.55;}
/* The colour is forced for the same reason the borders are: gradio styles
   anchors inside its container with two classes, which outranks ours, so the
   white label on this button was being repainted the theme's link green β€”
   green text on a green slab, which is how a primary action becomes
   invisible in production while looking correct in development. */
.c-veil__action{display:inline-block; background:var(--c-accent) !important;
                color:#fff !important; padding:10px 22px;
                border-radius:var(--r-md); font-weight:600;}
.c-veil__action:hover{background:var(--c-accent-hover) !important; color:#fff !important;}
/* A control is a control: the label inside it is never underlined. Gradio's
   prose styles underline every anchor, which turned the primary action into
   underlined text on a dark slab and the nav pills into links wearing a
   button's clothes. */
.c-veil__action,.c-veil__action:visited,
.c-quicknav__link,.c-quicknav__link:visited,
.c-libcard a,.gradio-container button a{text-decoration:none !important;}

/* ---- Professional polish pass ----------------------------------------- */
/* Calmer sections: the tail accordions read as pages, not widgets. */
.c-tail .gradio-accordion, .c-tail details{background:var(--c-surface);
  border:1px solid var(--c-hairline) !important; border-radius:var(--r-lg) !important;
  padding:var(--s3) var(--s4) !important; margin-bottom:var(--s4) !important;}
/* SECTION HEADINGS ARE ONE HEADING, AT ONE SIZE, ON ONE EDGE.
   A title that wrapped to two lines came out centred and a size larger than
   its neighbour, so two headings doing the same job looked like two different
   kinds of thing. Everything here is stated rather than inherited: the size,
   the weight, the alignment, and the fact that the title takes the row and
   the chevron keeps its corner. */
.c-tail .label-wrap{text-align:left !important; gap:var(--s3) !important;
                    align-items:center !important;}
.c-tail .label-wrap span{font-weight:650 !important; font-size:var(--t-lg) !important;
                         line-height:1.35 !important; text-align:left !important;
                         flex:1 1 auto !important; min-width:0 !important;
                         color:var(--c-text) !important;}
.c-tail .label-wrap::after{align-self:center !important;}
@media (max-width:700px){
  /* A long heading on a narrow screen is set at the body size rather than
     wrapping three words onto three lines at display size. */
  .c-tail .label-wrap span{font-size:var(--t-body) !important;}
}
/* One shadow language everywhere. */
.c-grade-card,.c-panel,.c-legend,.c-workers article{box-shadow:none !important;}
/* Inputs: quiet until focused. */
.gradio-container input[type="text"], .gradio-container textarea{
  border-radius:var(--r-md) !important;}
/* Buttons: one radius, one accent. The pill-shaped navy is gone; a primary
   action is the accent green, a secondary is paper with a hairline, and the
   Hugging Face sign-in follows the secondary language rather than bringing a
   fourth colour to the page. */
.gradio-container button{border-radius:var(--r-md) !important; font-weight:600 !important;
  letter-spacing:0 !important; transition:background .15s ease, border-color .15s ease !important;}
.gradio-container button.primary{background:var(--c-accent) !important; color:#fff !important;
  border:1px solid var(--c-accent) !important;}
.gradio-container button.primary:hover{background:var(--c-accent-hover) !important;
  border-color:var(--c-accent-hover) !important;}
.gradio-container button.secondary{background:var(--c-surface) !important;
  color:var(--c-text) !important; border:1px solid var(--c-border) !important;}
.gradio-container button.secondary:hover{border-color:var(--c-accent) !important;
  color:var(--c-sage-deep) !important;}
.gradio-container button.huggingface{background:var(--c-surface) !important;
  color:var(--c-text) !important; border:1px solid var(--c-border) !important;
  border-radius:var(--r-md) !important;}
.gradio-container button.huggingface:hover{border-color:var(--c-accent) !important;}
/* Focus is the accent, everywhere, and only on focus. */
.gradio-container :is(button,a,input,textarea,select,[role="button"]):focus-visible{
  outline:3px solid rgba(30,110,75,.4) !important; outline-offset:2px !important;}
/* Gradio's multipage navbar duplicates the quick nav; the page carries its
   own way back. Belt and braces beside gr.Navbar(visible=False). */
nav.navbar, .gradio-container .navbar{display:none !important;}

/* ---- Answer artifacts: show the thing that came out -------------------- */
/* A run that produced a file shows the file's own content, styled as the
   kind of thing it is, inside the answer. The GIF demos end on this block,
   because "generate a PDF" is only demonstrated by a PDF appearing. */
.c-made{margin:var(--s3) 0 0; display:flex; flex-direction:column; gap:var(--s3);}
.c-madecard{background:var(--c-surface); border:1px solid var(--c-hairline) !important;
            border-radius:var(--r-md); overflow:hidden; max-width:520px;
            box-shadow:var(--e1);}
.c-madecard__bar{display:flex; align-items:center; gap:var(--s2);
                 padding:8px var(--s3); border-bottom:1px solid var(--c-hairline) !important;
                 background:var(--c-fill);}
.c-madecard__dot{width:8px; height:8px; border-radius:50%; background:var(--c-accent); flex:none;}
.c-madecard__name{font-family:var(--mono); font-size:12px; color:var(--c-text) !important;
                  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.c-madecard__kind{margin-left:auto; flex:none; font-size:var(--t-micro); color:var(--c-muted) !important;
                  letter-spacing:.05em; text-transform:uppercase;}
/* A glance, not a document viewer. The preview sits inside a conversation
   and has to read as one object at one glance; at 340px it was a scrolling
   panel taller than most of the answers around it. */
.c-madecard__body{padding:var(--s3) var(--s4); max-height:210px; overflow:hidden;
                  position:relative;}
/* What is cut off is said with a fade rather than left as a hard edge, so a
   truncated preview reads as "there is more in the file" instead of as a
   rendering fault. The file itself is complete in Outputs. */
.c-madecard__body::after{content:""; position:absolute; left:0; right:0; bottom:0;
  height:34px; pointer-events:none;
  background:linear-gradient(to bottom, transparent, var(--c-surface));}
/* A document page: a white sheet with real margins and the actual text. */
.c-made--doc .c-madecard__body{font-family:Georgia,'Times New Roman',serif;
  color:#26241F !important; line-height:1.6; font-size:13.5px;}
.c-made--doc .c-madecard__body h4{margin:0 0 8px; font-size:16px; font-weight:700;}
.c-made--doc .c-madecard__body p{margin:0 0 8px;}
/* A sheet: a real grid of the actual cells. */
.c-madegrid{border-collapse:collapse; width:100%; font-size:12px; font-family:var(--font);}
.c-madegrid th{background:var(--c-fill); font-weight:650; text-align:left;}
.c-madegrid th,.c-madegrid td{border:1px solid var(--c-hairline) !important; padding:4px 8px;
  white-space:nowrap; max-width:180px; overflow:hidden; text-overflow:ellipsis;}
/* A deck: each slide a 16:9 miniature with its actual title. */
.c-madeslides{display:grid; grid-template-columns:repeat(auto-fill,minmax(130px,1fr));
  gap:var(--s2);}
.c-madeslide{aspect-ratio:16/9; border:1px solid var(--c-hairline) !important; border-radius:6px;
  background:#fff; padding:8px; display:flex; flex-direction:column; gap:3px; overflow:hidden;}
.c-madeslide__no{font-size:9px; color:var(--c-muted) !important;}
.c-madeslide__title{font-size:11px; font-weight:650; color:var(--c-text) !important; line-height:1.25;}
.c-madeslide__line{height:3px; border-radius:2px; background:var(--c-fill); width:86%;}
.c-madeslide__line+.c-madeslide__line{width:70%;}
/* Code or plain text: the content itself, monospaced. */
.c-made--text .c-madecard__body{padding:0;}
.c-made--text .c-madecard__body::after{height:30px;}
/* One height for every preview, whatever is inside it. The code preview kept
   its own taller cap, which meant a stylesheet came back twice the height of
   a document and the shelf of results had no common measure. */
.c-made--text pre{margin:0; padding:var(--s3) var(--s4); font-family:var(--mono);
  font-size:12px; line-height:1.55; color:var(--c-text) !important; overflow:hidden; max-height:210px;
  white-space:pre-wrap; overflow-wrap:anywhere;}
.c-made__foot{padding:6px var(--s3); border-top:1px solid var(--c-hairline) !important;
  font-size:var(--t-micro); color:var(--c-muted) !important;}

@media (max-width:700px){
  /* The grid used to collapse to one column here, which put a 554px card and a
     292px picture on a tablet and made 29 members seventeen thousand pixels of
     scroll. auto-fill already does the right thing down to about 560px; below
     that the second column is too narrow to read, so that is where it stops. */
  .c-quicknav{justify-content:flex-start;}
  .c-libpage{padding:var(--s4) var(--s4) var(--s7);}
  .c-madecard{max-width:none;}
}

@media (max-width:560px){
  .c-libgrid{grid-template-columns:1fr; gap:var(--s3);}
}
"""


# ---------------------------------------------------------------------------
# WHY THE SHEET IS POST-PROCESSED INSTEAD OF WRITTEN WITH !important BY HAND
#
# Gradio ships a Tailwind-derived reset scoped to a version-stamped container
# class: rules like ``.gradio-container-6-24-0 *``, ``.gradio-container-6-24-0
# [type="radio"]`` and ``.gradio-container-6-24-0 p``. A plain component class
# such as ``.c-os__radio`` is specificity (0,1,0); those are (0,1,1) and (0,2,0).
# They win. Worse, the sheets are injected in a different order on Spaces than
# in local dev, so a rule that survives on a laptop can be flattened in
# production β€” the exact failure that shipped a page which "looks identical"
# after a redesign.
#
# An audit of the live Space found 43 declarations losing this way: numbered
# steps drew Gradio's list markers *and* our own badges, the OS-switch radios
# kept their 16px box instead of collapsing to 1px, copy buttons kept the
# native button appearance, and paragraph margins throughout picked up the
# prose reset's 8px.
#
# Two earlier attempts fixed instances β€” first ``border``, then ``color`` β€”
# by hand. Both regressed the moment a new rule was added, because the next
# author has no reason to know which properties Gradio happens to reset. So
# the guarantee is mechanical instead: every declaration in a rule that styles
# one of our own ``.c-`` components is marked important at import time.
#
# This does not change how our own rules rank against each other. When two
# ``.c-`` rules both become important, specificity and then source order decide
# exactly as before, so state rules (``.c-libcard.is-on``), pseudo-class rules
# (``:hover``) and the mobile ``@media`` block at the end of the sheet all keep
# winning over the base rules they were written to override.
#
# Rules that deliberately target Gradio's own DOM are left alone: they are
# written with explicit ``!important`` where they need it, and hardening them
# blindly would freeze parts of the widget tree we only mean to nudge.
# ---------------------------------------------------------------------------

_COMMENT = re.compile(r"/\*.*?\*/", re.S)
_NESTING_AT_RULES = frozenset({"media", "supports", "layer", "container", "scope"})


def _split_declarations(body: str) -> list[str]:
    """Split a rule body on top-level ``;``.

    Quotes and parentheses are respected, so ``url(data:image/svg+xml;...)``
    and ``content:"a;b"`` survive intact.
    """

    out: list[str] = []
    buf: list[str] = []
    depth = 0
    quote = ""
    i = 0
    while i < len(body):
        ch = body[i]
        if not quote and body.startswith("/*", i):
            end = body.find("*/", i + 2)
            end = len(body) if end < 0 else end + 2
            buf.append(body[i:end])
            i = end
            continue
        if quote:
            buf.append(ch)
            if ch == "\\" and i + 1 < len(body):
                buf.append(body[i + 1])
                i += 2
                continue
            if ch == quote:
                quote = ""
            i += 1
            continue
        if ch in "\"'":
            quote = ch
            buf.append(ch)
        elif ch == "(":
            depth += 1
            buf.append(ch)
        elif ch == ")":
            depth = max(0, depth - 1)
            buf.append(ch)
        elif ch == ";" and depth == 0:
            out.append("".join(buf))
            buf = []
        else:
            buf.append(ch)
        i += 1
    tail = "".join(buf)
    if tail.strip():
        out.append(tail)
    return out


def _force_important(body: str) -> str:
    """Mark every declaration in one rule body important.

    Custom properties are skipped: ``!important`` on a ``--token`` changes
    which *declaration* wins, not how the value is used, and every token in
    this sheet is declared exactly once on ``:root``.
    """

    if "{" in body:  # a nested rule; leave it rather than guess at its shape
        return body
    pieces = _split_declarations(body)
    out: list[str] = []
    for piece in pieces:
        text = piece.strip()
        if not text or ":" not in text:
            out.append(piece)
            continue
        prop = text.split(":", 1)[0].strip()
        if prop.startswith("--") or "!important" in text.lower():
            out.append(piece)
            continue
        head, sep, trail = piece.rpartition(text)
        out.append(head + text + " !important" + trail)
    return ";".join(out) + (";" if pieces else "")


def _harden(css: str) -> str:
    """Give every ``.c-`` declaration the weight it was written to have."""

    out: list[str] = []
    prelude: list[str] = []
    i = 0
    n = len(css)
    while i < n:
        ch = css[i]
        # COMMENTS COME FIRST, AND THAT ORDER IS THE WHOLE POINT.
        #
        # This sheet documents itself in prose, and that prose is full of
        # apostrophes: "Gradio's chrome", "the card's own prose", "someone
        # else's machine". A scanner that checks for quotes before comments
        # reads the apostrophe in a comment as the start of a string, runs to
        # the next apostrophe hundreds of lines later, and swallows every brace
        # in between. The parse silently desynchronises and whole regions of the
        # sheet come out unhardened -- which is how the first version of this
        # pass left the OS-switch radios and the numbered steps untouched while
        # appearing to work everywhere else.
        if css.startswith("/*", i):
            end = css.find("*/", i + 2)
            end = n if end < 0 else end + 2
            prelude.append(css[i:end])
            i = end
            continue
        if ch in "\"'":
            j = i + 1
            while j < n and css[j] != ch:
                j += 2 if css[j] == "\\" else 1
            prelude.append(css[i : j + 1])
            i = j + 1
            continue
        if ch != "{":
            prelude.append(ch)
            i += 1
            continue
        depth = 1
        j = i + 1
        while j < n and depth:
            c = css[j]
            if css.startswith("/*", j):
                end = css.find("*/", j + 2)
                j = n if end < 0 else end + 2
                continue
            if c in "\"'":
                k = j + 1
                while k < n and css[k] != c:
                    k += 2 if css[k] == "\\" else 1
                j = k + 1
                continue
            if c == "{":
                depth += 1
            elif c == "}":
                depth -= 1
            j += 1
        selector = "".join(prelude)
        body = css[i + 1 : j - 1]
        # Classify the selector, not the documentation above it. Comments are
        # carried through verbatim in ``selector`` so the sheet keeps reading
        # the way it was written, but a rule preceded by a paragraph of prose
        # must still be recognised by what it selects: leaving them in made
        # ``@media`` blocks behind a comment look like ordinary rules, so their
        # contents were never walked, and would have let a comment that happens
        # to mention a ``.c-`` class harden a rule that targets Gradio's DOM.
        head = _COMMENT.sub("", selector).strip()
        if head.startswith("@"):
            name = head[1:].split(maxsplit=1)[0].lower() if len(head) > 1 else ""
            # @keyframes and @font-face hold declarations that are not subject
            # to the cascade in the same way; only wrappers get walked.
            if name in _NESTING_AT_RULES:
                body = _harden(body)
        elif ".c-" in head:
            body = _force_important(body)
        out.append(selector + "{" + body + "}")
        prelude = []
        i = j
    out.append("".join(prelude))
    return "".join(out)


CSS = _harden(_SHEET)