papilot 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -2
  3. package/README.zh-CN.md +127 -0
  4. package/bin/papilot.mjs +113 -0
  5. package/dist/apple-touch-icon.png +0 -0
  6. package/dist/assets/Inconsolatazi4-Regular-Dbtq7t_r.otf +0 -0
  7. package/dist/assets/TeXGyrePagellaX-Bold-CEtYdOXj.otf +0 -0
  8. package/dist/assets/TeXGyrePagellaX-Italic-CSuYIstn.otf +0 -0
  9. package/dist/assets/TeXGyrePagellaX-Regular-DQJjZE_L.otf +0 -0
  10. package/dist/assets/cursor-editorTextHighlight-kG3uUOwL.svg +8 -0
  11. package/dist/assets/index-BhQFCMTx.js +131 -0
  12. package/dist/assets/index-CAV3-87U.css +1 -0
  13. package/dist/assets/pdf-view-DJo0X38w.js +598 -0
  14. package/dist/assets/pdf.worker.min-CjEcRF4W.mjs +28 -0
  15. package/dist/favicon.png +0 -0
  16. package/dist/index.html +4 -0
  17. package/examples/papilot-paper/.latex-review.json +4 -0
  18. package/examples/papilot-paper/appendix/proofs.tex +60 -0
  19. package/examples/papilot-paper/appendix/reference.tex +54 -0
  20. package/examples/papilot-paper/main.tex +57 -0
  21. package/examples/papilot-paper/preamble.tex +53 -0
  22. package/examples/papilot-paper/references.bib +158 -0
  23. package/examples/papilot-paper/sections/01-introduction.tex +66 -0
  24. package/examples/papilot-paper/sections/02-using.tex +134 -0
  25. package/examples/papilot-paper/sections/03-background.tex +97 -0
  26. package/examples/papilot-paper/sections/04-model.tex +185 -0
  27. package/examples/papilot-paper/sections/05-conflicts.tex +99 -0
  28. package/examples/papilot-paper/sections/06-building.tex +70 -0
  29. package/examples/papilot-paper/sections/07-geometry.tex +193 -0
  30. package/examples/papilot-paper/sections/08-notes.tex +104 -0
  31. package/examples/papilot-paper/sections/09-agents.tex +106 -0
  32. package/examples/papilot-paper/sections/10-usage.tex +56 -0
  33. package/examples/papilot-paper/sections/11-git.tex +62 -0
  34. package/examples/papilot-paper/sections/12-security.tex +41 -0
  35. package/examples/papilot-paper/sections/13-evaluation.tex +106 -0
  36. package/examples/papilot-paper/sections/14-related.tex +38 -0
  37. package/examples/papilot-paper/sections/15-conclusion.tex +27 -0
  38. package/package.json +85 -4
  39. package/scripts/demo.ts +21 -0
  40. package/scripts/service.ts +35 -0
  41. package/src/notes.ts +40 -0
  42. package/src/server/agents.ts +343 -0
  43. package/src/server/codex.ts +63 -0
  44. package/src/server/frontend.ts +15 -0
  45. package/src/server/main.ts +202 -0
  46. package/src/server/manuscript.ts +337 -0
  47. package/src/server/paths.ts +11 -0
  48. package/src/server/pdf.ts +27 -0
  49. package/src/server/review.ts +53 -0
  50. package/src/server/security.ts +15 -0
  51. package/src/server/store.ts +60 -0
  52. package/src/server/workspace.ts +530 -0
  53. package/src/shared.ts +28 -0
  54. package/vendor/latex-review/LICENSE +21 -0
  55. package/vendor/latex-review/dist/web/assets/TeXGyrePagellaX-Bold-CEtYdOXj.otf +0 -0
  56. package/vendor/latex-review/dist/web/assets/TeXGyrePagellaX-Regular-DQJjZE_L.otf +0 -0
  57. package/vendor/latex-review/dist/web/assets/index-DyzYnIGk.css +1 -0
  58. package/vendor/latex-review/dist/web/assets/index-HxBK-dls.js +19 -0
  59. package/vendor/latex-review/dist/web/index.html +18 -0
  60. package/vendor/latex-review/package-lock.json +3114 -0
  61. package/vendor/latex-review/package.json +49 -0
  62. package/vendor/latex-review/src/cli.ts +494 -0
  63. package/vendor/latex-review/src/client.ts +198 -0
  64. package/vendor/latex-review/src/core/build.ts +296 -0
  65. package/vendor/latex-review/src/core/changes.ts +126 -0
  66. package/vendor/latex-review/src/core/config.ts +270 -0
  67. package/vendor/latex-review/src/core/diff.ts +54 -0
  68. package/vendor/latex-review/src/core/files.ts +96 -0
  69. package/vendor/latex-review/src/core/git.ts +317 -0
  70. package/vendor/latex-review/src/core/outline.ts +314 -0
  71. package/vendor/latex-review/src/core/process.ts +111 -0
  72. package/vendor/latex-review/src/core/publish.ts +339 -0
  73. package/vendor/latex-review/src/core/review.ts +734 -0
  74. package/vendor/latex-review/src/core/store.ts +66 -0
  75. package/vendor/latex-review/src/core/tasks.ts +237 -0
  76. package/vendor/latex-review/src/render/inline.ts +805 -0
  77. package/vendor/latex-review/src/render/locate.ts +481 -0
  78. package/vendor/latex-review/src/render/pdf.ts +281 -0
  79. package/vendor/latex-review/src/render/pdfdiff.ts +272 -0
  80. package/vendor/latex-review/src/render/round.ts +236 -0
  81. package/vendor/latex-review/src/render/worker.ts +10 -0
  82. package/vendor/latex-review/src/runtime.ts +23 -0
  83. package/vendor/latex-review/src/server.ts +401 -0
  84. package/vendor/latex-review/src/types.ts +283 -0
  85. package/vendor/latex-review/src/web/ChangeMap.tsx +212 -0
  86. package/vendor/latex-review/src/web/PdfStrip.tsx +77 -0
  87. package/vendor/latex-review/src/web/fonts/GUST-FONT-LICENSE.txt +29 -0
  88. package/vendor/latex-review/src/web/fonts/LPPL.txt +415 -0
  89. package/vendor/latex-review/src/web/fonts/MANIFEST-newpx.txt +20 -0
  90. package/vendor/latex-review/src/web/fonts/README-newpx.txt +473 -0
  91. package/vendor/latex-review/src/web/fonts/README.md +12 -0
  92. package/vendor/latex-review/src/web/fonts/TeXGyrePagellaX-Bold.otf +0 -0
  93. package/vendor/latex-review/src/web/fonts/TeXGyrePagellaX-Regular.otf +0 -0
  94. package/vendor/latex-review/src/web/index.html +17 -0
  95. package/vendor/latex-review/src/web/main.tsx +10 -0
  96. package/vendor/latex-review/src/web/model.ts +153 -0
  97. package/vendor/latex-review/src/web/overview.tsx +146 -0
  98. package/vendor/latex-review/src/web/review.tsx +991 -0
  99. package/vendor/latex-review/src/web/style.css +1249 -0
@@ -0,0 +1,1249 @@
1
+ @font-face {
2
+ font-family: "Review Serif";
3
+ src: url("./fonts/TeXGyrePagellaX-Regular.otf") format("opentype");
4
+ font-weight: 400;
5
+ font-display: swap;
6
+ }
7
+ @font-face {
8
+ font-family: "Review Serif";
9
+ src: url("./fonts/TeXGyrePagellaX-Bold.otf") format("opentype");
10
+ font-weight: 700;
11
+ font-display: swap;
12
+ }
13
+ :root {
14
+ color-scheme: light;
15
+ --serif:
16
+ "Review Serif", Palatino, "Palatino Linotype", "Songti SC", Georgia, serif;
17
+ --sans:
18
+ -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Noto Sans",
19
+ sans-serif;
20
+ --frame: #fff;
21
+ --bar: #fff;
22
+ --ink: #171717;
23
+ --muted: #666;
24
+ --line: #e5e5e5;
25
+ --paper: #fff;
26
+ --accent: #356aa0;
27
+ --accept: #1d7448;
28
+ --reject: #b0313b;
29
+ --comment: #356aa0;
30
+ --before: #fbeeee;
31
+ --before-edge: #d17c82;
32
+ --after: #eef8f1;
33
+ --after-edge: #68ab82;
34
+ --head: #fafafa;
35
+ --shadow: 0 1px 2px rgb(0 0 0 / 0.06), 0 4px 18px rgb(0 0 0 / 0.05);
36
+ --paper-top: 24px;
37
+ font: 14px/1.5 var(--sans);
38
+ color: var(--ink);
39
+ background: var(--frame);
40
+ }
41
+
42
+ * {
43
+ box-sizing: border-box;
44
+ }
45
+ body {
46
+ margin: 0;
47
+ height: 100dvh;
48
+ display: grid;
49
+ grid-template-rows: auto 1fr;
50
+ overflow: hidden;
51
+ background: var(--frame);
52
+ text-rendering: optimizeLegibility;
53
+ }
54
+ button,
55
+ input,
56
+ select,
57
+ textarea {
58
+ font: inherit;
59
+ color: inherit;
60
+ }
61
+ button {
62
+ cursor: pointer;
63
+ }
64
+ button:disabled {
65
+ cursor: default;
66
+ opacity: 0.38;
67
+ }
68
+ button:focus-visible,
69
+ a:focus-visible,
70
+ input:focus-visible,
71
+ select:focus-visible {
72
+ outline: 2px solid var(--accent);
73
+ outline-offset: 3px;
74
+ }
75
+ [hidden] {
76
+ display: none !important;
77
+ }
78
+ .muted {
79
+ color: var(--muted);
80
+ }
81
+ a {
82
+ color: var(--accent);
83
+ text-underline-offset: 0.18em;
84
+ }
85
+ h1,
86
+ h2,
87
+ .brand {
88
+ font-family: var(--serif);
89
+ font-weight: 400;
90
+ line-height: 1.3;
91
+ }
92
+ .brand {
93
+ font-size: 20px;
94
+ font-variant-caps: small-caps;
95
+ letter-spacing: 0.02em;
96
+ color: var(--ink);
97
+ text-decoration: none;
98
+ }
99
+ kbd {
100
+ font:
101
+ 600 10px/1 ui-monospace,
102
+ SFMono-Regular,
103
+ Menlo,
104
+ monospace;
105
+ padding: 2px 4px;
106
+ margin-left: 6px;
107
+ border: 1px solid var(--line);
108
+ border-radius: 4px;
109
+ color: var(--muted);
110
+ background: var(--frame);
111
+ vertical-align: 1px;
112
+ }
113
+
114
+ /* Top bar */
115
+ .bar {
116
+ display: flex;
117
+ align-items: center;
118
+ gap: 18px;
119
+ min-height: 62px;
120
+ padding: 10px 24px;
121
+ background: var(--bar);
122
+ border-bottom: 1px solid var(--line);
123
+ z-index: 3;
124
+ }
125
+ .identity {
126
+ display: flex;
127
+ align-items: baseline;
128
+ gap: 10px;
129
+ min-width: 0;
130
+ flex: 1;
131
+ }
132
+ .identity h1 {
133
+ margin: 0;
134
+ font-size: 20px;
135
+ font-variant-caps: small-caps;
136
+ letter-spacing: 0.02em;
137
+ white-space: nowrap;
138
+ overflow: hidden;
139
+ text-overflow: ellipsis;
140
+ }
141
+ .identity span {
142
+ white-space: nowrap;
143
+ font-size: 13px;
144
+ }
145
+ .meter {
146
+ display: flex;
147
+ align-items: center;
148
+ gap: 10px;
149
+ font-size: 12px;
150
+ color: var(--muted);
151
+ white-space: nowrap;
152
+ font-variant-numeric: tabular-nums;
153
+ }
154
+ .track {
155
+ width: 120px;
156
+ height: 2px;
157
+ background: var(--line);
158
+ overflow: hidden;
159
+ }
160
+ .track i {
161
+ display: block;
162
+ height: 100%;
163
+ width: 0;
164
+ background: #999;
165
+ transition: width 0.3s;
166
+ }
167
+ .bar-end {
168
+ display: flex;
169
+ align-items: center;
170
+ gap: 8px;
171
+ }
172
+ .status:empty {
173
+ display: none;
174
+ }
175
+ .status {
176
+ font-size: 12px;
177
+ padding: 3px 9px;
178
+ border-radius: 999px;
179
+ background: var(--head);
180
+ color: var(--muted);
181
+ white-space: nowrap;
182
+ }
183
+ .status[data-state="build_failed"],
184
+ .status[data-state="offline"] {
185
+ color: var(--reject);
186
+ }
187
+ .ghost {
188
+ border: 1px solid transparent;
189
+ background: transparent;
190
+ border-radius: 7px;
191
+ padding: 5px 9px;
192
+ font-size: 13px;
193
+ color: var(--muted);
194
+ }
195
+ .ghost:hover {
196
+ border-color: var(--line);
197
+ color: var(--ink);
198
+ text-decoration: underline;
199
+ text-underline-offset: 0.18em;
200
+ }
201
+ .accept-all,
202
+ .reject-all {
203
+ color: var(--ink);
204
+ border-color: var(--line);
205
+ border-radius: 999px;
206
+ box-shadow: 0 1px 3px rgb(0 0 0 / 0.05);
207
+ }
208
+ .overview-link {
209
+ flex: none;
210
+ text-decoration: none;
211
+ color: var(--accent);
212
+ }
213
+ .ghost.round {
214
+ width: 30px;
215
+ height: 30px;
216
+ padding: 0;
217
+ border-radius: 50%;
218
+ border-color: var(--line);
219
+ }
220
+
221
+ /* Document */
222
+ #paper {
223
+ overflow: auto;
224
+ padding: var(--paper-top) 24px 90px;
225
+ scroll-padding: 70px 0 90px;
226
+ overflow-anchor: none;
227
+ outline: none;
228
+ }
229
+ .document {
230
+ max-width: 980px;
231
+ margin: 0 auto;
232
+ }
233
+ .empty {
234
+ text-align: center;
235
+ color: var(--muted);
236
+ padding: 60px 16px;
237
+ }
238
+ .part + .part {
239
+ margin-top: 30px;
240
+ }
241
+ .part-title {
242
+ font-size: 19px;
243
+ font-weight: 400;
244
+ color: var(--muted);
245
+ margin: 14px 0 18px;
246
+ font-variant-caps: small-caps;
247
+ letter-spacing: 0.02em;
248
+ }
249
+ .part-title .number {
250
+ margin-right: 8px;
251
+ font-variant-numeric: tabular-nums;
252
+ }
253
+ .sheet {
254
+ background: var(--paper);
255
+ box-shadow: var(--shadow);
256
+ border-radius: 3px;
257
+ padding: 10px 0;
258
+ }
259
+ .context,
260
+ .side {
261
+ line-height: 0;
262
+ }
263
+ .document img {
264
+ display: block;
265
+ width: 100%;
266
+ height: auto;
267
+ }
268
+ .fold {
269
+ margin: 4px 0;
270
+ height: 22px;
271
+ display: flex;
272
+ align-items: center;
273
+ justify-content: center;
274
+ color: #9a9d98;
275
+ font-size: 16px;
276
+ letter-spacing: 4px;
277
+ background: repeating-linear-gradient(
278
+ 90deg,
279
+ transparent 0 6px,
280
+ #ececec 6px 12px
281
+ )
282
+ center / 100% 1px no-repeat;
283
+ }
284
+
285
+ .change {
286
+ position: relative;
287
+ scroll-margin: 70px;
288
+ outline: none;
289
+ color: var(--ink);
290
+ }
291
+ .change.standalone {
292
+ background: var(--paper);
293
+ box-shadow: var(--shadow);
294
+ border-radius: 3px;
295
+ margin-bottom: 26px;
296
+ }
297
+ .change.inline {
298
+ margin: 6px 0;
299
+ }
300
+ .change-head {
301
+ display: flex;
302
+ align-items: baseline;
303
+ gap: 10px;
304
+ padding: 8px 12px;
305
+ font-size: 12px;
306
+ line-height: 1.6;
307
+ background: var(--head);
308
+ color: var(--muted);
309
+ border-top: 1px solid var(--line);
310
+ border-bottom: 1px solid var(--line);
311
+ }
312
+ .change-number {
313
+ font-weight: 400;
314
+ color: var(--ink);
315
+ white-space: nowrap;
316
+ }
317
+ .change-where {
318
+ flex: 1;
319
+ min-width: 0;
320
+ overflow: hidden;
321
+ text-overflow: ellipsis;
322
+ white-space: nowrap;
323
+ font:
324
+ 11px/1.8 ui-monospace,
325
+ SFMono-Regular,
326
+ Menlo,
327
+ monospace;
328
+ }
329
+ .change-kind {
330
+ white-space: nowrap;
331
+ }
332
+ .badge {
333
+ font-weight: 600;
334
+ white-space: nowrap;
335
+ }
336
+ .badge:empty {
337
+ display: none;
338
+ }
339
+ .link {
340
+ border: 0;
341
+ background: none;
342
+ padding: 0 2px;
343
+ font-size: 12px;
344
+ color: var(--accent);
345
+ }
346
+ .link.active {
347
+ font-weight: 600;
348
+ text-decoration: underline;
349
+ }
350
+ .edits {
351
+ white-space: nowrap;
352
+ }
353
+ .side {
354
+ position: relative;
355
+ border-left: 2px solid transparent;
356
+ }
357
+ .side.before {
358
+ background: var(--before);
359
+ border-left-color: var(--before-edge);
360
+ }
361
+ .side.after {
362
+ background: var(--after);
363
+ border-left-color: var(--after-edge);
364
+ }
365
+ .side.after.identical {
366
+ background: transparent;
367
+ border-left-color: var(--line);
368
+ }
369
+ .side img {
370
+ mix-blend-mode: multiply;
371
+ }
372
+ .side::after {
373
+ position: absolute;
374
+ top: 4px;
375
+ right: 8px;
376
+ font: 10px/1 var(--sans);
377
+ letter-spacing: 0.06em;
378
+ text-transform: uppercase;
379
+ color: var(--before-edge);
380
+ opacity: 0.9;
381
+ pointer-events: none;
382
+ }
383
+ .side.before::after {
384
+ content: "before";
385
+ }
386
+ .side.after::after {
387
+ content: "after";
388
+ color: var(--after-edge);
389
+ }
390
+ .side.after.identical::after,
391
+ .change[data-resolved] .side::after {
392
+ content: none;
393
+ }
394
+ .caption {
395
+ margin: 0;
396
+ padding: 4px 12px 8px;
397
+ font-size: 12px;
398
+ color: var(--muted);
399
+ }
400
+
401
+ .change.current {
402
+ box-shadow: 0 0 0 2px var(--accent);
403
+ z-index: 1;
404
+ }
405
+ .change.current .change-head {
406
+ background: color-mix(in srgb, var(--accent) 8%, var(--head));
407
+ color: var(--ink);
408
+ }
409
+ .change[data-state="accepted"] .badge {
410
+ color: var(--accept);
411
+ }
412
+ .change[data-state="rejected"] .badge {
413
+ color: var(--reject);
414
+ }
415
+ .change[data-state="commented"] .badge,
416
+ .change[data-state="mixed"] .badge {
417
+ color: var(--comment);
418
+ }
419
+ .change[data-resolved="after"] .side.before,
420
+ .change[data-resolved="before"] .side.after:not(.identical) {
421
+ display: none;
422
+ }
423
+ .change[data-resolved] .side {
424
+ background: transparent;
425
+ border-left-color: transparent;
426
+ }
427
+ .change[data-resolved] .caption {
428
+ display: none;
429
+ }
430
+
431
+ .remark,
432
+ .histories {
433
+ padding: 8px 14px;
434
+ font-size: 13px;
435
+ line-height: 1.55;
436
+ }
437
+ .remark {
438
+ background: color-mix(in srgb, var(--comment) 8%, #fff);
439
+ border-top: 1px solid var(--line);
440
+ color: var(--ink);
441
+ }
442
+ .remark p,
443
+ .histories p {
444
+ margin: 0;
445
+ white-space: pre-wrap;
446
+ }
447
+ .histories {
448
+ background: #f6f7fb;
449
+ border-bottom: 1px solid var(--line);
450
+ color: var(--muted);
451
+ }
452
+ .source {
453
+ padding: 10px 14px 12px;
454
+ background: var(--paper);
455
+ border-top: 1px solid var(--line);
456
+ line-height: 1.5;
457
+ }
458
+ .source-unit + .source-unit {
459
+ margin-top: 12px;
460
+ }
461
+ .source-title {
462
+ display: flex;
463
+ align-items: center;
464
+ gap: 8px;
465
+ font:
466
+ 11px ui-monospace,
467
+ SFMono-Regular,
468
+ Menlo,
469
+ monospace;
470
+ color: #555;
471
+ margin-bottom: 6px;
472
+ }
473
+ .unit-actions {
474
+ margin-left: auto;
475
+ display: flex;
476
+ align-items: center;
477
+ gap: 2px;
478
+ font: 13px var(--sans);
479
+ }
480
+ .unit-actions button {
481
+ border: 1px solid var(--line);
482
+ background: var(--paper);
483
+ border-radius: 0;
484
+ padding: 1px 8px;
485
+ font-weight: 600;
486
+ }
487
+ .unit-actions button:not(:disabled):hover {
488
+ background: var(--frame);
489
+ }
490
+ .unit-actions .accept {
491
+ color: var(--accept);
492
+ }
493
+ .unit-actions .reject {
494
+ color: var(--reject);
495
+ }
496
+ .unit-actions .comment {
497
+ color: var(--comment);
498
+ }
499
+ .unit-state {
500
+ font-weight: 600;
501
+ }
502
+ .source-unit[data-state="accepted"] .unit-state {
503
+ color: var(--accept);
504
+ }
505
+ .source-unit[data-state="rejected"] .unit-state {
506
+ color: var(--reject);
507
+ }
508
+ .source-unit[data-state="commented"] .unit-state {
509
+ color: var(--comment);
510
+ }
511
+ .source-code {
512
+ margin: 0;
513
+ padding: 10px 12px;
514
+ background: #fff;
515
+ border: 1px solid var(--line);
516
+ border-radius: 5px;
517
+ font:
518
+ 12.5px/1.65 ui-monospace,
519
+ SFMono-Regular,
520
+ Menlo,
521
+ monospace;
522
+ white-space: pre-wrap;
523
+ overflow-wrap: anywhere;
524
+ color: #2b2f33;
525
+ max-height: 420px;
526
+ overflow: auto;
527
+ }
528
+ .source-code del {
529
+ background: #fadfe1;
530
+ color: #8e1d28;
531
+ text-decoration: line-through;
532
+ text-decoration-color: #c9636b;
533
+ }
534
+ .source-code ins {
535
+ background: #d6f0df;
536
+ color: #11603a;
537
+ text-decoration: none;
538
+ }
539
+
540
+ /* Messages above the document */
541
+ .banner {
542
+ max-width: 980px;
543
+ margin: 0 auto 14px;
544
+ padding: 10px 14px;
545
+ font-size: 13px;
546
+ background: color-mix(in srgb, var(--accent) 6%, var(--paper));
547
+ border: 1px solid var(--line);
548
+ border-radius: 8px;
549
+ }
550
+ .banner p {
551
+ margin: 3px 0;
552
+ }
553
+ .banner .details {
554
+ margin: 6px 0 2px;
555
+ padding: 8px 10px;
556
+ background: var(--bar);
557
+ border-radius: 5px;
558
+ font:
559
+ 11.5px/1.5 ui-monospace,
560
+ Menlo,
561
+ monospace;
562
+ white-space: pre-wrap;
563
+ max-height: 220px;
564
+ overflow: auto;
565
+ }
566
+ .banner summary {
567
+ cursor: pointer;
568
+ color: var(--muted);
569
+ }
570
+ .waiting {
571
+ text-align: center;
572
+ padding: 90px 16px;
573
+ }
574
+ .waiting p {
575
+ margin: 6px 0;
576
+ }
577
+ .pulse {
578
+ width: 12px;
579
+ height: 12px;
580
+ margin: 0 auto 18px;
581
+ border-radius: 50%;
582
+ background: var(--accent);
583
+ animation: pulse 1.6s ease-in-out infinite;
584
+ }
585
+ @keyframes pulse {
586
+ 0%,
587
+ 100% {
588
+ opacity: 0.25;
589
+ transform: scale(0.8);
590
+ }
591
+ 50% {
592
+ opacity: 1;
593
+ transform: scale(1.15);
594
+ }
595
+ }
596
+ .task-list {
597
+ list-style: none;
598
+ padding: 0;
599
+ margin: 0;
600
+ background: var(--bar);
601
+ border: 1px solid var(--line);
602
+ border-radius: 8px;
603
+ box-shadow: var(--shadow);
604
+ }
605
+ .task-list li + li {
606
+ border-top: 1px solid var(--line);
607
+ }
608
+ .index .document {
609
+ max-width: 880px;
610
+ }
611
+ .overview-heading {
612
+ margin: 32px 0;
613
+ }
614
+ .overview-heading h1 {
615
+ font-size: 34px;
616
+ letter-spacing: 0.02em;
617
+ font-variant-caps: small-caps;
618
+ margin: 0 0 6px;
619
+ }
620
+ .overview-heading p {
621
+ margin: 6px 0;
622
+ }
623
+ .overview-summary {
624
+ font-size: 13px;
625
+ color: var(--muted);
626
+ }
627
+ .task-tools {
628
+ display: flex;
629
+ gap: 10px;
630
+ margin-bottom: 16px;
631
+ }
632
+ .task-tools input,
633
+ .task-tools select {
634
+ font: inherit;
635
+ color: var(--ink);
636
+ background: var(--bar);
637
+ border: 1px solid var(--line);
638
+ border-radius: 7px;
639
+ padding: 9px 12px;
640
+ }
641
+ .task-tools input {
642
+ flex: 1;
643
+ min-width: 0;
644
+ }
645
+ .task-tools input::placeholder {
646
+ color: var(--muted);
647
+ }
648
+ .task-card {
649
+ display: block;
650
+ padding: 24px 20px;
651
+ border-radius: 7px;
652
+ color: var(--ink);
653
+ text-decoration: none;
654
+ }
655
+ .task-card:hover {
656
+ background: var(--head);
657
+ }
658
+ .task-card:focus-visible,
659
+ .overview-link:focus-visible,
660
+ .task-tools :focus-visible {
661
+ outline: 2px solid var(--accent);
662
+ outline-offset: 2px;
663
+ }
664
+ .task-heading {
665
+ display: flex;
666
+ align-items: baseline;
667
+ justify-content: space-between;
668
+ gap: 10px;
669
+ }
670
+ .task-heading h2 {
671
+ margin: 0;
672
+ font-size: 21px;
673
+ font-weight: 400;
674
+ overflow-wrap: anywhere;
675
+ }
676
+ .task-meta {
677
+ display: flex;
678
+ flex-wrap: wrap;
679
+ gap: 4px 14px;
680
+ margin-top: 5px;
681
+ color: var(--muted);
682
+ font-size: 12px;
683
+ }
684
+ .task-name {
685
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
686
+ overflow-wrap: anywhere;
687
+ }
688
+ .task-progress {
689
+ display: flex;
690
+ align-items: center;
691
+ gap: 10px;
692
+ margin-top: 14px;
693
+ color: var(--muted);
694
+ font-size: 12px;
695
+ }
696
+ .task-progress .track {
697
+ width: 140px;
698
+ }
699
+ .task-footer {
700
+ display: flex;
701
+ justify-content: space-between;
702
+ align-items: baseline;
703
+ gap: 10px;
704
+ margin-top: 9px;
705
+ font-size: 12px;
706
+ }
707
+ .task-counts {
708
+ display: flex;
709
+ flex-wrap: wrap;
710
+ gap: 4px 14px;
711
+ color: var(--muted);
712
+ }
713
+ .task-counts [data-kind="pending"] {
714
+ color: var(--accent);
715
+ font-weight: 600;
716
+ }
717
+ .task-counts [data-kind="commented"] {
718
+ color: var(--comment);
719
+ }
720
+ .task-open {
721
+ flex: none;
722
+ color: var(--accent);
723
+ font-weight: 600;
724
+ }
725
+
726
+ /* Action bar */
727
+ .actions {
728
+ position: fixed;
729
+ left: 50%;
730
+ bottom: 22px;
731
+ transform: translateX(-50%);
732
+ z-index: 4;
733
+ display: flex;
734
+ align-items: center;
735
+ gap: 2px;
736
+ padding: 5px;
737
+ max-width: calc(100vw - 24px);
738
+ background: var(--bar);
739
+ border: 1px solid var(--line);
740
+ border-radius: 12px;
741
+ box-shadow: var(--shadow);
742
+ }
743
+ .actions button {
744
+ border: 0;
745
+ background: transparent;
746
+ border-radius: 8px;
747
+ padding: 9px 14px;
748
+ font-size: 14px;
749
+ white-space: nowrap;
750
+ }
751
+ .actions button:not(:disabled):hover {
752
+ background: var(--head);
753
+ }
754
+ .actions .nav {
755
+ font-size: 20px;
756
+ line-height: 1;
757
+ padding: 6px 12px;
758
+ color: var(--muted);
759
+ }
760
+ .actions .accept {
761
+ color: var(--accept);
762
+ }
763
+ .actions .reject {
764
+ color: var(--reject);
765
+ }
766
+ .actions .comment {
767
+ color: var(--comment);
768
+ }
769
+ .actions .skip {
770
+ font-weight: 600;
771
+ }
772
+ .actions .undo {
773
+ font-size: 13px;
774
+ color: var(--muted);
775
+ border-left: 1px solid var(--line);
776
+ border-radius: 0 8px 8px 0;
777
+ margin-left: 4px;
778
+ }
779
+ .actions .working {
780
+ opacity: 0.55;
781
+ }
782
+ .position {
783
+ min-width: 52px;
784
+ text-align: center;
785
+ font-size: 12px;
786
+ color: var(--muted);
787
+ font-variant-numeric: tabular-nums;
788
+ }
789
+ .complete {
790
+ padding: 0 14px;
791
+ font-size: 13px;
792
+ color: var(--muted);
793
+ white-space: nowrap;
794
+ }
795
+
796
+ /* Keep the current change's tools visible while reading a long passage. */
797
+ .change.current > .change-head {
798
+ position: sticky;
799
+ top: calc(-1 * var(--paper-top));
800
+ z-index: 4;
801
+ }
802
+ .change-head .dock {
803
+ display: flex;
804
+ align-items: center;
805
+ flex: none;
806
+ margin: 0;
807
+ }
808
+ .change-head .actions {
809
+ position: static;
810
+ transform: none;
811
+ max-width: none;
812
+ padding: 3px;
813
+ gap: 0;
814
+ background: var(--bar);
815
+ border: 1px solid var(--line);
816
+ border-radius: 10px;
817
+ box-shadow:
818
+ 0 1px 2px rgb(0 0 0 / 0.08),
819
+ 0 6px 20px rgb(0 0 0 / 0.12);
820
+ }
821
+ .change-head .actions button {
822
+ padding: 4px 8px;
823
+ font-size: 13px;
824
+ line-height: 1.5;
825
+ }
826
+ .change-head .actions .nav {
827
+ font-size: 17px;
828
+ padding: 2px 8px;
829
+ }
830
+ .change-head .actions .undo {
831
+ font-size: 12px;
832
+ margin-left: 3px;
833
+ padding: 4px 10px;
834
+ }
835
+ .change-head .position {
836
+ min-width: 40px;
837
+ font-size: 11.5px;
838
+ }
839
+ .change-head .complete {
840
+ padding: 0 8px;
841
+ font-size: 12px;
842
+ }
843
+ .change-head .composer {
844
+ position: absolute;
845
+ top: calc(100% + 6px);
846
+ right: 8px;
847
+ left: auto;
848
+ bottom: auto;
849
+ transform: none;
850
+ width: min(380px, calc(100vw - 24px));
851
+ }
852
+
853
+ .composer {
854
+ position: fixed;
855
+ left: 50%;
856
+ bottom: 84px;
857
+ transform: translateX(-50%);
858
+ z-index: 5;
859
+ width: min(540px, calc(100vw - 24px));
860
+ padding: 12px;
861
+ background: var(--bar);
862
+ border: 1px solid var(--line);
863
+ border-radius: 12px;
864
+ box-shadow: 0 6px 24px rgb(0 0 0 / 0.08);
865
+ }
866
+ .composer label {
867
+ display: block;
868
+ font-size: 17px;
869
+ font-weight: 400;
870
+ color: var(--ink);
871
+ margin-bottom: 6px;
872
+ }
873
+ .composer textarea {
874
+ width: 100%;
875
+ resize: vertical;
876
+ min-height: 84px;
877
+ padding: 8px 10px;
878
+ border: 1px solid var(--line);
879
+ border-radius: 7px;
880
+ background: var(--paper);
881
+ color: #1f2328;
882
+ }
883
+ .composer textarea:focus {
884
+ outline: 2px solid color-mix(in srgb, var(--comment) 45%, transparent);
885
+ border-color: transparent;
886
+ }
887
+ .composer-row {
888
+ display: flex;
889
+ align-items: center;
890
+ justify-content: space-between;
891
+ margin-top: 8px;
892
+ font-size: 12px;
893
+ }
894
+ .composer-row kbd {
895
+ margin-left: 0;
896
+ }
897
+ .composer button {
898
+ border: 1px solid var(--line);
899
+ border-radius: 7px;
900
+ padding: 6px 16px;
901
+ background: var(--paper);
902
+ color: var(--ink);
903
+ }
904
+
905
+ .toast {
906
+ position: fixed;
907
+ top: 74px;
908
+ left: 50%;
909
+ transform: translateX(-50%);
910
+ z-index: 6;
911
+ max-width: min(640px, calc(100vw - 24px));
912
+ padding: 9px 14px;
913
+ border: 1px solid var(--line);
914
+ background: var(--paper);
915
+ color: var(--ink);
916
+ font-size: 13px;
917
+ box-shadow: 0 3px 12px rgb(0 0 0 / 0.06);
918
+ white-space: pre-wrap;
919
+ }
920
+ .toast.error {
921
+ background: #7f2b31;
922
+ }
923
+
924
+ dialog {
925
+ border: 1px solid var(--line);
926
+ border-radius: 12px;
927
+ box-shadow: var(--shadow);
928
+ padding: 20px 24px;
929
+ background: var(--bar);
930
+ color: var(--ink);
931
+ max-width: min(460px, calc(100vw - 32px));
932
+ }
933
+ dialog::backdrop {
934
+ background: rgb(0 0 0 / 0.25);
935
+ }
936
+ dialog h2 {
937
+ font-size: 23px;
938
+ margin: 0 0 12px;
939
+ }
940
+ dialog dl {
941
+ display: grid;
942
+ grid-template-columns: auto 1fr;
943
+ gap: 8px 16px;
944
+ margin: 0 0 12px;
945
+ font-size: 13px;
946
+ }
947
+ dialog dt {
948
+ white-space: nowrap;
949
+ }
950
+ dialog dt kbd {
951
+ margin: 0 2px 0 0;
952
+ }
953
+ dialog dd {
954
+ margin: 0;
955
+ }
956
+ dialog form {
957
+ text-align: right;
958
+ }
959
+ dialog button {
960
+ border: 1px solid var(--line);
961
+ background: var(--frame);
962
+ border-radius: 7px;
963
+ padding: 5px 14px;
964
+ }
965
+
966
+ @media (max-width: 720px) {
967
+ .bar {
968
+ display: grid;
969
+ grid-template-columns: auto 1fr auto;
970
+ gap: 8px;
971
+ padding: 12px 16px;
972
+ }
973
+ .identity {
974
+ grid-column: 1 / -1;
975
+ grid-row: 1;
976
+ }
977
+ .bar .meter {
978
+ justify-self: center;
979
+ font-size: 11px;
980
+ }
981
+ .bar-end {
982
+ gap: 2px;
983
+ }
984
+ .bar .ghost {
985
+ padding: 4px 2px;
986
+ font-size: 12px;
987
+ }
988
+ .side {
989
+ min-height: 20px;
990
+ }
991
+ .track {
992
+ width: 70px;
993
+ }
994
+ .actions button {
995
+ padding: 9px 9px;
996
+ }
997
+ .change-head {
998
+ flex-wrap: wrap;
999
+ }
1000
+ .change-head .dock {
1001
+ order: 9;
1002
+ flex-basis: 100%;
1003
+ justify-content: center;
1004
+ margin: 4px 0 2px;
1005
+ }
1006
+ .change-head .composer {
1007
+ right: 0;
1008
+ width: calc(100vw - 24px);
1009
+ }
1010
+ :root {
1011
+ --paper-top: 10px;
1012
+ }
1013
+ #paper {
1014
+ padding: var(--paper-top) 6px 90px;
1015
+ }
1016
+ #paper.index {
1017
+ padding: 10px 14px 40px;
1018
+ }
1019
+ .overview-heading {
1020
+ margin-top: 16px;
1021
+ }
1022
+ .task-tools {
1023
+ flex-wrap: wrap;
1024
+ }
1025
+ .task-tools input {
1026
+ flex-basis: 100%;
1027
+ }
1028
+ .task-tools select {
1029
+ width: 100%;
1030
+ }
1031
+ .task-card {
1032
+ padding: 14px;
1033
+ }
1034
+ .task-heading {
1035
+ flex-direction: column;
1036
+ gap: 6px;
1037
+ }
1038
+ }
1039
+ @media (prefers-reduced-motion: reduce) {
1040
+ * {
1041
+ scroll-behavior: auto !important;
1042
+ animation: none !important;
1043
+ transition: none !important;
1044
+ }
1045
+ }
1046
+ /* React owns the document tree; the glyph layer keeps the vector PDF selectable. */
1047
+ body {
1048
+ display: block;
1049
+ }
1050
+ #root {
1051
+ height: 100dvh;
1052
+ display: grid;
1053
+ grid-template-rows: auto 1fr;
1054
+ overflow: hidden;
1055
+ }
1056
+ .review-body {
1057
+ position: relative;
1058
+ min-height: 0;
1059
+ }
1060
+ .review-body > #paper {
1061
+ height: 100%;
1062
+ padding-right: 54px;
1063
+ scrollbar-width: none;
1064
+ }
1065
+ .review-body > #paper::-webkit-scrollbar {
1066
+ display: none;
1067
+ }
1068
+ .change-map {
1069
+ position: absolute;
1070
+ top: 12px;
1071
+ right: 18px;
1072
+ bottom: 12px;
1073
+ width: 22px;
1074
+ z-index: 5;
1075
+ border: 1px solid var(--line);
1076
+ border-radius: 7px;
1077
+ background: #fafafa;
1078
+ box-shadow: 0 1px 4px rgb(0 0 0 / 0.05);
1079
+ touch-action: none;
1080
+ user-select: none;
1081
+ }
1082
+ .change-map-viewport {
1083
+ position: absolute;
1084
+ left: 0;
1085
+ right: 0;
1086
+ border: 1px solid #c6c9cc;
1087
+ border-radius: 5px;
1088
+ background: rgb(106 111 116 / 0.11);
1089
+ cursor: grab;
1090
+ }
1091
+ .change-map-viewport:active {
1092
+ cursor: grabbing;
1093
+ }
1094
+ .change-map-mark {
1095
+ --mark: #b18a3c;
1096
+ position: absolute;
1097
+ left: 5px;
1098
+ width: calc(100% - 10px);
1099
+ min-height: 0;
1100
+ padding: 0;
1101
+ border: 0;
1102
+ border-radius: 2px;
1103
+ background: var(--mark);
1104
+ }
1105
+ .change-map-mark[data-state="accepted"] {
1106
+ --mark: var(--accept);
1107
+ }
1108
+ .change-map-mark[data-state="rejected"] {
1109
+ --mark: var(--reject);
1110
+ }
1111
+ .change-map-mark[data-state="commented"] {
1112
+ --mark: var(--comment);
1113
+ }
1114
+ .change-map-mark[data-state="mixed"] {
1115
+ --mark: #796195;
1116
+ }
1117
+ .change-map-mark[aria-current] {
1118
+ outline: 2px solid var(--ink);
1119
+ outline-offset: 2px;
1120
+ }
1121
+ .change-map-mark:hover,
1122
+ .change-map-mark:focus-visible {
1123
+ z-index: 1;
1124
+ outline: 2px solid var(--accent);
1125
+ outline-offset: 2px;
1126
+ }
1127
+ .change-map-tooltip {
1128
+ position: absolute;
1129
+ right: calc(100% + 12px);
1130
+ top: 0;
1131
+ width: max-content;
1132
+ max-width: min(360px, calc(100vw - 64px));
1133
+ padding: 7px 10px;
1134
+ border: 1px solid var(--line);
1135
+ border-radius: 7px;
1136
+ background: var(--paper);
1137
+ box-shadow: var(--shadow);
1138
+ color: var(--ink);
1139
+ font: 12px/1.5 var(--sans);
1140
+ text-align: left;
1141
+ overflow-wrap: anywhere;
1142
+ pointer-events: none;
1143
+ visibility: hidden;
1144
+ }
1145
+ .change-map-mark:hover .change-map-tooltip,
1146
+ .change-map-mark:focus-visible .change-map-tooltip {
1147
+ visibility: visible;
1148
+ }
1149
+ @media (max-width: 720px) {
1150
+ .review-body > #paper {
1151
+ padding-right: 46px;
1152
+ }
1153
+ .change-map {
1154
+ right: 16px;
1155
+ width: 18px;
1156
+ }
1157
+ .change-map-mark {
1158
+ left: 3px;
1159
+ width: calc(100% - 6px);
1160
+ }
1161
+ .change-head .actions {
1162
+ max-width: 100%;
1163
+ flex-wrap: wrap;
1164
+ justify-content: center;
1165
+ }
1166
+ .change-head .actions button {
1167
+ padding: 4px 6px;
1168
+ font-size: 12px;
1169
+ }
1170
+ .change-head .actions .nav {
1171
+ padding: 2px 6px;
1172
+ }
1173
+ .change-head .position {
1174
+ min-width: 32px;
1175
+ }
1176
+ }
1177
+ .pdf-strip {
1178
+ position: relative;
1179
+ width: 100%;
1180
+ container-type: inline-size;
1181
+ isolation: isolate;
1182
+ }
1183
+ .pdf-strip img {
1184
+ position: absolute;
1185
+ inset: 0;
1186
+ user-select: none;
1187
+ pointer-events: none;
1188
+ }
1189
+ .pdf-text {
1190
+ position: absolute;
1191
+ inset: 0;
1192
+ overflow: hidden;
1193
+ color: transparent;
1194
+ user-select: text;
1195
+ -webkit-user-select: text;
1196
+ cursor: text;
1197
+ line-height: 1;
1198
+ }
1199
+ .pdf-text-line {
1200
+ white-space: pre;
1201
+ }
1202
+ .pdf-glyph {
1203
+ position: absolute;
1204
+ font-family: "Times New Roman", serif;
1205
+ font-weight: normal;
1206
+ line-height: 1;
1207
+ white-space: pre;
1208
+ transform-origin: 0 0;
1209
+ color: transparent;
1210
+ }
1211
+ .pdf-glyph::selection {
1212
+ background: rgb(67 126 231 / 0.35);
1213
+ color: transparent;
1214
+ }
1215
+ .copy-reference {
1216
+ white-space: nowrap;
1217
+ }
1218
+ .change-head {
1219
+ flex-wrap: wrap;
1220
+ }
1221
+ .change-head .change-where {
1222
+ min-width: 160px;
1223
+ }
1224
+ .document .source-unit button {
1225
+ line-height: 1.5;
1226
+ }
1227
+ .help-backdrop {
1228
+ position: fixed;
1229
+ inset: 0;
1230
+ background: rgb(0 0 0 / 0.25);
1231
+ z-index: 8;
1232
+ display: grid;
1233
+ place-items: center;
1234
+ }
1235
+ .help-backdrop dialog {
1236
+ position: static;
1237
+ margin: 0;
1238
+ }
1239
+ .composer {
1240
+ line-height: 1.5;
1241
+ }
1242
+ @media (max-width: 900px) {
1243
+ .change-head .dock {
1244
+ order: 9;
1245
+ flex-basis: 100%;
1246
+ justify-content: center;
1247
+ margin: 4px 0 2px;
1248
+ }
1249
+ }