proctolog 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +23 -0
  3. data/README.md +178 -0
  4. data/app/controllers/proctolog/acceptances_controller.rb +29 -0
  5. data/app/controllers/proctolog/application_controller.rb +32 -0
  6. data/app/controllers/proctolog/bursts_controller.rb +34 -0
  7. data/app/controllers/proctolog/choices_controller.rb +30 -0
  8. data/app/controllers/proctolog/code_reviews_controller.rb +26 -0
  9. data/app/controllers/proctolog/decisions_controller.rb +33 -0
  10. data/app/controllers/proctolog/entries_controller.rb +14 -0
  11. data/app/controllers/proctolog/evidence_controller.rb +23 -0
  12. data/app/controllers/proctolog/freshness_controller.rb +27 -0
  13. data/app/controllers/proctolog/good_to_go_controller.rb +29 -0
  14. data/app/controllers/proctolog/memberships_controller.rb +20 -0
  15. data/app/controllers/proctolog/mentions_controller.rb +16 -0
  16. data/app/controllers/proctolog/moments_controller.rb +26 -0
  17. data/app/controllers/proctolog/note_params.rb +24 -0
  18. data/app/controllers/proctolog/notes_controller.rb +56 -0
  19. data/app/controllers/proctolog/open_pull_requests_controller.rb +59 -0
  20. data/app/controllers/proctolog/pictures_controller.rb +27 -0
  21. data/app/controllers/proctolog/prompts_controller.rb +28 -0
  22. data/app/controllers/proctolog/pull_request_scoped.rb +21 -0
  23. data/app/controllers/proctolog/pull_requests_controller.rb +34 -0
  24. data/app/controllers/proctolog/put_away_controller.rb +19 -0
  25. data/app/controllers/proctolog/recordings_controller.rb +28 -0
  26. data/app/controllers/proctolog/rendered_pieces_controller.rb +11 -0
  27. data/app/controllers/proctolog/review_data_controller.rb +12 -0
  28. data/app/controllers/proctolog/rules_controller.rb +20 -0
  29. data/app/controllers/proctolog/scenario_notes_controller.rb +26 -0
  30. data/app/controllers/proctolog/scenario_scoped.rb +21 -0
  31. data/app/controllers/proctolog/scenarios_controller.rb +67 -0
  32. data/app/controllers/proctolog/sitting_servers_controller.rb +30 -0
  33. data/app/controllers/proctolog/waiting_controller.rb +14 -0
  34. data/app/controllers/proctolog/with_decisions.rb +28 -0
  35. data/app/helpers/proctolog/bursts_helper.rb +52 -0
  36. data/app/helpers/proctolog/decisions_helper.rb +102 -0
  37. data/app/helpers/proctolog/desk_helper.rb +61 -0
  38. data/app/helpers/proctolog/mentions_helper.rb +27 -0
  39. data/app/helpers/proctolog/open_pull_requests_helper.rb +31 -0
  40. data/app/helpers/proctolog/prompts_helper.rb +21 -0
  41. data/app/helpers/proctolog/pull_requests_helper.rb +67 -0
  42. data/app/helpers/proctolog/recordings_helper.rb +30 -0
  43. data/app/helpers/proctolog/rounds_helper.rb +27 -0
  44. data/app/helpers/proctolog/scenarios_helper.rb +123 -0
  45. data/app/helpers/proctolog/standings_helper.rb +80 -0
  46. data/app/jobs/proctolog/application_job.rb +8 -0
  47. data/app/jobs/proctolog/ask_for_release_job.rb +9 -0
  48. data/app/jobs/proctolog/fetch_pictures_ahead_job.rb +36 -0
  49. data/app/jobs/proctolog/prune_fresh_profiles_job.rb +9 -0
  50. data/app/jobs/proctolog/read_mentions_ahead_job.rb +12 -0
  51. data/app/models/proctolog/acceptance.rb +47 -0
  52. data/app/models/proctolog/app.rb +92 -0
  53. data/app/models/proctolog/browser.rb +42 -0
  54. data/app/models/proctolog/burst.rb +268 -0
  55. data/app/models/proctolog/burst_notices.rb +143 -0
  56. data/app/models/proctolog/chapters.rb +42 -0
  57. data/app/models/proctolog/check.rb +122 -0
  58. data/app/models/proctolog/choices.rb +112 -0
  59. data/app/models/proctolog/code_review.rb +251 -0
  60. data/app/models/proctolog/decision_record.rb +12 -0
  61. data/app/models/proctolog/decisions.rb +199 -0
  62. data/app/models/proctolog/description.rb +165 -0
  63. data/app/models/proctolog/difference.rb +138 -0
  64. data/app/models/proctolog/doctor.rb +127 -0
  65. data/app/models/proctolog/evidence.rb +29 -0
  66. data/app/models/proctolog/failure.rb +7 -0
  67. data/app/models/proctolog/focus.rb +48 -0
  68. data/app/models/proctolog/fresh_sitting.rb +35 -0
  69. data/app/models/proctolog/github.rb +353 -0
  70. data/app/models/proctolog/handover/brief.rb +138 -0
  71. data/app/models/proctolog/handover/layers.rb +128 -0
  72. data/app/models/proctolog/handover/places.rb +98 -0
  73. data/app/models/proctolog/handover/taken.rb +41 -0
  74. data/app/models/proctolog/handover/worklist.rb +35 -0
  75. data/app/models/proctolog/handover.rb +123 -0
  76. data/app/models/proctolog/housekeeping.rb +23 -0
  77. data/app/models/proctolog/kit.rb +36 -0
  78. data/app/models/proctolog/marks.rb +130 -0
  79. data/app/models/proctolog/membership.rb +91 -0
  80. data/app/models/proctolog/mentions.rb +117 -0
  81. data/app/models/proctolog/note.rb +94 -0
  82. data/app/models/proctolog/outside.rb +45 -0
  83. data/app/models/proctolog/overlay/brief.rb +52 -0
  84. data/app/models/proctolog/overlay/written.rb +33 -0
  85. data/app/models/proctolog/overlay.rb +87 -0
  86. data/app/models/proctolog/owner.rb +16 -0
  87. data/app/models/proctolog/pick.rb +47 -0
  88. data/app/models/proctolog/picture.rb +138 -0
  89. data/app/models/proctolog/pieces_rendering.rb +40 -0
  90. data/app/models/proctolog/project.rb +118 -0
  91. data/app/models/proctolog/pull_request.rb +89 -0
  92. data/app/models/proctolog/recording.rb +194 -0
  93. data/app/models/proctolog/release.rb +59 -0
  94. data/app/models/proctolog/rendering.rb +303 -0
  95. data/app/models/proctolog/reports.rb +66 -0
  96. data/app/models/proctolog/response_files.rb +55 -0
  97. data/app/models/proctolog/rounds.rb +305 -0
  98. data/app/models/proctolog/route.rb +151 -0
  99. data/app/models/proctolog/rules.rb +121 -0
  100. data/app/models/proctolog/scenario.rb +126 -0
  101. data/app/models/proctolog/server.rb +273 -0
  102. data/app/models/proctolog/since.rb +108 -0
  103. data/app/models/proctolog/size.rb +30 -0
  104. data/app/models/proctolog/standing.rb +132 -0
  105. data/app/models/proctolog/theme.rb +40 -0
  106. data/app/models/proctolog/unopened/numbers.rb +48 -0
  107. data/app/models/proctolog/unopened/opening.rb +88 -0
  108. data/app/models/proctolog/unopened.rb +203 -0
  109. data/app/models/proctolog/visit.rb +26 -0
  110. data/app/views/layouts/proctolog/application.html.erb +58 -0
  111. data/app/views/proctolog/acceptances/new.html.erb +34 -0
  112. data/app/views/proctolog/bursts/_line.html.erb +28 -0
  113. data/app/views/proctolog/bursts/_merged.html.erb +23 -0
  114. data/app/views/proctolog/bursts/_moved.html.erb +16 -0
  115. data/app/views/proctolog/bursts/_notices.html.erb +39 -0
  116. data/app/views/proctolog/bursts/_put_away.html.erb +11 -0
  117. data/app/views/proctolog/bursts/_rules.html.erb +27 -0
  118. data/app/views/proctolog/bursts/_side.html.erb +49 -0
  119. data/app/views/proctolog/bursts/_side_stop.html.erb +10 -0
  120. data/app/views/proctolog/bursts/show.html.erb +54 -0
  121. data/app/views/proctolog/code_reviews/show.html.erb +33 -0
  122. data/app/views/proctolog/decisions/_alternative.html.erb +5 -0
  123. data/app/views/proctolog/decisions/_beneath.html.erb +21 -0
  124. data/app/views/proctolog/decisions/_box.html.erb +27 -0
  125. data/app/views/proctolog/decisions/_choices.html.erb +9 -0
  126. data/app/views/proctolog/decisions/_draft_tools.html.erb +47 -0
  127. data/app/views/proctolog/decisions/_part.html.erb +61 -0
  128. data/app/views/proctolog/decisions/_round_data.html.erb +1 -0
  129. data/app/views/proctolog/decisions/_theme.html.erb +13 -0
  130. data/app/views/proctolog/decisions/index.html.erb +75 -0
  131. data/app/views/proctolog/notes/_card.html.erb +19 -0
  132. data/app/views/proctolog/notes/_template.html.erb +41 -0
  133. data/app/views/proctolog/open_pull_requests/_side.html.erb +30 -0
  134. data/app/views/proctolog/open_pull_requests/index.html.erb +106 -0
  135. data/app/views/proctolog/prompts/show.html.erb +41 -0
  136. data/app/views/proctolog/pull_requests/_connections.html.erb +65 -0
  137. data/app/views/proctolog/pull_requests/_finish.html.erb +42 -0
  138. data/app/views/proctolog/pull_requests/_margin.html.erb +33 -0
  139. data/app/views/proctolog/pull_requests/_note.html.erb +4 -0
  140. data/app/views/proctolog/pull_requests/_outline.html.erb +26 -0
  141. data/app/views/proctolog/pull_requests/_paragraphs.html.erb +9 -0
  142. data/app/views/proctolog/pull_requests/_scenarios.html.erb +16 -0
  143. data/app/views/proctolog/pull_requests/_since.html.erb +42 -0
  144. data/app/views/proctolog/pull_requests/_standing.html.erb +51 -0
  145. data/app/views/proctolog/pull_requests/_status.html.erb +5 -0
  146. data/app/views/proctolog/pull_requests/_try.html.erb +122 -0
  147. data/app/views/proctolog/pull_requests/show.html.erb +145 -0
  148. data/app/views/proctolog/recordings/_dialog.html.erb +26 -0
  149. data/app/views/proctolog/recordings/_list.html.erb +8 -0
  150. data/app/views/proctolog/recordings/_note.html.erb +22 -0
  151. data/app/views/proctolog/recordings/index.html.erb +33 -0
  152. data/app/views/proctolog/recordings/show.html.erb +118 -0
  153. data/app/views/proctolog/scenarios/_dialog.html.erb +22 -0
  154. data/app/views/proctolog/scenarios/_note.html.erb +18 -0
  155. data/app/views/proctolog/scenarios/_open.html.erb +9 -0
  156. data/app/views/proctolog/scenarios/_scenario.html.erb +48 -0
  157. data/app/views/proctolog/scenarios/_server.html.erb +20 -0
  158. data/app/views/proctolog/scenarios/index.html.erb +62 -0
  159. data/bin/proctolog +330 -0
  160. data/completions/_proctolog +143 -0
  161. data/config/application.rb +94 -0
  162. data/config/database.yml +16 -0
  163. data/config/environment.rb +6 -0
  164. data/config/initializers/grouse.rb +113 -0
  165. data/config/initializers/grouse_notes.rb +9 -0
  166. data/config/keys.yml +6 -0
  167. data/config/routes.rb +71 -0
  168. data/config/storage.yml +4 -0
  169. data/db/migrate/20261019213542_create_grouse_tables.grouse.rb +128 -0
  170. data/db/migrate/20261019213550_create_active_storage_tables.active_storage.rb +58 -0
  171. data/docs/manual/app.md +157 -0
  172. data/docs/manual/bursts.md +129 -0
  173. data/docs/manual/deciding.md +89 -0
  174. data/docs/manual/desk.png +0 -0
  175. data/docs/manual/films.md +20 -0
  176. data/docs/manual/handover.md +93 -0
  177. data/docs/manual/pr-format.md +75 -0
  178. data/docs/manual/reading.md +233 -0
  179. data/docs/manual/unopened.md +80 -0
  180. data/docs/manual/updates.md +55 -0
  181. data/lib/proctolog/installation.rb +125 -0
  182. data/lib/proctolog/version.rb +7 -0
  183. data/public/asking.js +50 -0
  184. data/public/code-review.js +40 -0
  185. data/public/cursor.js +292 -0
  186. data/public/decision-screenshots.js +97 -0
  187. data/public/decisions.css +949 -0
  188. data/public/decisions.js +1289 -0
  189. data/public/desk.css +582 -0
  190. data/public/desk.js +126 -0
  191. data/public/favicon.png +0 -0
  192. data/public/keys.js +228 -0
  193. data/public/mentions.js +389 -0
  194. data/public/messages.js +103 -0
  195. data/public/notes.js +731 -0
  196. data/public/pick.css +99 -0
  197. data/public/plaque.png +0 -0
  198. data/public/pr-number.js +11 -0
  199. data/public/prompt.css +46 -0
  200. data/public/prompt.js +16 -0
  201. data/public/pull_request.css +805 -0
  202. data/public/recording.css +379 -0
  203. data/public/recording.js +394 -0
  204. data/public/release.js +25 -0
  205. data/public/respond.css +260 -0
  206. data/public/respond.js +95 -0
  207. data/public/review-drafts.js +949 -0
  208. data/public/review-rounds.js +1447 -0
  209. data/public/scenarios.css +253 -0
  210. data/public/scenarios.js +36 -0
  211. data/public/schemas/proctolog-response-v1.json +101 -0
  212. data/public/side.js +133 -0
  213. data/public/standing.css +478 -0
  214. data/public/terminal-apl.svg +6 -0
  215. data/public/terminal-cuneiform.svg +3 -0
  216. data/public/terminal-grain-dots.svg +6 -0
  217. data/public/terminal-grain-weave.svg +6 -0
  218. data/public/terminal-grain-wedges.svg +6 -0
  219. data/public/terminal-shades.svg +3 -0
  220. data/public/terminal.css +4426 -0
  221. data/public/toast.js +26 -0
  222. data/public/try.js +124 -0
  223. data/public/viewer.js +808 -0
  224. data/public/words.js +81 -0
  225. data/skills/proctolog-handover/SKILL.md +77 -0
  226. data/skills/proctolog-pr-writing/SKILL.md +228 -0
  227. data/skills/proctolog-pr-writing/references/example-description.md +33 -0
  228. metadata +366 -0
@@ -0,0 +1,4426 @@
1
+ /* The look of the desk, laid over every page last: a terminal's. One fixed
2
+ face, straight rules and square work surfaces; a pane at the left that
3
+ always shows the route, the page beside it, a status line at the foot.
4
+ The sheets before this one lay each page out; this one says what the desk
5
+ is made of, so it names the same tokens they use and overrides their faces. */
6
+
7
+ :root {
8
+ /* The plaque's black ground carries into the pane; charcoal sheets separate
9
+ the work, with grey title plates and shade characters at their edges.
10
+ There is no colour. What the owner is on and
11
+ what waits for them stand in full relief, white and bold; what is settled
12
+ or only said in passing lies back in grey. So the sheets' colours for
13
+ "open", "met" and the kinds of a note all come down to these two. */
14
+ color-scheme: dark;
15
+ --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
16
+ --serif: var(--mono);
17
+ --prose: var(--mono);
18
+ --paper: #141414;
19
+ --panel: #101010;
20
+ --surface: #1d1d1d;
21
+ --surface-head: #2b2b2b;
22
+ --rest: #303030;
23
+ --plate: #cacaca;
24
+ --ink: #ededed;
25
+ --quiet: #ababab;
26
+ --rule: #393939;
27
+ --rule-soft: #292929;
28
+ --rule-strong: #626262;
29
+ --shade-ramp: url("/terminal-shades.svg");
30
+ --apl-seam: url("/terminal-apl.svg");
31
+ --cuneiform: url("/terminal-cuneiform.svg");
32
+ --grain-wedges: url("/terminal-grain-wedges.svg");
33
+ --grain-weave: url("/terminal-grain-weave.svg");
34
+ --grain-dots: url("/terminal-grain-dots.svg");
35
+ --chalk: var(--ink);
36
+ --pin: var(--ink);
37
+ --ok: var(--quiet);
38
+ --met: var(--quiet);
39
+ --waiting: var(--quiet);
40
+ --remark: var(--quiet);
41
+ --change: var(--ink);
42
+ --question: var(--ink);
43
+ --side: 320px;
44
+ --group-gap: 24px;
45
+ --row-pad: 4px;
46
+ --control-gap: 8px;
47
+
48
+ /* One bead, 2.3px across, every 6px: the line round the plaque's figure,
49
+ and the only line the desk draws that is not a hairline. It frames the
50
+ desk, at the pane's edge and over the bar at its foot. */
51
+ --bead: #686868;
52
+ --beads-across: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='5'%3E%3Ccircle cx='3' cy='2.5' r='1.15'/%3E%3C/svg%3E");
53
+ --beads-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='5' height='6'%3E%3Ccircle cx='2.5' cy='3' r='1.15'/%3E%3C/svg%3E");
54
+ }
55
+
56
+ html {
57
+ font-size: 93.75%;
58
+ scrollbar-color: var(--rule) var(--paper);
59
+ }
60
+
61
+ /* The sheets before this one name sans and serif faces of their own, rule by
62
+ rule; here every one of them is the terminal's. */
63
+ body,
64
+ body * {
65
+ border-radius: 0 !important;
66
+ font-family: var(--mono) !important;
67
+ font-style: normal !important;
68
+ }
69
+
70
+ body em,
71
+ body i,
72
+ body cite {
73
+ font-style: italic !important;
74
+ }
75
+
76
+ body {
77
+ font-size: 1rem;
78
+ line-height: 1.6;
79
+ caret-color: var(--pin);
80
+ font-variant-numeric: tabular-nums;
81
+ }
82
+
83
+ button,
84
+ input,
85
+ textarea,
86
+ select {
87
+ box-sizing: border-box;
88
+ }
89
+
90
+ button:disabled {
91
+ cursor: default;
92
+ }
93
+
94
+ input::placeholder,
95
+ textarea::placeholder {
96
+ color: var(--quiet);
97
+ opacity: 1;
98
+ }
99
+
100
+ ::selection {
101
+ background: var(--ink);
102
+ color: var(--paper);
103
+ }
104
+
105
+ :focus-visible {
106
+ outline: 2px solid var(--pin);
107
+ outline-offset: 2px;
108
+ }
109
+
110
+ a {
111
+ text-decoration-thickness: 1px;
112
+ text-underline-offset: 0.22em;
113
+ }
114
+
115
+ h1 {
116
+ font-size: 1.55rem;
117
+ font-weight: 700;
118
+ line-height: 1.3;
119
+ letter-spacing: 0;
120
+ text-wrap: balance;
121
+ }
122
+
123
+ .burst .lede,
124
+ .films-head .tally,
125
+ .main > .empty {
126
+ max-width: 76ch;
127
+ color: var(--quiet);
128
+ font-size: 0.933rem;
129
+ }
130
+
131
+ /* The title plate has a cut corner and a stippled lower edge. Its full width
132
+ belongs to the title, with no ornament that could be mistaken for a control. */
133
+ .burst h1,
134
+ .pull-request h1,
135
+ .films-head h1,
136
+ .film-head h1 {
137
+ position: relative;
138
+ box-sizing: border-box;
139
+ padding: 8px 16px;
140
+ border-block: 1px solid #dedede;
141
+ background: var(--plate);
142
+ color: var(--panel);
143
+ clip-path: polygon(6px 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 0 100%, 0 6px);
144
+ }
145
+
146
+ .burst h1::after,
147
+ .pull-request h1::after,
148
+ .films-head h1::after,
149
+ .film-head h1::after {
150
+ content: "";
151
+ position: absolute;
152
+ right: 0;
153
+ bottom: 0;
154
+ left: 0;
155
+ height: 2px;
156
+ background: #777;
157
+ mask: var(--shade-ramp) left center / 64px 12px repeat-x;
158
+ pointer-events: none;
159
+ }
160
+
161
+ /* The shell: the route at the left, the page beside it */
162
+
163
+ body.shell {
164
+ display: grid;
165
+ grid-template-columns: var(--side) minmax(0, 1fr);
166
+ max-width: none;
167
+ min-height: 100vh;
168
+ margin: 0;
169
+ padding: 0;
170
+ }
171
+
172
+ /* The page beside the pane: one column of reading set off from the pane's
173
+ edge by a gutter, where the cursor's mark stands. The docked list of keys
174
+ takes its room from the foot of the page. */
175
+ body.shell > .main {
176
+ --gutter: 56px;
177
+ position: relative;
178
+ min-width: 0;
179
+ max-width: none;
180
+ padding: 32px 2.6rem max(110px, calc(var(--foot-height, 0px) + 24px)) var(--gutter);
181
+ }
182
+
183
+ .side {
184
+ position: sticky;
185
+ top: 0;
186
+ height: 100vh;
187
+ padding: 0 0 4rem;
188
+ overflow-y: auto;
189
+ background: var(--panel);
190
+ font-size: 0.867rem;
191
+ scrollbar-color: var(--rule) var(--panel);
192
+ }
193
+
194
+ /* The pane's edge is beaded. It stays put while the route scrolls under it. */
195
+ body.shell::before {
196
+ content: "";
197
+ position: fixed;
198
+ z-index: 9;
199
+ top: 0;
200
+ bottom: 0;
201
+ left: calc(var(--side) - 3px);
202
+ width: 5px;
203
+ background: var(--bead);
204
+ mask: var(--beads-down) repeat-y;
205
+ pointer-events: none;
206
+ }
207
+
208
+ .side p,
209
+ .side h2 {
210
+ margin: 0;
211
+ padding: 0 16px;
212
+ }
213
+
214
+ /* The plaque lies on the pane's own ground, the desk's pages beside it. */
215
+
216
+ .side .head {
217
+ display: grid;
218
+ grid-template-columns: 172px minmax(0, 1fr);
219
+ gap: 12px;
220
+ align-items: center;
221
+ padding: 14px 16px 0 14px;
222
+ }
223
+
224
+ .side .plaque {
225
+ display: block;
226
+ width: 172px;
227
+ height: 172px;
228
+ }
229
+
230
+ .side > .name {
231
+ display: grid;
232
+ grid-template-columns: auto minmax(0, 1fr);
233
+ gap: 12px;
234
+ align-items: baseline;
235
+ margin-top: 16px;
236
+ padding-block: 10px;
237
+ border-block: 1px solid var(--rule-soft);
238
+ background: var(--surface);
239
+ color: var(--quiet);
240
+ line-height: 1.4;
241
+ overflow-wrap: anywhere;
242
+ }
243
+
244
+ .side .name a {
245
+ margin: 0;
246
+ color: var(--ink);
247
+ font-size: 1rem;
248
+ font-weight: 700;
249
+ text-decoration: none;
250
+ }
251
+
252
+ .side .overall {
253
+ display: grid;
254
+ gap: 8px;
255
+ margin-top: 8px;
256
+ color: var(--quiet);
257
+ }
258
+
259
+ .side .overall meter {
260
+ width: 100%;
261
+ height: 3px;
262
+ border: 0;
263
+ background: var(--rule);
264
+ }
265
+
266
+ .side .overall meter::-webkit-meter-bar {
267
+ height: 3px;
268
+ background: var(--rule);
269
+ }
270
+
271
+ .side .overall meter::-webkit-meter-optimum-value {
272
+ background: var(--ink);
273
+ }
274
+
275
+ .side .overall meter::-moz-meter-bar {
276
+ background: var(--ink);
277
+ }
278
+
279
+ /* The part the pages are focused on, with the key back to the whole burst. */
280
+
281
+ .side .focus {
282
+ margin: 8px 0 0;
283
+ color: var(--ink);
284
+ font-weight: 700;
285
+ }
286
+
287
+ .side .focus a {
288
+ color: var(--quiet);
289
+ font-weight: 400;
290
+ text-decoration: none;
291
+ }
292
+
293
+ .side .focus a:hover {
294
+ color: var(--ink);
295
+ }
296
+
297
+ .side .focus kbd {
298
+ margin-right: 0.6ch;
299
+ border-color: var(--rule);
300
+ color: var(--quiet);
301
+ }
302
+
303
+ /* How many notices wait at the head of the route: they wait for the owner,
304
+ so they stand in full relief. */
305
+
306
+ .side .notices {
307
+ margin: 8px 0 0;
308
+ }
309
+
310
+ .side .notices a {
311
+ color: var(--ink);
312
+ font-weight: 700;
313
+ text-decoration: none;
314
+ }
315
+
316
+ /* When GitHub was read, whether it has moved on since, and the way to read it again */
317
+
318
+ .side .read {
319
+ display: grid;
320
+ gap: 4px;
321
+ margin-top: var(--group-gap);
322
+ padding: 12px 16px 0;
323
+ border-top: 1px solid var(--rule-soft);
324
+ color: var(--quiet);
325
+ }
326
+
327
+ .side .read p {
328
+ padding: 0;
329
+ }
330
+
331
+ .side .read .moved {
332
+ color: var(--ink);
333
+ font-weight: 700;
334
+ }
335
+
336
+ .side .read .moved[hidden] {
337
+ display: none;
338
+ }
339
+
340
+ .side .read .again {
341
+ color: var(--quiet);
342
+ }
343
+
344
+ .side .read .again:hover {
345
+ color: var(--ink);
346
+ }
347
+
348
+ .side .stops [data-moved] .title::before {
349
+ content: "* ";
350
+ color: var(--ink);
351
+ font-weight: 700;
352
+ }
353
+
354
+ /* A row of the pane held under the pointer: its title in full, its marks in
355
+ words, the way to GitHub. Beside the pane, over the page, and quiet. */
356
+
357
+ .side-card {
358
+ inset: auto;
359
+ width: min(44ch, calc(100vw - 24px));
360
+ margin: 0;
361
+ padding: 10px 14px 12px;
362
+ border: 1px solid var(--rule-strong);
363
+ background: var(--surface);
364
+ color: var(--ink);
365
+ font-size: 0.867rem;
366
+ line-height: 1.45;
367
+ }
368
+
369
+ .side-card .name {
370
+ margin: 0;
371
+ font-weight: 700;
372
+ }
373
+
374
+ .side-card .name .number {
375
+ color: var(--quiet);
376
+ font-weight: 400;
377
+ }
378
+
379
+ .side-card dl {
380
+ display: grid;
381
+ grid-template-columns: max-content 1fr;
382
+ gap: 2px 1.2ch;
383
+ margin: 10px 0 0;
384
+ }
385
+
386
+ .side-card dl div {
387
+ display: contents;
388
+ }
389
+
390
+ .side-card dt {
391
+ color: var(--ink);
392
+ font-weight: 700;
393
+ white-space: pre;
394
+ }
395
+
396
+ .side-card dd {
397
+ margin: 0;
398
+ color: var(--quiet);
399
+ }
400
+
401
+ .side-card .ways {
402
+ display: flex;
403
+ gap: 2ch;
404
+ margin: 10px 0 0;
405
+ padding-top: 8px;
406
+ border-top: 1px solid var(--rule-soft);
407
+ }
408
+
409
+ .side-card .ways a {
410
+ color: var(--quiet);
411
+ }
412
+
413
+ .side-card .ways a:hover {
414
+ color: var(--ink);
415
+ }
416
+
417
+ .side .desk {
418
+ display: grid;
419
+ gap: 2px;
420
+ margin: 0;
421
+ font-size: inherit;
422
+ letter-spacing: 0;
423
+ text-transform: none;
424
+ }
425
+
426
+ .side .desk a {
427
+ display: grid;
428
+ grid-template-columns: 1ch minmax(0, 1fr);
429
+ column-gap: 0.6ch;
430
+ align-items: baseline;
431
+ padding: 2px 6px;
432
+ color: var(--quiet);
433
+ }
434
+
435
+ .side .desk a::before {
436
+ content: "";
437
+ }
438
+
439
+ .side .desk a:hover {
440
+ background: var(--rest);
441
+ color: var(--ink);
442
+ }
443
+
444
+ .side .desk a[aria-current] {
445
+ box-shadow: none;
446
+ background: var(--plate);
447
+ color: var(--panel);
448
+ font-weight: 700;
449
+ }
450
+
451
+ .side .desk a[aria-current]::before {
452
+ content: ">";
453
+ }
454
+
455
+ .side h2 {
456
+ margin-top: var(--group-gap);
457
+ padding: 6px 12px;
458
+ border-block: 1px solid var(--rule-soft);
459
+ background: var(--surface-head);
460
+ color: var(--quiet);
461
+ font-size: 0.8rem;
462
+ font-weight: 600;
463
+ letter-spacing: 0.025em;
464
+ text-transform: uppercase;
465
+ }
466
+
467
+ .side .stops + h2 {
468
+ margin-top: var(--group-gap);
469
+ }
470
+
471
+ .side .stops {
472
+ margin: 0;
473
+ padding: 0;
474
+ list-style: none;
475
+ background: var(--panel);
476
+ }
477
+
478
+ .side .stops li:nth-child(even) {
479
+ background: var(--paper);
480
+ }
481
+
482
+ .side .stops a {
483
+ display: grid;
484
+ grid-template-columns: 1ch 4ch minmax(0, 1fr) auto;
485
+ gap: 0.6ch;
486
+ align-items: baseline;
487
+ padding: 2px 12px;
488
+ border-block: 1px solid transparent;
489
+ color: var(--quiet);
490
+ text-decoration: none;
491
+ white-space: nowrap;
492
+ }
493
+
494
+ .side .stops .mark {
495
+ white-space: pre;
496
+ }
497
+
498
+ .side .stops .title {
499
+ overflow: hidden;
500
+ color: var(--ink);
501
+ text-overflow: ellipsis;
502
+ }
503
+
504
+ .side .stops .number {
505
+ margin: 0;
506
+ color: var(--quiet);
507
+ font-size: 0.8rem;
508
+ text-align: right;
509
+ }
510
+
511
+ .side .stops a:hover {
512
+ background: var(--rest);
513
+ color: var(--ink);
514
+ }
515
+
516
+ .side .stops [aria-current] a {
517
+ border-color: var(--quiet);
518
+ background: var(--rest);
519
+ }
520
+
521
+ .side .stops [aria-current] .number,
522
+ .side .stops [aria-current] .mark {
523
+ color: var(--ink);
524
+ }
525
+
526
+ .side .stops [aria-current] .title {
527
+ color: var(--ink);
528
+ font-weight: 700;
529
+ white-space: normal;
530
+ }
531
+
532
+ .side .stops [aria-current] .fraction {
533
+ border-color: var(--rule-strong);
534
+ color: var(--ink);
535
+ }
536
+
537
+ /* The bars: how far, drawn square */
538
+
539
+ meter,
540
+ .progress meter,
541
+ .progress-line meter {
542
+ border: 1px solid var(--quiet);
543
+ background: none;
544
+ }
545
+
546
+ meter::-webkit-meter-bar,
547
+ .progress meter::-webkit-meter-bar {
548
+ border: 0;
549
+ background: none;
550
+ }
551
+
552
+ meter::-webkit-meter-optimum-value,
553
+ .progress meter::-webkit-meter-optimum-value {
554
+ background: var(--ok);
555
+ }
556
+
557
+ meter::-moz-meter-bar,
558
+ .progress meter::-moz-meter-bar {
559
+ background: var(--ok);
560
+ }
561
+
562
+ /* Controls: a button is a box with its word in it; the main one is inverse */
563
+
564
+ button {
565
+ font-size: inherit;
566
+ }
567
+
568
+ button.quiet,
569
+ .elsewhere button,
570
+ .code-link,
571
+ .session-link {
572
+ padding: 0.12rem 0.7rem;
573
+ border: 1px solid var(--rule);
574
+ background: none;
575
+ color: var(--ink);
576
+ font-size: inherit;
577
+ text-decoration: none;
578
+ }
579
+
580
+ button.quiet:hover,
581
+ .elsewhere button:hover,
582
+ .code-link:hover,
583
+ .session-link:hover {
584
+ border-color: var(--ink);
585
+ background: var(--rest);
586
+ color: var(--ink);
587
+ }
588
+
589
+ /* A link that opens a Claude session, among buttons: its words centred as theirs are. */
590
+ .session-link:not([hidden]) {
591
+ display: inline-flex;
592
+ align-items: center;
593
+ }
594
+
595
+ button.quiet:disabled {
596
+ border-style: dashed;
597
+ color: var(--quiet);
598
+ cursor: default;
599
+ }
600
+
601
+ button.quiet[aria-pressed="true"] {
602
+ border-color: var(--ink);
603
+ background: var(--ink);
604
+ color: var(--paper);
605
+ }
606
+
607
+ button.primary {
608
+ padding: 0.35rem 1rem;
609
+ border: 1px solid var(--ink);
610
+ background: var(--ink);
611
+ color: var(--paper);
612
+ font-weight: 700;
613
+ }
614
+
615
+ button.primary:hover {
616
+ background: var(--pin);
617
+ border-color: var(--pin);
618
+ }
619
+
620
+ input[type="text"],
621
+ textarea,
622
+ select {
623
+ border: 1px solid var(--quiet);
624
+ background: var(--panel);
625
+ color: var(--ink);
626
+ font-size: 1rem;
627
+ }
628
+
629
+ textarea:focus-visible,
630
+ input:focus-visible {
631
+ border-color: var(--pin);
632
+ outline: 1px solid var(--pin);
633
+ outline-offset: 0;
634
+ }
635
+
636
+ kbd {
637
+ display: inline-block;
638
+ box-sizing: border-box;
639
+ min-width: 1.7em;
640
+ padding: 0 0.4em;
641
+ border: 1px solid var(--rule-strong);
642
+ color: var(--ink);
643
+ font-size: 0.8rem;
644
+ line-height: 1.45;
645
+ text-align: center;
646
+ }
647
+
648
+ button.primary kbd {
649
+ border-color: currentcolor;
650
+ color: inherit;
651
+ opacity: 1;
652
+ }
653
+
654
+ /* Marks made of letters, where the sheets before drew dots */
655
+
656
+ /* Whose turn it is is said in words; it is the owner's that stands out. */
657
+ .turn::before,
658
+ .turn[data-turn]::before {
659
+ content: none;
660
+ }
661
+
662
+ .turn {
663
+ color: var(--quiet);
664
+ font-weight: 400;
665
+ }
666
+
667
+ .turn[data-turn="owner"] {
668
+ color: var(--ink);
669
+ font-weight: 700;
670
+ }
671
+
672
+ .progress[data-done="true"] .fraction::after {
673
+ content: " ok";
674
+ color: var(--ok);
675
+ }
676
+
677
+ /* No stripe down a side: a thing that stands apart gets a box of its own */
678
+
679
+ .card,
680
+ .respond {
681
+ border: 1px solid var(--rule);
682
+ }
683
+
684
+ .respond {
685
+ border-color: var(--rule-strong);
686
+ padding: 12px 16px;
687
+ background: var(--surface);
688
+ }
689
+
690
+ .flash,
691
+ .flash.alert,
692
+ .finish,
693
+ .taken-in,
694
+ .unmatched,
695
+ .unreadable,
696
+ [data-stop][aria-current] {
697
+ border: 1px solid var(--rule);
698
+ box-shadow: none;
699
+ }
700
+
701
+ .flash.alert,
702
+ .unreadable {
703
+ border-color: var(--ink);
704
+ }
705
+
706
+ .taken-in,
707
+ .unmatched,
708
+ .unreadable {
709
+ box-sizing: border-box;
710
+ background: none;
711
+ }
712
+
713
+ .finish {
714
+ border-color: var(--ok);
715
+ background: none;
716
+ }
717
+
718
+ [data-stop][aria-current] {
719
+ border-color: var(--ink);
720
+ background: var(--rest);
721
+ }
722
+
723
+ .ledger tr[data-stop][aria-current] {
724
+ border: 0;
725
+ outline: 1px solid var(--ink);
726
+ outline-offset: -1px;
727
+ }
728
+
729
+ /* The foot of the desk: the bar that says where the owner is and the few keys
730
+ that matter there, and above it, once ? has docked it, the list of them all.
731
+ It is beaded along its top, as the pane is along its edge. */
732
+
733
+ .foot {
734
+ position: fixed;
735
+ inset: auto 0 0 0;
736
+ z-index: 8;
737
+ background: var(--panel);
738
+ font-size: 0.867rem;
739
+ }
740
+
741
+ body.shell .foot {
742
+ left: var(--side);
743
+ }
744
+
745
+ .foot::before {
746
+ content: "";
747
+ position: absolute;
748
+ top: -2px;
749
+ right: 0;
750
+ left: 0;
751
+ height: 5px;
752
+ background: var(--bead);
753
+ mask: var(--beads-across) repeat-x;
754
+ }
755
+
756
+ .modebar {
757
+ position: static;
758
+ align-items: center;
759
+ gap: 16px;
760
+ padding: 8px 16px 8px 56px;
761
+ border-top: 0;
762
+ background: none;
763
+ font-size: inherit;
764
+ }
765
+
766
+ .modebar .mode {
767
+ gap: 4px 20px;
768
+ align-items: center;
769
+ }
770
+
771
+ .modebar .mode strong {
772
+ padding: 0 1ch;
773
+ background: var(--ink);
774
+ color: var(--paper);
775
+ font-weight: 700;
776
+ letter-spacing: 0.04em;
777
+ text-transform: uppercase;
778
+ }
779
+
780
+ .modebar kbd,
781
+ .modebar .all-keys {
782
+ border-color: var(--rule-strong);
783
+ background: var(--paper);
784
+ color: var(--ink);
785
+ }
786
+
787
+ .modebar kbd {
788
+ min-width: 2em;
789
+ padding: 1px 0.45em;
790
+ }
791
+
792
+ .modebar kbd + kbd {
793
+ margin-left: 4px;
794
+ }
795
+
796
+ .modebar .all-keys {
797
+ padding: 3px 0.6em;
798
+ border: 1px solid var(--rule-strong);
799
+ font-size: 0.8rem;
800
+ }
801
+
802
+ .modebar .all-keys kbd {
803
+ min-width: 0;
804
+ padding: 0;
805
+ border: 0;
806
+ }
807
+
808
+ .modebar .all-keys:hover {
809
+ border-color: var(--ink);
810
+ color: var(--ink);
811
+ }
812
+
813
+ .modebar .all-keys[aria-expanded="true"] {
814
+ border-color: var(--ink);
815
+ }
816
+
817
+ .keys-help {
818
+ display: grid;
819
+ grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
820
+ gap: 16px 28px;
821
+ width: auto;
822
+ max-height: 46vh;
823
+ padding: 16px 16px 16px 56px;
824
+ overflow-y: auto;
825
+ border: 0;
826
+ border-bottom: 1px solid var(--rule);
827
+ background: none;
828
+ }
829
+
830
+ .keys-help[hidden],
831
+ .keys-help [hidden] {
832
+ display: none;
833
+ }
834
+
835
+ .keys-help h3 {
836
+ margin: 0 0 8px;
837
+ color: var(--quiet);
838
+ font-size: 0.8rem;
839
+ font-weight: 400;
840
+ letter-spacing: 0.04em;
841
+ }
842
+
843
+ .keys-help dl {
844
+ display: grid;
845
+ grid-template-columns: max-content minmax(0, 1fr);
846
+ gap: 3px 1.2ch;
847
+ align-items: baseline;
848
+ }
849
+
850
+ .keys-help dl div {
851
+ display: contents;
852
+ }
853
+
854
+ .keys-help dt kbd + kbd {
855
+ margin-left: 3px;
856
+ }
857
+
858
+ /* The keys of the block the owner is on lead the list, in full relief. */
859
+ .keys-help .this-block dd {
860
+ font-weight: 700;
861
+ }
862
+
863
+ .keys-help .this-block kbd {
864
+ border-color: var(--ink);
865
+ }
866
+
867
+ .toast {
868
+ right: 1.1rem;
869
+ bottom: calc(var(--foot-height, 2.2rem) + 0.6rem);
870
+ border: 1px solid var(--ink);
871
+ background: var(--ink);
872
+ color: var(--paper);
873
+ font-size: 0.9rem;
874
+ }
875
+
876
+ /* What the desk said lately, where the toast said it, newest first. */
877
+
878
+ .messages {
879
+ inset: auto 1.1rem calc(var(--foot-height, 2.2rem) + 0.6rem) auto;
880
+ width: min(64ch, calc(100vw - 2.2rem));
881
+ max-height: 60vh;
882
+ margin: 0;
883
+ padding: 12px 16px;
884
+ overflow-y: auto;
885
+ border: 1px solid var(--ink);
886
+ background: var(--paper);
887
+ color: var(--ink);
888
+ font-size: 0.867rem;
889
+ }
890
+
891
+ .messages h3 {
892
+ margin: 0 0 8px;
893
+ color: var(--quiet);
894
+ font-size: 0.8rem;
895
+ font-weight: 400;
896
+ letter-spacing: 0.04em;
897
+ }
898
+
899
+ .messages ol {
900
+ margin: 0;
901
+ padding: 0;
902
+ list-style: none;
903
+ }
904
+
905
+ .messages li {
906
+ padding: 6px 0;
907
+ border-top: 1px solid var(--rule);
908
+ }
909
+
910
+ .messages li p {
911
+ margin: 0;
912
+ white-space: pre-line;
913
+ }
914
+
915
+ .messages .where,
916
+ .messages .none {
917
+ color: var(--quiet);
918
+ font-size: 0.8rem;
919
+ }
920
+
921
+ .messages .where a {
922
+ color: inherit;
923
+ }
924
+
925
+ .draft-tools .data {
926
+ border: 1px solid var(--ink);
927
+ box-shadow: none;
928
+ }
929
+
930
+ .draft-tools .data h2 {
931
+ font-size: 1.1rem;
932
+ font-weight: 700;
933
+ }
934
+
935
+ /* A picture looked at closely: the whole window, the picture on a dark stage */
936
+
937
+ .viewer {
938
+ width: 100vw;
939
+ max-width: none;
940
+ height: 100vh;
941
+ max-height: none;
942
+ margin: 0;
943
+ padding: 0;
944
+ border: 0;
945
+ background: var(--paper);
946
+ color: var(--ink);
947
+ }
948
+
949
+ .viewer[open] {
950
+ display: grid;
951
+ grid-template-rows: minmax(0, 1fr) auto auto auto;
952
+ }
953
+
954
+ .viewer .stage {
955
+ position: relative;
956
+ overflow: hidden;
957
+ cursor: crosshair;
958
+ touch-action: none;
959
+ }
960
+
961
+ .viewer .stage[data-zoomed="true"] {
962
+ cursor: grab;
963
+ }
964
+
965
+ /* What is looked at, laid in its own pixels and moved and scaled as one: a
966
+ picture, or a pair's halves side by side or one over the other. */
967
+ .viewer .canvas {
968
+ position: absolute;
969
+ top: 0;
970
+ left: 0;
971
+ transform-origin: 0 0;
972
+ isolation: isolate;
973
+ }
974
+
975
+ .viewer img {
976
+ position: absolute;
977
+ top: 0;
978
+ left: 0;
979
+ max-width: none;
980
+ user-select: none;
981
+ }
982
+
983
+ .viewer img[hidden] {
984
+ display: none;
985
+ }
986
+
987
+ .viewer .canvas[data-view="onion"] .second {
988
+ opacity: 0.5;
989
+ }
990
+
991
+ .viewer .canvas[data-view="difference"] .second {
992
+ mix-blend-mode: difference;
993
+ }
994
+
995
+ .viewer .stage:has(.canvas[data-view="swipe"]) {
996
+ cursor: ew-resize;
997
+ }
998
+
999
+ /* The swipe's divider and the changed regions: as thin on the screen at any
1000
+ zoom, white inside black, so that they show on a light picture and a dark. */
1001
+ .viewer .divider,
1002
+ .viewer .change {
1003
+ position: absolute;
1004
+ pointer-events: none;
1005
+ }
1006
+
1007
+ .viewer .divider {
1008
+ top: 0;
1009
+ bottom: 0;
1010
+ width: calc(var(--line) * 2);
1011
+ margin-left: calc(var(--line) * -1);
1012
+ background: #fff;
1013
+ box-shadow: 0 0 0 var(--line) #000;
1014
+ }
1015
+
1016
+ .viewer .divider[hidden] {
1017
+ display: none;
1018
+ }
1019
+
1020
+ .viewer .outlines {
1021
+ position: absolute;
1022
+ inset: 0;
1023
+ pointer-events: none;
1024
+ }
1025
+
1026
+ .viewer .change {
1027
+ margin: calc(var(--line) * -2);
1028
+ border: calc(var(--line) * 2) solid #fff;
1029
+ outline: var(--line) solid #000;
1030
+ }
1031
+
1032
+ .viewer .change[data-current] {
1033
+ outline-width: calc(var(--line) * 3);
1034
+ }
1035
+
1036
+ .viewer .swipe {
1037
+ margin: 0.3rem 1.1rem;
1038
+ }
1039
+
1040
+ .viewer .keys .current {
1041
+ color: var(--ink);
1042
+ font-weight: 700;
1043
+ }
1044
+
1045
+ /* A region being drawn, and the place a note is being written on: white
1046
+ inside black, so that it shows on a light picture and a dark, with all
1047
+ outside it dimmed. */
1048
+ .viewer .marking {
1049
+ position: absolute;
1050
+ border: 2px solid #fff;
1051
+ outline: 1px solid #000;
1052
+ box-shadow: 0 0 0 100vmax rgb(0 0 0 / 0.5);
1053
+ pointer-events: none;
1054
+ }
1055
+
1056
+ .viewer .marking[hidden] {
1057
+ display: none;
1058
+ }
1059
+
1060
+ /* The notes on a picture, as thin on the screen at any zoom as the changed
1061
+ regions; a pin is a ring. */
1062
+ .viewer .notes {
1063
+ position: absolute;
1064
+ inset: 0;
1065
+ pointer-events: none;
1066
+ }
1067
+
1068
+ .viewer .note {
1069
+ position: absolute;
1070
+ margin: calc(var(--line) * -2);
1071
+ border: calc(var(--line) * 2) solid #fff;
1072
+ outline: var(--line) solid #000;
1073
+ }
1074
+
1075
+ .viewer .note.pin {
1076
+ width: calc(var(--line) * 14);
1077
+ height: calc(var(--line) * 14);
1078
+ margin: calc(var(--line) * -7);
1079
+ border-radius: 50%;
1080
+ }
1081
+
1082
+ /* A note saved opens at a click, and says so under the pointer. */
1083
+ .viewer[data-takes-notes] .canvas:is([data-view=""], [data-view="side"], [data-view="blink"]) .note[data-note] {
1084
+ pointer-events: auto;
1085
+ cursor: pointer;
1086
+ }
1087
+
1088
+ .viewer[data-takes-notes] .note[data-note]:hover {
1089
+ border-width: calc(var(--line) * 3);
1090
+ }
1091
+
1092
+ .viewer .note.drafted {
1093
+ border-width: calc(var(--line) * 3);
1094
+ box-shadow: 0 0 0 calc(var(--line) * 100000) rgb(0 0 0 / 0.5);
1095
+ }
1096
+
1097
+ /* The note's form, beside the place it is about. */
1098
+ .viewer .beside-note {
1099
+ position: absolute;
1100
+ z-index: 1;
1101
+ width: min(24rem, calc(100% - 24px));
1102
+ cursor: auto;
1103
+ }
1104
+
1105
+ .viewer .beside-note[hidden] {
1106
+ display: none;
1107
+ }
1108
+
1109
+ .viewer .beside-note .respond {
1110
+ margin: 0;
1111
+ box-shadow: 0 0.5rem 2rem rgb(0 0 0 / 0.6);
1112
+ }
1113
+
1114
+ .viewer .caption,
1115
+ .viewer .keys {
1116
+ display: flex;
1117
+ flex-wrap: wrap;
1118
+ gap: 0.2rem 1.4rem;
1119
+ margin: 0;
1120
+ padding: 0.3rem 1.1rem;
1121
+ border-top: 1px solid var(--rule);
1122
+ color: var(--quiet);
1123
+ font-size: 0.86rem;
1124
+ }
1125
+
1126
+ .viewer .caption {
1127
+ color: var(--ink);
1128
+ }
1129
+
1130
+ .viewer .caption:empty {
1131
+ display: none;
1132
+ }
1133
+
1134
+ /* The way out by pointer, in the corner where windows keep theirs. */
1135
+ .viewer .close {
1136
+ position: absolute;
1137
+ top: 0.6rem;
1138
+ right: 0.8rem;
1139
+ z-index: 2;
1140
+ min-width: 2.2rem;
1141
+ padding: 0.1rem 0.6ch;
1142
+ border: 1px solid var(--rule-strong);
1143
+ background: var(--paper);
1144
+ color: var(--ink);
1145
+ font: 1rem / 1.6 var(--mono);
1146
+ cursor: pointer;
1147
+ }
1148
+
1149
+ .viewer .close:hover,
1150
+ .viewer .close:focus-visible {
1151
+ background: var(--ink);
1152
+ color: var(--paper);
1153
+ }
1154
+
1155
+ /* A picture that takes no note is only looked at. */
1156
+ .viewer:not([data-takes-notes]) .stage:not([data-zoomed="true"]) {
1157
+ cursor: default;
1158
+ }
1159
+
1160
+ .viewer kbd {
1161
+ border-color: var(--quiet);
1162
+ color: var(--ink);
1163
+ }
1164
+
1165
+ .viewer kbd + kbd {
1166
+ margin-left: 0.3ch;
1167
+ }
1168
+
1169
+ .decision-pictures img {
1170
+ cursor: zoom-in;
1171
+ }
1172
+
1173
+ /* A pull request's page, as a cursor reads it. One column: the title, a line
1174
+ on where it stands, the description's sections, then the sections of its
1175
+ review. The reading rests on one block; that block alone carries keys, in
1176
+ the margin beside it, and an outline at the right says which section it is
1177
+ in. Everything else waits until it is asked for. */
1178
+
1179
+ /* The column is 68 of the page's characters wide, in rem so that the margin
1180
+ beside it, set smaller, measures the same; it gives way before the keys
1181
+ beside it and the outline do. */
1182
+ body[data-page="pull_requests"] > .main {
1183
+ --rail: 15rem;
1184
+ --measure: min(
1185
+ 41rem,
1186
+ calc(100vw - var(--side) - var(--gutter) - var(--rail) - 18px - 14rem - 28px)
1187
+ );
1188
+ }
1189
+
1190
+ .pull-request,
1191
+ .since,
1192
+ .lost,
1193
+ .page,
1194
+ [data-round-results],
1195
+ body[data-page="pull_requests"] .flash {
1196
+ max-width: var(--measure);
1197
+ }
1198
+
1199
+ .pull-request {
1200
+ position: relative;
1201
+ margin: 0;
1202
+ }
1203
+
1204
+ .along[hidden] {
1205
+ display: none;
1206
+ }
1207
+
1208
+ .review-actions,
1209
+ .review-actions .along {
1210
+ display: flex;
1211
+ flex-wrap: wrap;
1212
+ align-items: center;
1213
+ gap: 8px 16px;
1214
+ }
1215
+
1216
+ .review-actions {
1217
+ margin: 16px 0 24px;
1218
+ padding: 12px 16px;
1219
+ border-block: 1px solid var(--rule);
1220
+ background: var(--surface);
1221
+ font-size: 0.867rem;
1222
+ }
1223
+
1224
+ .review-actions .along {
1225
+ margin: 0;
1226
+ font-size: inherit;
1227
+ }
1228
+
1229
+ .review-actions :is(a, button) {
1230
+ color: var(--quiet);
1231
+ text-decoration: none;
1232
+ }
1233
+
1234
+ .review-actions :is(a, button):hover {
1235
+ color: var(--ink);
1236
+ }
1237
+
1238
+ .review-actions [data-enter-decisions] {
1239
+ color: var(--ink);
1240
+ font-weight: 700;
1241
+ }
1242
+
1243
+ .review-actions button {
1244
+ padding: 3px 8px;
1245
+ border: 1px solid var(--rule-strong);
1246
+ background: var(--panel);
1247
+ font-size: inherit;
1248
+ cursor: pointer;
1249
+ }
1250
+
1251
+ .review-actions button:disabled {
1252
+ color: var(--quiet);
1253
+ opacity: 0.5;
1254
+ }
1255
+
1256
+ .review-actions [hidden] {
1257
+ display: none;
1258
+ }
1259
+
1260
+ .queue-empty {
1261
+ padding: 16px;
1262
+ border: 1px solid var(--rule);
1263
+ background: var(--surface);
1264
+ }
1265
+
1266
+ .queue-empty p {
1267
+ margin: 0 0 12px;
1268
+ }
1269
+
1270
+ .queue-empty > a {
1271
+ display: inline-block;
1272
+ }
1273
+
1274
+ .queue-empty > button + a {
1275
+ margin-left: 16px;
1276
+ }
1277
+
1278
+ .pull-request h1 {
1279
+ margin: 0;
1280
+ font-size: 1.4rem;
1281
+ }
1282
+
1283
+ .pull-request h1 .number {
1284
+ margin-right: 0.6ch;
1285
+ color: inherit;
1286
+ font-weight: 400;
1287
+ }
1288
+
1289
+ .side .stops .fraction {
1290
+ min-width: 4ch;
1291
+ padding-left: 0.6ch;
1292
+ border-left: 1px solid var(--rule-soft);
1293
+ color: var(--quiet);
1294
+ font-size: 0.8rem;
1295
+ text-align: right;
1296
+ }
1297
+
1298
+ .pull-request .status {
1299
+ display: block;
1300
+ margin: 8px 0 var(--group-gap);
1301
+ padding: 0 16px;
1302
+ border: 0;
1303
+ color: var(--quiet);
1304
+ font-size: 0.933rem;
1305
+ }
1306
+
1307
+ .status .turn {
1308
+ display: inline;
1309
+ font-size: inherit;
1310
+ white-space: normal;
1311
+ }
1312
+
1313
+ .pull-request .recordings {
1314
+ margin: -16px 0 26px;
1315
+ color: var(--quiet);
1316
+ }
1317
+
1318
+ /* What can be done with the whole pull request: beside its title, while the
1319
+ reading rests there. */
1320
+
1321
+ .pull-request .whole {
1322
+ position: absolute;
1323
+ top: 5px;
1324
+ left: calc(100% + 28px);
1325
+ display: none;
1326
+ }
1327
+
1328
+ .pull-request:has(h1:focus, .whole:focus-within) .whole {
1329
+ display: grid;
1330
+ }
1331
+
1332
+ .whole,
1333
+ .cursor .beside {
1334
+ gap: var(--control-gap);
1335
+ justify-items: start;
1336
+ width: 13.5rem;
1337
+ overflow: hidden;
1338
+ color: var(--quiet);
1339
+ font-size: 0.867rem;
1340
+ white-space: nowrap;
1341
+ }
1342
+
1343
+ .whole :is(button, a),
1344
+ .cursor .beside button {
1345
+ padding: 0;
1346
+ border: 0;
1347
+ background: none;
1348
+ color: inherit;
1349
+ font: inherit;
1350
+ text-decoration: none;
1351
+ cursor: pointer;
1352
+ }
1353
+
1354
+ .whole :is(button, a):hover,
1355
+ .cursor .beside button:hover {
1356
+ color: var(--ink);
1357
+ }
1358
+
1359
+ .whole kbd,
1360
+ .cursor .beside kbd {
1361
+ margin-right: 0.6ch;
1362
+ border-color: var(--rule);
1363
+ color: var(--quiet);
1364
+ }
1365
+
1366
+ .whole .keyless {
1367
+ text-decoration: underline;
1368
+ }
1369
+
1370
+ .whole form {
1371
+ margin: 0;
1372
+ }
1373
+
1374
+ /* The cursor: a mark in the gutter at the block the reading rests on, and that
1375
+ block's keys beside it. The script puts it there; the block itself is not
1376
+ outlined. */
1377
+
1378
+ .cursor {
1379
+ position: absolute;
1380
+ right: 0;
1381
+ left: 0;
1382
+ height: 0;
1383
+ pointer-events: none;
1384
+ }
1385
+
1386
+ .cursor[hidden] {
1387
+ display: none;
1388
+ }
1389
+
1390
+ .cursor .mark {
1391
+ position: absolute;
1392
+ left: calc(var(--gutter) - 2.4ch);
1393
+ display: flex;
1394
+ align-items: center;
1395
+ height: var(--line, 1.6em);
1396
+ font-weight: 700;
1397
+ }
1398
+
1399
+ /* Under the mark, a rule as long as the block the reading rests on. */
1400
+ .cursor .reach {
1401
+ position: absolute;
1402
+ top: var(--line, 1.6em);
1403
+ left: calc(var(--gutter) - 2ch);
1404
+ height: max(0px, calc(var(--height, 0px) - var(--line, 1.6em)));
1405
+ border-left: 1px solid var(--rule-strong);
1406
+ }
1407
+
1408
+ .cursor .beside {
1409
+ position: absolute;
1410
+ top: 2px;
1411
+ left: calc(var(--gutter) + var(--measure) + 28px);
1412
+ display: grid;
1413
+ pointer-events: auto;
1414
+ }
1415
+
1416
+ [data-reading]:focus,
1417
+ [data-reading]:focus-visible,
1418
+ li[data-decision]:focus-visible,
1419
+ .finish:focus-visible {
1420
+ outline: none;
1421
+ }
1422
+
1423
+ [data-reading] {
1424
+ scroll-margin-block: 2.5rem calc(4rem + var(--keys-height, 0px));
1425
+ }
1426
+
1427
+ /* The rail at the right of a pull request's page: the outline, and Try it
1428
+ under it, which takes what height is left above the key bar and scrolls
1429
+ within it. */
1430
+
1431
+ .rail {
1432
+ position: fixed;
1433
+ top: 36px;
1434
+ right: 18px;
1435
+ bottom: 56px;
1436
+ z-index: 2;
1437
+ display: flex;
1438
+ flex-direction: column;
1439
+ gap: var(--group-gap);
1440
+ width: var(--rail);
1441
+ }
1442
+
1443
+ /* The outline: the page's sections, the one the reading is in marked, and a
1444
+ count only where something waits for the owner. */
1445
+
1446
+ .outline {
1447
+ display: grid;
1448
+ flex: none;
1449
+ padding: 8px;
1450
+ border: 1px solid var(--rule);
1451
+ background: var(--panel);
1452
+ font-size: 0.867rem;
1453
+ }
1454
+
1455
+ .outline :is(button, a) {
1456
+ display: flex;
1457
+ gap: 1ch;
1458
+ justify-content: space-between;
1459
+ padding: 4px 6px 4px 0;
1460
+ border: 0;
1461
+ background: none;
1462
+ color: var(--quiet);
1463
+ font: inherit;
1464
+ text-align: left;
1465
+ text-decoration: none;
1466
+ cursor: pointer;
1467
+ }
1468
+
1469
+ .outline [hidden] {
1470
+ display: none;
1471
+ }
1472
+
1473
+ .outline :is(button, a):hover,
1474
+ .outline [aria-current] {
1475
+ color: var(--ink);
1476
+ }
1477
+
1478
+ .outline [aria-current] {
1479
+ background: var(--plate);
1480
+ color: var(--panel);
1481
+ font-weight: 700;
1482
+ }
1483
+
1484
+ .outline :is(button, a)[aria-current] .count {
1485
+ color: inherit;
1486
+ }
1487
+
1488
+ .outline .name {
1489
+ overflow: hidden;
1490
+ text-overflow: ellipsis;
1491
+ white-space: nowrap;
1492
+ }
1493
+
1494
+ .outline .name::before {
1495
+ content: " ";
1496
+ white-space: pre;
1497
+ }
1498
+
1499
+ .outline [aria-current] .name::before {
1500
+ content: "> ";
1501
+ font-weight: 700;
1502
+ }
1503
+
1504
+ .outline .apart {
1505
+ margin-top: 12px;
1506
+ padding-top: 12px;
1507
+ border-top: 1px solid var(--rule);
1508
+ }
1509
+
1510
+ .outline .count {
1511
+ color: var(--quiet);
1512
+ }
1513
+
1514
+ .outline .count[data-waits="true"],
1515
+ details.section > summary .count[data-waits="true"] {
1516
+ color: var(--ink);
1517
+ }
1518
+
1519
+ .outline .count[data-waits="true"] {
1520
+ font-weight: 700;
1521
+ }
1522
+
1523
+ /* The checkout, the server and the scenarios read as separate groups. The
1524
+ same beads as Standing distinguish what is ready from what still waits. */
1525
+
1526
+ .try {
1527
+ min-height: 0;
1528
+ padding: 0;
1529
+ overflow-y: auto;
1530
+ border: 1px solid var(--rule);
1531
+ background: var(--surface);
1532
+ font-size: 0.867rem;
1533
+ line-height: 1.5;
1534
+ scrollbar-width: thin;
1535
+ }
1536
+
1537
+ .try h2 {
1538
+ margin: 0;
1539
+ padding: 8px 12px;
1540
+ border-bottom: 1px solid var(--rule);
1541
+ background: var(--surface-head);
1542
+ color: var(--ink);
1543
+ font-size: 0.933rem;
1544
+ font-weight: 700;
1545
+ }
1546
+
1547
+ .try code {
1548
+ overflow-wrap: anywhere;
1549
+ }
1550
+
1551
+ .try .conditions {
1552
+ grid-template-columns: 9px minmax(0, 1fr);
1553
+ row-gap: 12px;
1554
+ column-gap: 1ch;
1555
+ margin: 12px;
1556
+ padding: 0;
1557
+ font-size: inherit;
1558
+ }
1559
+
1560
+ .try .conditions li {
1561
+ row-gap: 4px;
1562
+ padding: 0;
1563
+ }
1564
+
1565
+ .try .conditions .detail,
1566
+ .try .conditions .remedy button {
1567
+ grid-column: 2;
1568
+ }
1569
+
1570
+ .try .conditions [data-met="true"] .name {
1571
+ font-weight: 400;
1572
+ }
1573
+
1574
+ /* Starting: the bead breathes, as on the Scenarios page. */
1575
+ @media (prefers-reduced-motion: no-preference) {
1576
+ .try .conditions [data-state="starting"]::before {
1577
+ animation: breathe 1.2s ease-in-out infinite alternate;
1578
+ }
1579
+ }
1580
+
1581
+ .try .conditions .server-state {
1582
+ padding-top: 12px;
1583
+ border-top: 1px solid var(--rule);
1584
+ }
1585
+
1586
+ .try .server-action {
1587
+ display: flex;
1588
+ flex-wrap: wrap;
1589
+ gap: 4px 1ch;
1590
+ align-items: baseline;
1591
+ }
1592
+
1593
+ .try .server-action form {
1594
+ margin: 0;
1595
+ }
1596
+
1597
+ .try .conditions button.quiet {
1598
+ min-height: 28px;
1599
+ padding: 3px 1ch;
1600
+ font: inherit;
1601
+ }
1602
+
1603
+ .try .server-state[data-state="down"] button {
1604
+ border-color: var(--plate);
1605
+ background: var(--plate);
1606
+ color: var(--panel);
1607
+ font-weight: 700;
1608
+ }
1609
+
1610
+ /* The way to the fix stands where a bead would, without one: it is no
1611
+ condition, only what to do about the two above it. */
1612
+ .try .conditions li.remedy::before {
1613
+ display: none;
1614
+ }
1615
+
1616
+ .try .conditions .remedy button {
1617
+ justify-self: start;
1618
+ }
1619
+
1620
+ /* The fix opens in a popup beside the rail, level with its top, over the
1621
+ page: the rail stays as short as it was. */
1622
+ .try-pop {
1623
+ position: fixed;
1624
+ inset: 42px auto auto;
1625
+ right: calc(18px + var(--rail) + 14px);
1626
+ width: min(72ch, 56vw);
1627
+ max-height: calc(100vh - 110px);
1628
+ margin: 0;
1629
+ padding: 18px 20px 16px;
1630
+ overflow: auto;
1631
+ border: 1px solid var(--ink);
1632
+ background: var(--panel);
1633
+ color: var(--ink);
1634
+ font-size: 0.867rem;
1635
+ line-height: 1.5;
1636
+ box-shadow: 0 16px 40px rgb(0 0 0 / 0.55);
1637
+ }
1638
+
1639
+ .try-pop::backdrop {
1640
+ background: rgb(0 0 0 / 0.35);
1641
+ }
1642
+
1643
+ .try-pop h3 {
1644
+ margin: 0 0 10px;
1645
+ font-size: 1rem;
1646
+ }
1647
+
1648
+ .try-pop p {
1649
+ margin: 0 0 10px;
1650
+ }
1651
+
1652
+ .try-pop .steps {
1653
+ margin: 16px 0;
1654
+ padding: 0;
1655
+ list-style: none;
1656
+ counter-reset: step;
1657
+ }
1658
+
1659
+ .try-pop .steps > li {
1660
+ position: relative;
1661
+ margin-top: 16px;
1662
+ padding-left: 3ch;
1663
+ counter-increment: step;
1664
+ }
1665
+
1666
+ .try-pop .steps > li::before {
1667
+ content: counter(step) ".";
1668
+ position: absolute;
1669
+ left: 0;
1670
+ color: var(--quiet);
1671
+ }
1672
+
1673
+ .try-pop .steps p {
1674
+ margin-bottom: 6px;
1675
+ }
1676
+
1677
+ /* Words to copy: set apart as a terminal would show them, the button at
1678
+ their corner. */
1679
+ .copyable {
1680
+ position: relative;
1681
+ margin: 0 0 8px;
1682
+ }
1683
+
1684
+ .copyable pre {
1685
+ margin: 0;
1686
+ padding: 8px 8ch 8px 10px;
1687
+ border: 1px solid var(--rule);
1688
+ background: var(--rest);
1689
+ font-size: 0.8rem;
1690
+ line-height: 1.5;
1691
+ white-space: pre-wrap;
1692
+ overflow-wrap: anywhere;
1693
+ }
1694
+
1695
+ .copyable pre code {
1696
+ padding: 0;
1697
+ background: none;
1698
+ }
1699
+
1700
+ .copyable button {
1701
+ position: absolute;
1702
+ top: 6px;
1703
+ right: 6px;
1704
+ padding: 0 1ch;
1705
+ font-size: 0.75rem;
1706
+ }
1707
+
1708
+ /* The end of the log of a server that has stopped shows while the pointer or
1709
+ the focus is on its line: beside the rail, level with the line, over the
1710
+ page. Without anchors it stands at the top. */
1711
+ .rail {
1712
+ anchor-name: --rail;
1713
+ }
1714
+
1715
+ .try .log {
1716
+ anchor-name: --log-end;
1717
+ color: var(--ink);
1718
+ text-decoration: underline dotted;
1719
+ text-underline-offset: 0.22em;
1720
+ cursor: help;
1721
+ }
1722
+
1723
+ .try .tail {
1724
+ position: fixed;
1725
+ top: 42px;
1726
+ right: calc(18px + var(--rail) + 14px);
1727
+ z-index: 9;
1728
+ display: none;
1729
+ width: min(84ch, 52vw);
1730
+ max-height: 70vh;
1731
+ margin: 0;
1732
+ padding: 10px 12px;
1733
+ overflow: auto;
1734
+ border: 1px solid var(--ink);
1735
+ background: var(--panel);
1736
+ color: var(--ink);
1737
+ font-size: 0.75rem;
1738
+ line-height: 1.4;
1739
+ white-space: pre-wrap;
1740
+ overflow-wrap: anywhere;
1741
+ box-shadow: 0 10px 30px rgb(0 0 0 / 0.5);
1742
+ }
1743
+
1744
+ @supports (anchor-name: --a) {
1745
+ .try .tail {
1746
+ top: auto;
1747
+ right: calc(anchor(--rail left) + 14px);
1748
+ bottom: anchor(--log-end bottom);
1749
+ position-try-fallbacks: flip-block;
1750
+ }
1751
+ }
1752
+
1753
+ .try li:has(.log:is(:hover, :focus-visible)) .tail {
1754
+ display: block;
1755
+ }
1756
+
1757
+ .try .tries {
1758
+ margin-top: 0;
1759
+ padding: 12px;
1760
+ border-top: 1px solid var(--rule);
1761
+ background: var(--panel);
1762
+ }
1763
+
1764
+ .try .tries h3 {
1765
+ margin: 0 0 4px;
1766
+ color: var(--ink);
1767
+ font-size: inherit;
1768
+ }
1769
+
1770
+ .try .tries .lede {
1771
+ margin: 0 0 12px;
1772
+ color: var(--quiet);
1773
+ }
1774
+
1775
+ .try .tries ol {
1776
+ display: grid;
1777
+ gap: 12px;
1778
+ margin: 0;
1779
+ padding: 0;
1780
+ list-style: none;
1781
+ }
1782
+
1783
+ .try .tries li {
1784
+ display: grid;
1785
+ gap: 4px;
1786
+ }
1787
+
1788
+ /* A scenario's button carries its name: the thing pressed is the thing tried. */
1789
+ .try .try-one {
1790
+ width: 100%;
1791
+ padding: 8px 1ch;
1792
+ border: 1px solid var(--plate);
1793
+ background: var(--plate);
1794
+ color: var(--panel);
1795
+ font: inherit;
1796
+ font-weight: 700;
1797
+ text-align: left;
1798
+ overflow-wrap: anywhere;
1799
+ cursor: pointer;
1800
+ }
1801
+
1802
+ .try .try-one:hover,
1803
+ .try .try-one:focus-visible {
1804
+ background: var(--ink);
1805
+ color: var(--paper);
1806
+ }
1807
+
1808
+ .try .try-one:disabled {
1809
+ border-style: dashed;
1810
+ border-color: var(--rule);
1811
+ background: none;
1812
+ color: var(--quiet);
1813
+ cursor: default;
1814
+ }
1815
+
1816
+ .try .tries .how {
1817
+ padding: 0;
1818
+ color: var(--quiet);
1819
+ overflow-wrap: anywhere;
1820
+ }
1821
+
1822
+ body[data-focus] .outline :is(button, a):not([aria-current]) {
1823
+ color: var(--quiet);
1824
+ }
1825
+
1826
+ /* The sections: a heading and what it holds at a glance; open, its blocks. */
1827
+
1828
+ .page {
1829
+ display: block;
1830
+ }
1831
+
1832
+ details.section {
1833
+ margin-bottom: 8px;
1834
+ padding-inline: 16px;
1835
+ border: 1px solid var(--rule);
1836
+ background: var(--surface);
1837
+ }
1838
+
1839
+ details.section:focus-within {
1840
+ border-color: var(--rule-strong);
1841
+ }
1842
+
1843
+ details.section:last-child {
1844
+ border-bottom: 1px solid var(--rule);
1845
+ }
1846
+
1847
+ main.description + details.section {
1848
+ margin-top: var(--group-gap);
1849
+ }
1850
+
1851
+ details.section > summary {
1852
+ position: relative;
1853
+ gap: 1.4ch;
1854
+ align-items: baseline;
1855
+ margin-inline: -16px;
1856
+ padding: 9px 16px;
1857
+ background: var(--surface);
1858
+ color: var(--quiet);
1859
+ }
1860
+
1861
+ details.section[open] > summary,
1862
+ details.section > summary:hover {
1863
+ background: var(--surface-head);
1864
+ color: var(--ink);
1865
+ }
1866
+
1867
+ details.section[open] > summary {
1868
+ margin-bottom: 12px;
1869
+ border-bottom: 1px solid var(--rule);
1870
+ box-shadow: inset 0 1px #3d3d3d, 0 1px #151515;
1871
+ }
1872
+
1873
+ /* The fold has a visible state even when its heading has no count. */
1874
+ details.section > summary::after {
1875
+ content: "+";
1876
+ flex: none;
1877
+ margin-left: auto;
1878
+ color: var(--quiet);
1879
+ font-size: 0.867rem;
1880
+ }
1881
+
1882
+ details.section[open] > summary::after {
1883
+ content: "−";
1884
+ }
1885
+
1886
+ details.section > summary::before,
1887
+ .pr-scenarios > summary::before,
1888
+ .pr-scenarios[open] > summary::before {
1889
+ content: none;
1890
+ }
1891
+
1892
+ /* The open fold has an etched joint, using only a thin slice of APL's grid.
1893
+ No complete sign is presented as a label, status or action. */
1894
+ details.section[open] > summary::before {
1895
+ content: "";
1896
+ position: absolute;
1897
+ right: 0;
1898
+ bottom: -1px;
1899
+ left: 0;
1900
+ width: auto;
1901
+ height: 3px;
1902
+ background: var(--rule-strong);
1903
+ mask: var(--apl-seam) left center / 28px 7px repeat-x;
1904
+ pointer-events: none;
1905
+ }
1906
+
1907
+ details.section .heading,
1908
+ .pr-scenarios .heading {
1909
+ font-size: 1rem;
1910
+ font-weight: 700;
1911
+ letter-spacing: 0;
1912
+ line-height: 1.2;
1913
+ text-transform: none;
1914
+ }
1915
+
1916
+ details.section > summary .count {
1917
+ margin-left: 0;
1918
+ color: var(--quiet);
1919
+ font-size: 0.867rem;
1920
+ }
1921
+
1922
+ [data-quotable] {
1923
+ padding: 0 0 0.9rem;
1924
+ font-size: 1rem;
1925
+ line-height: 1.62;
1926
+ }
1927
+
1928
+ [data-quotable] :is(pre, table) {
1929
+ border-color: var(--rule-strong);
1930
+ }
1931
+
1932
+ [data-quotable] code {
1933
+ background: var(--rest);
1934
+ }
1935
+
1936
+ .description [data-quotable] > p,
1937
+ .description [data-quotable] > ul,
1938
+ .description [data-quotable] > ol {
1939
+ max-width: none;
1940
+ }
1941
+
1942
+ /* The + for a note by pointer stands in the gutter, under the pointer alone:
1943
+ where the reading rests, the cursor's mark stands there instead. */
1944
+
1945
+ .plus {
1946
+ left: -1.6rem;
1947
+ border-color: var(--rule-strong);
1948
+ line-height: 1;
1949
+ }
1950
+
1951
+ .task-list-item > .plus {
1952
+ left: -3.3rem;
1953
+ }
1954
+
1955
+ [data-reading]:focus > .plus,
1956
+ [data-reading]:focus > :first-child > .plus {
1957
+ opacity: 0;
1958
+ pointer-events: none;
1959
+ }
1960
+
1961
+ /* A decision as it is read: a bead where GitHub drew a box, hollow while it
1962
+ is still to review and solid once it is. It is a row that opens, and says
1963
+ so under the pointer. */
1964
+
1965
+ .description li[data-decision] > input[type="checkbox"],
1966
+ .description li[data-decision] > p > input[type="checkbox"] {
1967
+ display: none;
1968
+ }
1969
+
1970
+ .description [data-quotable] li[data-decision] {
1971
+ padding-left: 2.6ch;
1972
+ }
1973
+
1974
+ .description li[data-decision]::before {
1975
+ content: "";
1976
+ position: absolute;
1977
+ top: 0.56em;
1978
+ left: 0;
1979
+ box-sizing: border-box;
1980
+ width: 9px;
1981
+ height: 9px;
1982
+ border: 1px solid var(--ink);
1983
+ border-radius: 50%;
1984
+ }
1985
+
1986
+ .description li[data-decision]:not([data-said=""])::before {
1987
+ border-color: var(--quiet);
1988
+ background: var(--quiet);
1989
+ }
1990
+
1991
+ .description li[data-decision][data-choice="stale"]::before {
1992
+ border-color: var(--ink);
1993
+ border-style: dashed;
1994
+ background: none;
1995
+ }
1996
+
1997
+ .description [data-decision][aria-current] {
1998
+ background: none;
1999
+ outline: 0;
2000
+ }
2001
+
2002
+ body:not([data-focus]) .description li[data-decision] {
2003
+ cursor: pointer;
2004
+ }
2005
+
2006
+ body:not([data-focus]) .description li[data-decision]:hover {
2007
+ background: var(--rest);
2008
+ }
2009
+
2010
+ /* Which decisions the list shows: two words, the one in force in full relief. */
2011
+
2012
+ .views {
2013
+ gap: 2.4ch;
2014
+ margin: 0 0 14px;
2015
+ font-size: 0.867rem;
2016
+ }
2017
+
2018
+ .views button.quiet,
2019
+ .views button.quiet[aria-pressed="true"] {
2020
+ padding: 0;
2021
+ border: 0;
2022
+ background: none;
2023
+ color: var(--quiet);
2024
+ }
2025
+
2026
+ .views button.quiet[aria-pressed="true"] {
2027
+ color: var(--ink);
2028
+ font-weight: 700;
2029
+ }
2030
+
2031
+ .views button.quiet:hover {
2032
+ color: var(--ink);
2033
+ }
2034
+
2035
+ .views .count {
2036
+ margin-left: 0.4ch;
2037
+ color: var(--quiet);
2038
+ font-weight: 400;
2039
+ }
2040
+
2041
+ /* Standing: what should hold, a bead to each, in two columns: the condition,
2042
+ then what makes it so. A hollow bead in full relief waits; a solid one is met,
2043
+ and its line lies back with it. The verdict is the bead's to say: its words
2044
+ are for a screen reader. Whether the scenarios were tried follows apart,
2045
+ always quiet, because nothing waits on it. */
2046
+
2047
+ .standing {
2048
+ margin: 0;
2049
+ padding: 0 0 14px;
2050
+ border: 0;
2051
+ }
2052
+
2053
+ /* The lines share their columns, so the conditions and what makes them so each
2054
+ line up, the first as wide as the longest condition. */
2055
+ .conditions {
2056
+ grid-template-columns: 9px fit-content(44ch) minmax(0, 1fr);
2057
+ column-gap: 2ch;
2058
+ font-size: 0.867rem;
2059
+ }
2060
+
2061
+ .conditions li {
2062
+ grid-column: 1 / -1;
2063
+ grid-template-columns: subgrid;
2064
+ align-items: start;
2065
+ padding: 2px 0;
2066
+ border: 0;
2067
+ }
2068
+
2069
+ /* On a phone, what makes it so goes under the condition. */
2070
+ @media (max-width: 40rem) {
2071
+ .conditions {
2072
+ grid-template-columns: 9px minmax(0, 1fr);
2073
+ }
2074
+
2075
+ .conditions .detail {
2076
+ grid-column: 2;
2077
+ }
2078
+ }
2079
+
2080
+ .conditions li::before {
2081
+ content: "";
2082
+ width: 9px;
2083
+ height: 9px;
2084
+ box-sizing: border-box;
2085
+ margin-top: calc((1lh - 9px) / 2);
2086
+ border: 1px solid var(--ink);
2087
+ border-radius: 50%;
2088
+ }
2089
+
2090
+ .conditions [data-met="false"] .name {
2091
+ font-weight: 700;
2092
+ }
2093
+
2094
+ .conditions [data-met="true"],
2095
+ .conditions li.optional {
2096
+ color: var(--quiet);
2097
+ }
2098
+
2099
+ .conditions [data-met="true"]::before {
2100
+ border-color: var(--quiet);
2101
+ background: var(--quiet);
2102
+ }
2103
+
2104
+ /* Yours to judge: no fact decides it. */
2105
+ .conditions [data-met="nil"]::before {
2106
+ border-style: dashed;
2107
+ }
2108
+
2109
+ .conditions li.optional {
2110
+ margin-top: 8px;
2111
+ }
2112
+
2113
+ .conditions li.optional::before {
2114
+ border-color: var(--quiet);
2115
+ }
2116
+
2117
+ .conditions li.optional .name {
2118
+ font-weight: 400;
2119
+ }
2120
+
2121
+ .conditions .detail {
2122
+ color: var(--quiet);
2123
+ }
2124
+
2125
+ .standing .good-to-go {
2126
+ display: flex;
2127
+ flex-wrap: wrap;
2128
+ gap: 0.3rem 2ch;
2129
+ align-items: baseline;
2130
+ justify-items: start;
2131
+ margin-top: 16px;
2132
+ font-size: 0.867rem;
2133
+ text-align: left;
2134
+ }
2135
+
2136
+ .standing .good-to-go button {
2137
+ padding: 0;
2138
+ border: 0;
2139
+ background: none;
2140
+ color: var(--ink);
2141
+ font: inherit;
2142
+ font-weight: 700;
2143
+ cursor: pointer;
2144
+ }
2145
+
2146
+ .standing .good-to-go button.quiet {
2147
+ color: var(--quiet);
2148
+ font-weight: 400;
2149
+ text-decoration: underline;
2150
+ }
2151
+
2152
+ .standing .good-to-go kbd {
2153
+ margin-right: 0.6ch;
2154
+ font-weight: 400;
2155
+ }
2156
+
2157
+ /* Set aside as waiting: a question until it is, then a sentence that says on what. */
2158
+ .standing .waiting {
2159
+ display: block;
2160
+ margin-top: 12px;
2161
+ color: var(--quiet);
2162
+ font-size: 0.867rem;
2163
+ }
2164
+
2165
+ .standing .waiting > summary {
2166
+ width: fit-content;
2167
+ cursor: pointer;
2168
+ list-style: none;
2169
+ }
2170
+
2171
+ .standing .waiting > summary::-webkit-details-marker {
2172
+ display: none;
2173
+ }
2174
+
2175
+ .standing .waiting > summary::before {
2176
+ content: "+ ";
2177
+ }
2178
+
2179
+ .standing .waiting[open] > summary::before {
2180
+ content: "- ";
2181
+ }
2182
+
2183
+ .standing details.waiting form {
2184
+ display: flex;
2185
+ flex-wrap: wrap;
2186
+ gap: 0.4rem 1.2ch;
2187
+ align-items: baseline;
2188
+ margin: 8px 0 0 2ch;
2189
+ }
2190
+
2191
+ .standing details.waiting form .hint {
2192
+ flex-basis: 100%;
2193
+ margin: 0;
2194
+ }
2195
+
2196
+ .standing .waiting input {
2197
+ flex: 0 1 40ch;
2198
+ padding: 0.1rem 0.5rem;
2199
+ border-color: var(--rule);
2200
+ background: none;
2201
+ font-size: inherit;
2202
+ }
2203
+
2204
+ .standing div.waiting {
2205
+ display: flex;
2206
+ flex-wrap: wrap;
2207
+ gap: 0.3rem 2ch;
2208
+ align-items: baseline;
2209
+ }
2210
+
2211
+ .standing div.waiting :is(p, form) {
2212
+ margin: 0;
2213
+ }
2214
+
2215
+ .standing div.waiting strong {
2216
+ color: var(--ink);
2217
+ }
2218
+
2219
+ .standing div.waiting button {
2220
+ padding: 0;
2221
+ border: 0;
2222
+ background: none;
2223
+ color: var(--quiet);
2224
+ font: inherit;
2225
+ text-decoration: underline;
2226
+ cursor: pointer;
2227
+ }
2228
+
2229
+ /* Its scenarios, in the page's one column: what to do, then how to open it
2230
+ and what was seen. */
2231
+ .pr-scenarios {
2232
+ margin: 0;
2233
+ border-bottom: 0;
2234
+ font-size: 0.867rem;
2235
+ }
2236
+
2237
+ .pr-scenarios .hint {
2238
+ margin: 0 0 10px;
2239
+ }
2240
+
2241
+ .pr-scenarios .scenario {
2242
+ grid-template-columns: minmax(0, 1fr);
2243
+ gap: 8px;
2244
+ padding: 0 0 14px;
2245
+ border: 0;
2246
+ }
2247
+
2248
+ .pr-scenarios .scenario h4 {
2249
+ font-size: 1rem;
2250
+ font-weight: 700;
2251
+ }
2252
+
2253
+ .pr-scenarios .scenario .act,
2254
+ .pr-scenarios .scenario .seen {
2255
+ display: flex;
2256
+ flex-wrap: wrap;
2257
+ gap: 0.3rem 1.4rem;
2258
+ align-items: baseline;
2259
+ justify-items: start;
2260
+ text-align: left;
2261
+ }
2262
+
2263
+ .connections {
2264
+ margin: 0;
2265
+ padding: 0 0 14px;
2266
+ border: 0;
2267
+ font-size: 0.867rem;
2268
+ }
2269
+
2270
+ /* Notes: each as its words, then quietly what kind it is, how it stands and
2271
+ what it was written on. */
2272
+
2273
+ .margin {
2274
+ position: static;
2275
+ max-height: none;
2276
+ padding-bottom: 14px;
2277
+ overflow: visible;
2278
+ font-size: 0.867rem;
2279
+ }
2280
+
2281
+ .margin h3 {
2282
+ margin: 0 0 6px;
2283
+ color: var(--quiet);
2284
+ font-size: 0.8rem;
2285
+ font-weight: 400;
2286
+ letter-spacing: 0.07em;
2287
+ }
2288
+
2289
+ .margin .cards + h3 {
2290
+ margin-top: 16px;
2291
+ }
2292
+
2293
+ .margin .card,
2294
+ .lost .card {
2295
+ padding: 0;
2296
+ border: 0;
2297
+ background: none;
2298
+ }
2299
+
2300
+ .margin .card .meta {
2301
+ color: var(--quiet);
2302
+ font-size: inherit;
2303
+ letter-spacing: 0;
2304
+ text-transform: none;
2305
+ }
2306
+
2307
+ .margin .card .text {
2308
+ color: var(--ink);
2309
+ line-height: 1.55;
2310
+ }
2311
+
2312
+ .margin .empty {
2313
+ max-width: none;
2314
+ }
2315
+
2316
+ /* The handover: how far the choices are, and what goes to the agent. */
2317
+
2318
+ .draft-tools.compact {
2319
+ position: static;
2320
+ padding: 0 0 14px;
2321
+ border: 0;
2322
+ background: none;
2323
+ font-size: 0.867rem;
2324
+ }
2325
+
2326
+ /* The decisions in the page as it is read: each a row, its choices kept for
2327
+ when it is the one at hand */
2328
+
2329
+ .description [data-decision] > .beneath > .actions {
2330
+ display: none;
2331
+ }
2332
+
2333
+ .box:not([aria-current]) .beneath > .actions {
2334
+ display: none;
2335
+ }
2336
+
2337
+ /* The menu of choices: the key, what it does, and for the alternative, which */
2338
+
2339
+ .beneath > .actions,
2340
+ .box .beneath > .actions,
2341
+ .task-list-item > .beneath > .actions {
2342
+ display: grid;
2343
+ gap: 0;
2344
+ width: auto;
2345
+ max-width: none;
2346
+ margin-top: 14px;
2347
+ border-top: 1px solid var(--rule);
2348
+ font-size: 1rem;
2349
+ opacity: 1;
2350
+ background: var(--panel);
2351
+ }
2352
+
2353
+ button.choice,
2354
+ .beneath > .actions > a {
2355
+ display: grid;
2356
+ grid-template-columns: 3ch minmax(0, 1fr);
2357
+ gap: 0 1.4ch;
2358
+ align-items: baseline;
2359
+ padding: 8px 8px;
2360
+ border: 0;
2361
+ border-bottom: 1px solid var(--rule);
2362
+ background: none;
2363
+ color: var(--ink);
2364
+ font-size: 1rem;
2365
+ text-align: left;
2366
+ text-decoration: none;
2367
+ cursor: pointer;
2368
+ }
2369
+
2370
+ .beneath > .actions > a {
2371
+ display: block;
2372
+ color: var(--quiet);
2373
+ font-size: 0.867rem;
2374
+ }
2375
+
2376
+ button.choice:hover,
2377
+ button.choice:focus-visible,
2378
+ .beneath > .actions > a:hover {
2379
+ background: var(--rest);
2380
+ }
2381
+
2382
+ button.choice kbd {
2383
+ min-width: 0;
2384
+ padding: 0;
2385
+ font-weight: 400;
2386
+ }
2387
+
2388
+ /* Which alternative it is stands under the words that choose it. */
2389
+ button.choice .what {
2390
+ grid-column: 2;
2391
+ color: var(--quiet);
2392
+ }
2393
+
2394
+ button.choice[data-choice-clear] {
2395
+ grid-template-columns: minmax(0, 1fr);
2396
+ color: var(--quiet);
2397
+ font-size: 0.867rem;
2398
+ }
2399
+
2400
+ button.choice[aria-pressed="true"] .does {
2401
+ color: var(--ink);
2402
+ font-weight: 700;
2403
+ }
2404
+
2405
+ button.choice[aria-pressed="true"] {
2406
+ background: var(--plate);
2407
+ color: var(--panel);
2408
+ }
2409
+
2410
+ button.choice[aria-pressed="true"] :is(.does, .what, kbd),
2411
+ button.choice[aria-pressed="true"] .does::after {
2412
+ color: inherit;
2413
+ }
2414
+
2415
+ button.choice[aria-pressed="true"] .does::after {
2416
+ content: " <- your choice";
2417
+ color: var(--quiet);
2418
+ font-weight: 400;
2419
+ white-space: pre;
2420
+ }
2421
+
2422
+ .draft-status {
2423
+ color: var(--quiet);
2424
+ }
2425
+
2426
+ .box[data-choice="stale"] .draft-status {
2427
+ color: var(--ink);
2428
+ font-weight: 700;
2429
+ }
2430
+
2431
+ button.choice[hidden] {
2432
+ display: none;
2433
+ }
2434
+
2435
+ .choice-editor textarea {
2436
+ width: 100%;
2437
+ max-width: none;
2438
+ min-height: 7rem;
2439
+ padding: 0.6rem 0.8rem;
2440
+ line-height: 1.5;
2441
+ }
2442
+
2443
+ .choice-editor :is(textarea, input):focus-visible {
2444
+ border-color: var(--ink);
2445
+ outline: 1px solid var(--ink);
2446
+ outline-offset: 2px;
2447
+ }
2448
+
2449
+ /* A choice's one line, a note on the alternative or a rule, spans the
2450
+ column as the longer answer does. */
2451
+ .choice-editor input[type="text"] {
2452
+ box-sizing: border-box;
2453
+ flex-basis: 100%;
2454
+ width: 100%;
2455
+ padding: 0.45rem 0.8rem;
2456
+ }
2457
+
2458
+ /* Which decision of how many: a bead each. Hollow, it is still to review;
2459
+ solid, it is chosen; ringed, it is the one at hand. */
2460
+
2461
+ .stepper {
2462
+ display: flex;
2463
+ flex-wrap: wrap;
2464
+ gap: 5px;
2465
+ align-items: center;
2466
+ margin: 12px 0 20px;
2467
+ }
2468
+
2469
+ .stepper:empty {
2470
+ display: none;
2471
+ }
2472
+
2473
+ .stepper .cell,
2474
+ .finish .bead {
2475
+ box-sizing: border-box;
2476
+ width: 9px;
2477
+ height: 9px;
2478
+ border: 1px solid var(--ink);
2479
+ border-radius: 50% !important;
2480
+ cursor: pointer;
2481
+ }
2482
+
2483
+ .stepper .cell:not([data-state=""]),
2484
+ .finish [data-line-of]:not([data-state=""]) .bead {
2485
+ border-color: var(--quiet);
2486
+ background: var(--quiet);
2487
+ }
2488
+
2489
+ /* A choice the description has since moved under needs another look. */
2490
+ .stepper .cell[data-state="stale"],
2491
+ .finish [data-line-of][data-state="stale"] .bead {
2492
+ border-color: var(--ink);
2493
+ border-style: dashed;
2494
+ background: none;
2495
+ }
2496
+
2497
+ .stepper .cell[data-at],
2498
+ #decisions:has(> summary:focus) .stepper .cell[data-first] {
2499
+ border-color: var(--ink);
2500
+ outline: 0;
2501
+ box-shadow:
2502
+ 0 0 0 2px var(--paper),
2503
+ 0 0 0 3px var(--ink);
2504
+ }
2505
+
2506
+ /* While the reading rests on the decisions' heading, the decision f would
2507
+ begin on says so, at the end of its lead, as a choice says it is yours. */
2508
+ #decisions:has(> summary:focus) li[data-first] > strong:first-of-type::after,
2509
+ #decisions:has(> summary:focus)
2510
+ li[data-first]
2511
+ > p:first-of-type
2512
+ > strong:first-child::after {
2513
+ content: " <- f begins here";
2514
+ color: var(--quiet);
2515
+ font-weight: 400;
2516
+ white-space: pre;
2517
+ }
2518
+
2519
+ .stepper .place {
2520
+ margin-left: 1.2ch;
2521
+ color: var(--quiet);
2522
+ font-size: 0.867rem;
2523
+ }
2524
+
2525
+ /* Deciding: one decision is all the page shows, read from the top down: the
2526
+ line its group is led in with, its lead set large, its words, its pictures,
2527
+ then its choices as a menu. It stays at the top of the page whichever
2528
+ decision it is. Everything else of the pull request waits behind Escape. */
2529
+
2530
+ body[data-focus] .status,
2531
+ body[data-focus] .review-actions,
2532
+ body[data-focus] .pull-request .recordings,
2533
+ body[data-focus] .since,
2534
+ body[data-focus] .lost,
2535
+ body[data-focus] [data-round-results],
2536
+ body[data-focus] .views,
2537
+ body[data-focus] details.section:not(#decisions),
2538
+ body[data-focus] #decisions > summary,
2539
+ body[data-focus] .plus,
2540
+ body[data-focus] li[data-decision]:not([aria-current]),
2541
+ body[data-focus]
2542
+ #decisions
2543
+ [data-quotable]
2544
+ > :not(:has([data-decision][aria-current])),
2545
+ body[data-focus="decide"] .finish,
2546
+ body[data-focus="done"] #decisions [data-quotable] {
2547
+ display: none;
2548
+ }
2549
+
2550
+ body[data-focus] #decisions,
2551
+ body[data-focus] details.section:last-child {
2552
+ border: 0;
2553
+ padding-inline: 0;
2554
+ background: none;
2555
+ }
2556
+
2557
+ /* The pull request is named, quietly, in one line. */
2558
+ body[data-focus] .pull-request h1 {
2559
+ color: var(--quiet);
2560
+ font-size: 1rem;
2561
+ font-weight: 400;
2562
+ padding: 8px 12px;
2563
+ border-color: var(--rule);
2564
+ background: var(--surface-head);
2565
+ }
2566
+
2567
+ /* The line a description leads a group of decisions in with stays, as its label. */
2568
+ body[data-focus="decide"]
2569
+ #decisions
2570
+ [data-quotable]
2571
+ > :has(+ * [data-decision][aria-current]) {
2572
+ display: block;
2573
+ margin: 0 0 4px;
2574
+ color: var(--quiet);
2575
+ font-size: 0.8rem;
2576
+ letter-spacing: 0.07em;
2577
+ text-transform: uppercase;
2578
+ }
2579
+
2580
+ body[data-focus] #decisions [data-quotable] > ul,
2581
+ body[data-focus] #decisions [data-quotable] > ol {
2582
+ max-width: none;
2583
+ margin: 0;
2584
+ padding: 0;
2585
+ }
2586
+
2587
+ body[data-focus="decide"]
2588
+ .description
2589
+ [data-quotable]
2590
+ li[data-decision][aria-current] {
2591
+ margin: 0;
2592
+ padding: 16px;
2593
+ border: 1px solid var(--rule);
2594
+ background: var(--surface);
2595
+ color: var(--ink);
2596
+ font-size: 1.1rem;
2597
+ line-height: 1.7;
2598
+ list-style: none;
2599
+ outline: none;
2600
+ }
2601
+
2602
+ /* The bead of the list as it is read stands aside: the stepper has one. */
2603
+ body[data-focus] .description li[data-decision]::before {
2604
+ content: none;
2605
+ }
2606
+
2607
+ /* One already reviewed says so before anything else, in reverse like the name
2608
+ of a mode, and its words lie back: passing over it on the way, it cannot be
2609
+ taken for one still to decide. One chosen on before its words changed says
2610
+ that instead, in outline, for it is to decide again. */
2611
+ body[data-focus="decide"]
2612
+ .description
2613
+ li[data-decision][aria-current]:not([data-said=""])::before {
2614
+ content: "● reviewed · " attr(data-said);
2615
+ position: static;
2616
+ display: block;
2617
+ width: fit-content;
2618
+ height: auto;
2619
+ margin: 0 0 1.1rem;
2620
+ padding: 0.2rem 1.2ch;
2621
+ border: 1px solid var(--ink);
2622
+ border-radius: 0;
2623
+ background: var(--ink);
2624
+ color: var(--paper);
2625
+ font-size: 0.867rem;
2626
+ font-weight: 700;
2627
+ letter-spacing: 0.07em;
2628
+ line-height: 1.6;
2629
+ text-transform: uppercase;
2630
+ }
2631
+
2632
+ body[data-focus="decide"]
2633
+ .description
2634
+ li[data-decision][aria-current][data-choice="stale"]::before {
2635
+ content: "◌ changed since your choice · " attr(data-said);
2636
+ border-style: dashed;
2637
+ background: none;
2638
+ color: var(--ink);
2639
+ }
2640
+
2641
+ body[data-focus="decide"]
2642
+ .description
2643
+ li[data-decision][aria-current]:not([data-said=""], [data-choice="stale"]),
2644
+ body[data-focus="decide"]
2645
+ .description
2646
+ li[data-decision][aria-current]:not([data-said=""], [data-choice="stale"])
2647
+ :is(strong, a, code) {
2648
+ color: var(--quiet);
2649
+ }
2650
+
2651
+ body[data-focus="decide"]
2652
+ li[data-decision][aria-current]
2653
+ > strong:first-of-type,
2654
+ body[data-focus="decide"]
2655
+ li[data-decision][aria-current]
2656
+ > p:first-of-type
2657
+ > strong:first-child {
2658
+ display: block;
2659
+ margin-bottom: 0.8rem;
2660
+ font-size: 1.3rem;
2661
+ line-height: 1.35;
2662
+ text-wrap: balance;
2663
+ }
2664
+
2665
+ body[data-focus] li[data-decision] > input[type="checkbox"],
2666
+ body[data-focus] li[data-decision] > p > input[type="checkbox"] {
2667
+ display: none;
2668
+ }
2669
+
2670
+ /* Under the decision at hand: its pictures, then its choices. */
2671
+ body[data-focus] li[data-decision] > .beneath {
2672
+ max-width: none;
2673
+ margin: 1.2rem 0 0;
2674
+ font-size: 1rem;
2675
+ }
2676
+
2677
+ body[data-focus] li[data-decision][aria-current] > .beneath > .actions {
2678
+ display: grid;
2679
+ margin-top: 1rem;
2680
+ }
2681
+
2682
+ body[data-focus] .decision-screenshots[open] > summary {
2683
+ color: var(--quiet);
2684
+ font-size: 0.867rem;
2685
+ }
2686
+
2687
+ /* A decision's pictures share the column, side by side while they fit. */
2688
+ body[data-focus] .decision-pictures {
2689
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
2690
+ align-items: start;
2691
+ }
2692
+
2693
+ body[data-focus] .decision-pictures img {
2694
+ max-height: 46vh;
2695
+ width: auto;
2696
+ max-width: 100%;
2697
+ border: 1px solid var(--rule);
2698
+ }
2699
+
2700
+ body[data-focus="done"] .finish {
2701
+ margin-top: 2rem;
2702
+ padding: 1rem 1.2rem;
2703
+ }
2704
+
2705
+ .finish .actions {
2706
+ gap: 0.6rem 1rem;
2707
+ margin-top: 0.9rem;
2708
+ }
2709
+
2710
+ .finish .actions a {
2711
+ padding: 0.12rem 0.7rem;
2712
+ border: 1px solid var(--rule);
2713
+ color: var(--ink);
2714
+ text-decoration: none;
2715
+ }
2716
+
2717
+ .finish .actions a:hover {
2718
+ border-color: var(--ink);
2719
+ background: var(--rest);
2720
+ }
2721
+
2722
+ /* Alone on the page, where the decisions end lists them, a line each under
2723
+ its grade: a bead, its lead, and what was chosen or what holds it. One
2724
+ reviewed lies back in grey, as it does while it is decided. The beads above
2725
+ say the same of the blocking alone, so they stand aside. Under the page the
2726
+ decisions themselves are just above, and only what to do next stays. */
2727
+
2728
+ body:not([data-focus="done"]) .finish .grade > :not(.leave),
2729
+ body[data-focus="done"] .stepper {
2730
+ display: none;
2731
+ }
2732
+
2733
+ .finish h3 {
2734
+ margin: 1.6rem 0 0.2rem;
2735
+ font-size: 0.8rem;
2736
+ font-weight: 700;
2737
+ letter-spacing: 0.07em;
2738
+ text-transform: uppercase;
2739
+ }
2740
+
2741
+ .finish h3 .count {
2742
+ margin-left: 1ch;
2743
+ color: var(--quiet);
2744
+ font-weight: 400;
2745
+ }
2746
+
2747
+ .finish .meaning {
2748
+ color: var(--quiet);
2749
+ font-size: 0.867rem;
2750
+ }
2751
+
2752
+ .finish .lines {
2753
+ margin: 0.6rem -0.8ch 0;
2754
+ padding: 0;
2755
+ list-style: none;
2756
+ }
2757
+
2758
+ .finish [data-line-of] {
2759
+ display: grid;
2760
+ grid-template-columns: 9px minmax(0, 1fr) auto;
2761
+ gap: 1.6ch;
2762
+ align-items: center;
2763
+ padding: 0.15rem 0.8ch;
2764
+ cursor: pointer;
2765
+ }
2766
+
2767
+ .finish [data-line-of]:focus {
2768
+ background: var(--rest);
2769
+ }
2770
+
2771
+ .finish [data-line-of] .lead {
2772
+ overflow: hidden;
2773
+ text-overflow: ellipsis;
2774
+ white-space: nowrap;
2775
+ }
2776
+
2777
+ .finish [data-line-of]:not([data-state=""]) .lead,
2778
+ .finish [data-line-of] .said {
2779
+ color: var(--quiet);
2780
+ }
2781
+
2782
+ .finish [data-line-of] .said {
2783
+ font-size: 0.867rem;
2784
+ }
2785
+
2786
+ /* Unfolded, a line shows its decision's own words under its lead, and the
2787
+ choice in full, in the column the lead stands in. */
2788
+ .finish [data-line-of] .more {
2789
+ grid-column: 2 / -1;
2790
+ margin: 0.3rem 0 0.7rem;
2791
+ font-size: 0.933rem;
2792
+ line-height: 1.6;
2793
+ cursor: auto;
2794
+ }
2795
+
2796
+ .finish [data-line-of]:not([aria-expanded="true"]) .more {
2797
+ display: none;
2798
+ }
2799
+
2800
+ .finish [data-line-of][aria-expanded="true"] .lead {
2801
+ white-space: normal;
2802
+ }
2803
+
2804
+ .finish .more .words > :first-child {
2805
+ margin-top: 0;
2806
+ }
2807
+
2808
+ /* The lead stands whole on the line above, so its words do not repeat it,
2809
+ whether its box's checkbox came with them or not. */
2810
+ .finish .more .words input,
2811
+ .finish .more .words > strong:first-child,
2812
+ .finish .more .words > input:first-child + strong,
2813
+ .finish .more .words > p:first-child > strong:first-child {
2814
+ display: none;
2815
+ }
2816
+
2817
+ .finish .more .words p {
2818
+ margin: 0 0 0.5rem;
2819
+ }
2820
+
2821
+ .finish .more .choice {
2822
+ margin: 0.4rem 0 0;
2823
+ padding-left: 1.2ch;
2824
+ border-left: 1px solid var(--rule-strong);
2825
+ color: var(--quiet);
2826
+ }
2827
+
2828
+ .finish .more .choice[hidden] {
2829
+ display: none;
2830
+ }
2831
+
2832
+ .finish .leave {
2833
+ display: flex;
2834
+ flex-wrap: wrap;
2835
+ gap: 0.4rem 1.6ch;
2836
+ align-items: baseline;
2837
+ margin-top: 0.6rem;
2838
+ color: var(--quiet);
2839
+ font-size: 0.867rem;
2840
+ }
2841
+
2842
+ .finish .leave[hidden] {
2843
+ display: none;
2844
+ }
2845
+
2846
+ /* The page of every decision: a pull request's decisions under its heading, a
2847
+ line each with a bead, and the one at hand opened out with its menu, as on
2848
+ a pull request's own page while it is decided. */
2849
+
2850
+ body:not([data-page="pull_requests"]):not([data-page="bursts"]) > .main {
2851
+ --measure: min(64rem, 100%);
2852
+ }
2853
+
2854
+ body[data-page="decisions"] .burst,
2855
+ body[data-page="decisions"] main.decisions,
2856
+ body[data-page="decisions"] .draft-tools,
2857
+ body[data-page="decisions"] .unmatched,
2858
+ body[data-page="decisions"] .recorded,
2859
+ body[data-page="decisions"] .empty {
2860
+ max-width: var(--measure);
2861
+ }
2862
+
2863
+ .burst .tally {
2864
+ max-width: 76ch;
2865
+ }
2866
+
2867
+ .part {
2868
+ margin-top: var(--group-gap);
2869
+ border: 1px solid var(--rule);
2870
+ background: var(--surface);
2871
+ }
2872
+
2873
+ .part header {
2874
+ position: relative;
2875
+ padding: 10px 16px;
2876
+ border-top: 0;
2877
+ border-bottom: 0;
2878
+ background: var(--surface-head);
2879
+ }
2880
+
2881
+ .part h2 {
2882
+ margin: 0;
2883
+ font-size: 1rem;
2884
+ font-weight: 700;
2885
+ }
2886
+
2887
+ .part h2 .number {
2888
+ margin-right: 0.6ch;
2889
+ color: var(--quiet);
2890
+ font-weight: 400;
2891
+ text-decoration: none;
2892
+ }
2893
+
2894
+ .part .facts,
2895
+ .part .refused {
2896
+ color: var(--quiet);
2897
+ font-size: 0.867rem;
2898
+ }
2899
+
2900
+ .lead-in {
2901
+ margin: 12px 0 4px;
2902
+ color: var(--quiet);
2903
+ font-size: 0.8rem;
2904
+ font-weight: 400;
2905
+ letter-spacing: 0.07em;
2906
+ text-transform: uppercase;
2907
+ }
2908
+
2909
+ /* The non-blocking decisions, folded under their heading, which reads like
2910
+ a lead-in with how many wait beside it. One gesture leaves them. */
2911
+
2912
+ details.non-blocking > summary {
2913
+ margin: 14px 0 4px;
2914
+ color: var(--ink);
2915
+ font-size: 0.8rem;
2916
+ font-weight: 700;
2917
+ letter-spacing: 0.07em;
2918
+ text-transform: uppercase;
2919
+ cursor: pointer;
2920
+ }
2921
+
2922
+ details.non-blocking > summary .count {
2923
+ margin-left: 1ch;
2924
+ color: var(--quiet);
2925
+ font-weight: 400;
2926
+ letter-spacing: 0;
2927
+ text-transform: none;
2928
+ }
2929
+
2930
+ /* Pictures no line links, folded where they stood: one quiet line until
2931
+ the reader opens it. */
2932
+
2933
+ details.more-pictures > summary {
2934
+ margin: 10px 0;
2935
+ color: var(--quiet);
2936
+ font-size: 0.867rem;
2937
+ cursor: pointer;
2938
+ }
2939
+
2940
+ .part .facts [data-leave-non-blocking] {
2941
+ margin-left: 1ch;
2942
+ padding: 0;
2943
+ border: 0;
2944
+ background: none;
2945
+ color: var(--ink);
2946
+ font: inherit;
2947
+ cursor: pointer;
2948
+ }
2949
+
2950
+ .boxes {
2951
+ margin: 0;
2952
+ }
2953
+
2954
+ /* In rem, not ch: a line that shows its lead alone has no type size of its own. */
2955
+ .box {
2956
+ position: relative;
2957
+ padding: 6px 10.5rem 6px 2.6rem;
2958
+ border: 0;
2959
+ background: none;
2960
+ box-shadow: none;
2961
+ border-top: 1px solid var(--rule-soft);
2962
+ scroll-margin-block: 12rem 4rem;
2963
+ }
2964
+
2965
+ .box::before {
2966
+ content: "";
2967
+ position: absolute;
2968
+ top: 0.75rem;
2969
+ left: 12px;
2970
+ box-sizing: border-box;
2971
+ width: 9px;
2972
+ height: 9px;
2973
+ border: 1px solid var(--ink);
2974
+ border-radius: 50%;
2975
+ }
2976
+
2977
+ .box:not([data-said=""])::before {
2978
+ border-color: var(--quiet);
2979
+ background: var(--quiet);
2980
+ }
2981
+
2982
+ .box[data-choice="stale"]::before {
2983
+ border-color: var(--ink);
2984
+ border-style: dashed;
2985
+ background: none;
2986
+ }
2987
+
2988
+ /* Selected for one answer with others: a mark beside its bead. */
2989
+ .box[data-selected] > .body::before {
2990
+ content: "+";
2991
+ position: absolute;
2992
+ top: 0.3rem;
2993
+ left: 26px;
2994
+ color: var(--ink);
2995
+ font-weight: 700;
2996
+ }
2997
+
2998
+ .box[aria-current][data-selected] > .body::before {
2999
+ top: 1rem;
3000
+ }
3001
+
3002
+ /* By theme: one kind of question across the burst under a heading the
3003
+ cursor rests on, each decision with its pull request above it. */
3004
+
3005
+ .theme-group {
3006
+ margin-top: var(--group-gap);
3007
+ border: 1px solid var(--rule);
3008
+ background: var(--surface);
3009
+ }
3010
+
3011
+ .theme-group header {
3012
+ position: relative;
3013
+ padding: 10px 16px;
3014
+ border-top: 0;
3015
+ background: var(--surface-head);
3016
+ }
3017
+
3018
+ .theme-group h2 {
3019
+ position: relative;
3020
+ margin: 0;
3021
+ font-size: 1rem;
3022
+ font-weight: 700;
3023
+ outline: 0;
3024
+ }
3025
+
3026
+ .theme-group h2 .count,
3027
+ .theme-group .facts,
3028
+ .box .of {
3029
+ color: var(--quiet);
3030
+ font-size: 0.867rem;
3031
+ font-weight: 400;
3032
+ }
3033
+
3034
+ .theme-group h2[aria-current]::before {
3035
+ content: ">";
3036
+ position: absolute;
3037
+ left: -2.4ch;
3038
+ }
3039
+
3040
+ .box .of {
3041
+ margin: 0 0 2px;
3042
+ }
3043
+
3044
+ /* What was chosen on it, at the line's end. */
3045
+ .box:not([aria-current])::after {
3046
+ content: attr(data-said);
3047
+ position: absolute;
3048
+ top: 5px;
3049
+ right: 12px;
3050
+ color: var(--quiet);
3051
+ font-size: 0.867rem;
3052
+ line-height: 1.85;
3053
+ }
3054
+
3055
+ .box .body input[type="checkbox"] {
3056
+ display: none;
3057
+ }
3058
+
3059
+ /* A line of the list is the decision's lead alone. */
3060
+ .box:not([aria-current]) .body {
3061
+ display: block;
3062
+ max-width: none;
3063
+ overflow: hidden;
3064
+ color: var(--quiet);
3065
+ text-overflow: ellipsis;
3066
+ white-space: nowrap;
3067
+ -webkit-line-clamp: none;
3068
+ }
3069
+
3070
+ .box:not([aria-current]) .body:has(> strong, > p:first-child > strong) {
3071
+ font-size: 0;
3072
+ }
3073
+
3074
+ .box:not([aria-current]) .body > strong:first-of-type,
3075
+ .box:not([aria-current]) .body > p:first-child > strong:first-child {
3076
+ font-size: 1rem;
3077
+ font-weight: 400;
3078
+ }
3079
+
3080
+ .box:not([aria-current]) .body > :not(strong, p:first-child),
3081
+ .box:not([aria-current]) .body br {
3082
+ display: none;
3083
+ }
3084
+
3085
+ .box:not([aria-current]) .body > p:first-child {
3086
+ display: inline;
3087
+ margin: 0;
3088
+ }
3089
+
3090
+ /* One a review file names, or that asks the owner something, waits in full relief. */
3091
+ .box[data-waiting="true"]:not([aria-current]) .body > strong:first-of-type,
3092
+ .box[data-waiting="true"]:not([aria-current])
3093
+ .body
3094
+ > p:first-child
3095
+ > strong:first-child {
3096
+ color: var(--ink);
3097
+ font-weight: 700;
3098
+ }
3099
+
3100
+ .box:not([aria-current]) .beneath {
3101
+ display: none;
3102
+ }
3103
+
3104
+ .box[aria-current] {
3105
+ margin: 0;
3106
+ padding: 16px 16px 12px 2.6rem;
3107
+ border-top: 1px solid var(--rule);
3108
+ background: var(--rest);
3109
+ outline: 0;
3110
+ }
3111
+
3112
+ .box[aria-current]::before {
3113
+ top: 1.45rem;
3114
+ }
3115
+
3116
+ .box[aria-current] .body {
3117
+ max-width: none;
3118
+ color: var(--ink);
3119
+ font-size: 1rem;
3120
+ line-height: 1.62;
3121
+ }
3122
+
3123
+ .box[aria-current] .body > strong:first-of-type,
3124
+ .box[aria-current] .body > p:first-child > strong:first-child {
3125
+ display: block;
3126
+ margin-bottom: 8px;
3127
+ }
3128
+
3129
+ .box[aria-current] .beneath {
3130
+ max-width: none;
3131
+ margin-top: 14px;
3132
+ font: inherit;
3133
+ font-size: 1rem;
3134
+ }
3135
+
3136
+ .box[aria-current] .beneath .status {
3137
+ color: var(--quiet);
3138
+ font-size: 0.867rem;
3139
+ }
3140
+
3141
+ .box .beneath > .actions {
3142
+ margin-top: 0;
3143
+ }
3144
+
3145
+ /* The cursor at the decision at hand, in the gutter, as on a pull request's page. */
3146
+ .decisions .box[aria-current] .body::before {
3147
+ content: ">";
3148
+ position: absolute;
3149
+ top: 14px;
3150
+ left: -2.4ch;
3151
+ color: var(--ink);
3152
+ font-size: 1rem;
3153
+ font-weight: 700;
3154
+ }
3155
+
3156
+ .box:focus-visible {
3157
+ outline: 0;
3158
+ }
3159
+
3160
+ .unmatched {
3161
+ padding: 10px 14px;
3162
+ font-size: 0.867rem;
3163
+ }
3164
+
3165
+ .unmatched h2,
3166
+ .connections h2,
3167
+ .lost h2,
3168
+ .since h2 {
3169
+ font-size: 1rem;
3170
+ font-weight: 700;
3171
+ }
3172
+
3173
+ .recorded {
3174
+ margin-top: 30px;
3175
+ padding: 11px 0 0;
3176
+ border-top: 1px solid var(--rule);
3177
+ font-size: 0.867rem;
3178
+ }
3179
+
3180
+ .recorded summary {
3181
+ color: var(--ink);
3182
+ font-size: 1rem;
3183
+ font-weight: 700;
3184
+ }
3185
+
3186
+ .recorded .count {
3187
+ margin-left: 1.4ch;
3188
+ font-weight: 400;
3189
+ }
3190
+
3191
+ /* The bar of the choices, on the page of every decision and on the prompt: how
3192
+ far they are in a line over a thin bar, what to do with them by key, and the
3193
+ ways to look at them as words, the one in force in full relief. */
3194
+
3195
+ .draft-tools {
3196
+ box-sizing: border-box;
3197
+ padding: 12px 16px 16px;
3198
+ border-block: 0;
3199
+ border-bottom: 1px solid var(--rule-strong);
3200
+ background: var(--panel);
3201
+ font-size: 0.867rem;
3202
+ }
3203
+
3204
+ .draft-tools .bar {
3205
+ gap: 12px 3.2ch;
3206
+ }
3207
+
3208
+ .draft-tools .bar .actions {
3209
+ gap: var(--control-gap) 2.4ch;
3210
+ }
3211
+
3212
+ .progress-line {
3213
+ gap: 0.3rem 1.6ch;
3214
+ font-size: 0.867rem;
3215
+ }
3216
+
3217
+ .progress-line strong {
3218
+ color: var(--ink);
3219
+ font-weight: 700;
3220
+ }
3221
+
3222
+ .progress-line meter,
3223
+ .progress-line meter::-webkit-meter-bar {
3224
+ width: 10rem;
3225
+ height: 3px;
3226
+ border: 0;
3227
+ background: var(--rule);
3228
+ }
3229
+
3230
+ .progress-line meter::-webkit-meter-optimum-value {
3231
+ background: var(--ink);
3232
+ }
3233
+
3234
+ .progress-line meter::-moz-meter-bar {
3235
+ background: var(--ink);
3236
+ }
3237
+
3238
+ .progress-line .left {
3239
+ color: var(--ink);
3240
+ font-weight: 700;
3241
+ }
3242
+
3243
+ .round-line {
3244
+ color: var(--quiet);
3245
+ font-size: 0.867rem;
3246
+ }
3247
+
3248
+ .draft-tools button.quiet,
3249
+ .draft-tools button.primary,
3250
+ .filters button.quiet,
3251
+ .filters a,
3252
+ .views button.quiet {
3253
+ padding: 0;
3254
+ border: 0;
3255
+ background: none;
3256
+ color: var(--quiet);
3257
+ font: inherit;
3258
+ font-size: 0.867rem;
3259
+ font-weight: 400;
3260
+ text-decoration: none;
3261
+ cursor: pointer;
3262
+ }
3263
+
3264
+ .draft-tools button.primary {
3265
+ color: var(--ink);
3266
+ font-weight: 700;
3267
+ }
3268
+
3269
+ .draft-tools button:hover,
3270
+ .filters :is(a, button):hover {
3271
+ color: var(--ink);
3272
+ }
3273
+
3274
+ .draft-tools button kbd {
3275
+ margin-right: 0.6ch;
3276
+ font-weight: 400;
3277
+ }
3278
+
3279
+ /* The session that reads the handover just kept, in the bar's plain manner. */
3280
+ .draft-tools .session-link {
3281
+ padding: 0;
3282
+ border: 0;
3283
+ background: none;
3284
+ font-size: 0.867rem;
3285
+ }
3286
+
3287
+ .draft-tools .session-link:hover {
3288
+ text-decoration: underline;
3289
+ }
3290
+
3291
+ .draft-tools button.primary kbd {
3292
+ border-color: var(--rule-strong);
3293
+ color: var(--ink);
3294
+ }
3295
+
3296
+ .filters {
3297
+ gap: var(--control-gap) 2.4ch;
3298
+ align-items: baseline;
3299
+ margin-top: 12px;
3300
+ padding-top: 10px;
3301
+ border-top: 1px solid var(--rule);
3302
+ }
3303
+
3304
+ .filters [data-filter="open"],
3305
+ .filters [data-filter="all"] {
3306
+ margin-left: 0;
3307
+ }
3308
+
3309
+ .filters button.quiet[aria-pressed="true"],
3310
+ .filters a[aria-current] {
3311
+ border: 0;
3312
+ text-decoration: underline;
3313
+ text-underline-offset: 0.4em;
3314
+ background: var(--plate);
3315
+ color: var(--panel);
3316
+ font-weight: 700;
3317
+ }
3318
+
3319
+ .filters .count {
3320
+ margin-left: 0.4ch;
3321
+ color: var(--quiet);
3322
+ font-weight: 400;
3323
+ opacity: 1;
3324
+ }
3325
+
3326
+ .filters [aria-pressed="true"] .count,
3327
+ .filters [aria-current] .count {
3328
+ color: inherit;
3329
+ }
3330
+
3331
+ .filters .by-state {
3332
+ font-size: 0.867rem;
3333
+ }
3334
+
3335
+ .filters .by-state > summary {
3336
+ color: var(--quiet);
3337
+ }
3338
+
3339
+ .filters .by-state p {
3340
+ display: flex;
3341
+ flex-wrap: wrap;
3342
+ gap: 4px 2.4ch;
3343
+ margin-top: 6px;
3344
+ }
3345
+
3346
+ .draft-tools .data {
3347
+ padding: 14px 16px;
3348
+ font-size: 0.867rem;
3349
+ }
3350
+
3351
+ .draft-tools .data .actions {
3352
+ gap: 6px 2.4ch;
3353
+ }
3354
+
3355
+ .draft-tools .data button.quiet,
3356
+ .import-choices {
3357
+ color: var(--ink);
3358
+ text-decoration: underline;
3359
+ }
3360
+
3361
+ /* Scenarios: the server in one line with a bead for its state, then each
3362
+ scenario a row: what to do, how to open it, what was seen. */
3363
+
3364
+ body[data-page="scenarios"] .burst,
3365
+ body[data-page="scenarios"] main.scenarios {
3366
+ max-width: var(--measure);
3367
+ }
3368
+
3369
+ .server {
3370
+ gap: 4px 2.4ch;
3371
+ margin: 16px 0 0;
3372
+ padding: 12px 16px;
3373
+ border: 1px solid var(--rule);
3374
+ background: var(--panel);
3375
+ font-size: 0.867rem;
3376
+ }
3377
+
3378
+ .server .status {
3379
+ gap: 1.2ch;
3380
+ padding: 0;
3381
+ border: 0;
3382
+ font-weight: 700;
3383
+ }
3384
+
3385
+ /* Up is a solid bead; starting, a hollow one that breathes; down, a hollow grey one. */
3386
+ .light {
3387
+ box-sizing: border-box;
3388
+ width: 9px;
3389
+ height: 9px;
3390
+ border-radius: 50% !important;
3391
+ border: 1px solid var(--quiet);
3392
+ background: none;
3393
+ }
3394
+
3395
+ .server[data-state="up"] .light {
3396
+ border-color: var(--ink);
3397
+ background: var(--ink);
3398
+ }
3399
+
3400
+ .server[data-state="starting"] .light {
3401
+ border-color: var(--ink);
3402
+ background: none;
3403
+ }
3404
+
3405
+ .server .where {
3406
+ flex-basis: 100%;
3407
+ min-width: 0;
3408
+ margin-left: calc(9px + 1.2ch);
3409
+ overflow-wrap: anywhere;
3410
+ }
3411
+
3412
+ .server .action {
3413
+ margin: 0 0 0 calc(9px + 1.2ch);
3414
+ }
3415
+
3416
+ .scenarios h2 {
3417
+ margin: var(--group-gap) 0 0;
3418
+ padding: 8px 12px;
3419
+ border: 1px solid var(--rule);
3420
+ background: var(--surface-head);
3421
+ font-size: 1rem;
3422
+ font-weight: 700;
3423
+ }
3424
+
3425
+ .scenarios .lede {
3426
+ padding: 8px 12px;
3427
+ background: var(--surface);
3428
+ color: var(--quiet);
3429
+ font-size: 0.867rem;
3430
+ }
3431
+
3432
+ .scenarios h3 {
3433
+ margin: var(--group-gap) 0 8px;
3434
+ color: var(--quiet);
3435
+ font-size: 0.8rem;
3436
+ font-weight: 400;
3437
+ letter-spacing: 0.04em;
3438
+ text-transform: uppercase;
3439
+ }
3440
+
3441
+ .scenarios h3 .number {
3442
+ color: var(--quiet);
3443
+ }
3444
+
3445
+ .scenario {
3446
+ grid-template-columns: minmax(0, 1fr) minmax(8rem, 11rem) minmax(10rem, 15rem);
3447
+ gap: 12px 2.4ch;
3448
+ padding: 16px 0;
3449
+ border-top: 1px solid var(--rule);
3450
+ background: var(--surface);
3451
+ }
3452
+
3453
+ .scenario:nth-child(even) {
3454
+ background: var(--panel);
3455
+ }
3456
+
3457
+ .scenario > .text {
3458
+ padding-left: 12px;
3459
+ }
3460
+
3461
+ .scenario > .act,
3462
+ .scenario > .seen {
3463
+ padding: 8px 12px;
3464
+ border-left: 1px solid var(--rule);
3465
+ background: var(--surface-head);
3466
+ }
3467
+
3468
+ .scenario:target {
3469
+ background: none;
3470
+ box-shadow: none;
3471
+ }
3472
+
3473
+ .scenario h4 {
3474
+ font-size: 1rem;
3475
+ font-weight: 700;
3476
+ }
3477
+
3478
+ .scenario .n {
3479
+ min-width: 3ch;
3480
+ color: var(--quiet);
3481
+ font-weight: 400;
3482
+ }
3483
+
3484
+ .scenario .expect,
3485
+ .steps {
3486
+ font-size: 0.867rem;
3487
+ }
3488
+
3489
+ .act small,
3490
+ .seen .line {
3491
+ font-size: 0.8rem;
3492
+ }
3493
+
3494
+ /* Opening is the act of a row; what was seen is said in words, the one given in full relief. */
3495
+ .open,
3496
+ .action {
3497
+ padding: 0;
3498
+ border: 0;
3499
+ background: none;
3500
+ color: var(--ink);
3501
+ font-weight: 700;
3502
+ text-decoration: underline;
3503
+ text-underline-offset: 0.22em;
3504
+ }
3505
+
3506
+ .open:disabled {
3507
+ border: 0;
3508
+ color: var(--quiet);
3509
+ font-weight: 400;
3510
+ text-decoration: none;
3511
+ }
3512
+
3513
+ .results {
3514
+ gap: var(--control-gap) 1.6ch;
3515
+ }
3516
+
3517
+ .result,
3518
+ .result:hover {
3519
+ padding: 0;
3520
+ border: 0;
3521
+ background: none;
3522
+ font-size: 0.8rem;
3523
+ }
3524
+
3525
+ .result {
3526
+ color: var(--quiet);
3527
+ }
3528
+
3529
+ .result:hover,
3530
+ .result[aria-pressed="true"] {
3531
+ color: var(--ink);
3532
+ }
3533
+
3534
+ .result[aria-pressed="true"] {
3535
+ font-weight: 700;
3536
+ text-decoration: underline;
3537
+ text-underline-offset: 0.4em;
3538
+ }
3539
+
3540
+ .seen .line[data-result="ok"] {
3541
+ color: var(--quiet);
3542
+ }
3543
+
3544
+ .seen .line[data-result="not_ok"] {
3545
+ color: var(--ink);
3546
+ font-weight: 700;
3547
+ }
3548
+
3549
+ /* Recordings: a line to each, and the player. */
3550
+
3551
+ body[data-page="recordings"] .films-head,
3552
+ body[data-page="recordings"] .folder,
3553
+ body[data-page="recordings"] .empty {
3554
+ max-width: var(--measure);
3555
+ }
3556
+
3557
+ .films-head h1,
3558
+ .film-head h1 {
3559
+ margin: 0;
3560
+ font-size: 1.4rem;
3561
+ }
3562
+
3563
+ .films-head .tally {
3564
+ margin: 10px 0 0;
3565
+ }
3566
+
3567
+ .folder h2 {
3568
+ margin: var(--group-gap) 0 0;
3569
+ padding: 8px 12px;
3570
+ border: 1px solid var(--rule);
3571
+ background: var(--surface-head);
3572
+ color: var(--ink);
3573
+ font-size: 0.8rem;
3574
+ font-weight: 400;
3575
+ letter-spacing: 0.04em;
3576
+ text-transform: uppercase;
3577
+ }
3578
+
3579
+ .folder h2 a {
3580
+ color: inherit;
3581
+ }
3582
+
3583
+ .films {
3584
+ border: 0;
3585
+ }
3586
+
3587
+ .films li {
3588
+ display: grid;
3589
+ grid-template-columns: minmax(0, 1fr) auto;
3590
+ gap: 2.4ch;
3591
+ align-items: baseline;
3592
+ padding: 8px 12px;
3593
+ border: 0;
3594
+ border-bottom: 1px solid var(--rule-soft);
3595
+ background: var(--surface);
3596
+ }
3597
+
3598
+ .films li:nth-child(even) {
3599
+ background: var(--panel);
3600
+ }
3601
+
3602
+ .films .title {
3603
+ font-size: 1rem;
3604
+ font-weight: 700;
3605
+ }
3606
+
3607
+ .films .facts {
3608
+ font-size: 0.867rem;
3609
+ }
3610
+
3611
+ .film-head .crumbs,
3612
+ .film-head .facts {
3613
+ font-size: 0.867rem;
3614
+ }
3615
+
3616
+ .titling [data-fill] {
3617
+ color: var(--quiet);
3618
+ font-size: 0.867rem;
3619
+ }
3620
+
3621
+ .screen {
3622
+ border-color: var(--rule);
3623
+ background: var(--rest);
3624
+ }
3625
+
3626
+ .controls {
3627
+ gap: var(--control-gap) 2.4ch;
3628
+ padding: 12px;
3629
+ border-bottom: 1px solid var(--rule-strong);
3630
+ background: var(--panel);
3631
+ font-size: 0.867rem;
3632
+ }
3633
+
3634
+ .controls button,
3635
+ .controls .note-here {
3636
+ padding: 0;
3637
+ border: 0;
3638
+ background: none;
3639
+ color: var(--quiet);
3640
+ font-size: 0.867rem;
3641
+ }
3642
+
3643
+ .controls button:hover {
3644
+ color: var(--ink);
3645
+ }
3646
+
3647
+ .controls button.primary {
3648
+ min-width: 0;
3649
+ padding: 1px 1ch;
3650
+ background: var(--ink);
3651
+ color: var(--paper);
3652
+ font-weight: 700;
3653
+ }
3654
+
3655
+ .controls .note-here {
3656
+ color: var(--ink);
3657
+ font-weight: 700;
3658
+ }
3659
+
3660
+ .controls kbd {
3661
+ margin-left: 0.6ch;
3662
+ border-color: var(--rule);
3663
+ color: var(--quiet);
3664
+ font-weight: 400;
3665
+ }
3666
+
3667
+ .timeline,
3668
+ .segments {
3669
+ border-color: var(--rule);
3670
+ background: none;
3671
+ }
3672
+
3673
+ .segments li,
3674
+ .segments li:nth-child(even) {
3675
+ border-left: 1px solid var(--rule-strong);
3676
+ background: none;
3677
+ color: var(--quiet);
3678
+ }
3679
+
3680
+ .segments li.here {
3681
+ background: var(--rest);
3682
+ color: var(--ink);
3683
+ }
3684
+
3685
+ .playhead {
3686
+ background: var(--ink);
3687
+ }
3688
+
3689
+ .pin {
3690
+ border-color: var(--paper);
3691
+ background: var(--kind, var(--ink));
3692
+ }
3693
+
3694
+ /* The steps and notes beside the player are not the pane, though they share its name. */
3695
+ .film .side {
3696
+ position: static;
3697
+ height: auto;
3698
+ padding: 0;
3699
+ overflow: visible;
3700
+ background: none;
3701
+ }
3702
+
3703
+ .film .side h2,
3704
+ .film .side p {
3705
+ padding: 0;
3706
+ }
3707
+
3708
+ .film .side .name {
3709
+ margin: 0;
3710
+ color: inherit;
3711
+ }
3712
+
3713
+ .steps {
3714
+ border-left: 0;
3715
+ }
3716
+
3717
+ .steps button {
3718
+ padding: 4px 0 4px 2.4ch;
3719
+ font-size: 0.867rem;
3720
+ }
3721
+
3722
+ .steps li {
3723
+ position: relative;
3724
+ }
3725
+
3726
+ .steps li[aria-current] {
3727
+ background: none;
3728
+ box-shadow: none;
3729
+ color: var(--ink);
3730
+ font-weight: 700;
3731
+ }
3732
+
3733
+ .steps li[aria-current]::before {
3734
+ content: ">";
3735
+ position: absolute;
3736
+ top: 4px;
3737
+ left: 0;
3738
+ font-size: 0.867rem;
3739
+ }
3740
+
3741
+ /* The player's keys: a bar at the foot, as on every page with keys. */
3742
+ body[data-page="recordings"] footer.keys {
3743
+ position: fixed;
3744
+ inset: auto 0 0 var(--side);
3745
+ z-index: 8;
3746
+ display: flex;
3747
+ gap: 20px;
3748
+ margin: 0;
3749
+ padding: 6px 16px 6px 56px;
3750
+ background: var(--panel);
3751
+ color: var(--quiet);
3752
+ font-size: 0.867rem;
3753
+ }
3754
+
3755
+ body[data-page="recordings"] footer.keys::before {
3756
+ content: "";
3757
+ position: absolute;
3758
+ top: -2px;
3759
+ right: 0;
3760
+ left: 0;
3761
+ height: 5px;
3762
+ background: var(--bead);
3763
+ mask: var(--beads-across) repeat-x;
3764
+ }
3765
+
3766
+ /* The prompt: the bar of the choices, what the agent returned, and the handover as it would go. */
3767
+
3768
+ body[data-page="prompts"] .burst,
3769
+ body[data-page="prompts"] .draft-tools,
3770
+ body[data-page="prompts"] .round-results,
3771
+ body[data-page="prompts"] .handover,
3772
+ body[data-page="prompts"] .taken-in,
3773
+ body[data-page="prompts"] .unreadable,
3774
+ body[data-page="prompts"] .main > details {
3775
+ max-width: var(--measure);
3776
+ }
3777
+
3778
+ .round-results h2 {
3779
+ margin: 0 0 6px;
3780
+ padding: 8px 80px 8px 12px;
3781
+ border: 1px solid var(--rule);
3782
+ background: var(--surface-head);
3783
+ font-size: 1rem;
3784
+ font-weight: 700;
3785
+ }
3786
+
3787
+ .round-results > p {
3788
+ color: var(--quiet);
3789
+ font-size: 0.867rem;
3790
+ }
3791
+
3792
+ .round-results > button,
3793
+ .round-result button {
3794
+ padding: 0;
3795
+ border: 0;
3796
+ background: none;
3797
+ color: var(--ink);
3798
+ font-size: 0.867rem;
3799
+ text-decoration: underline;
3800
+ text-underline-offset: 0.22em;
3801
+ cursor: pointer;
3802
+ }
3803
+
3804
+ .round-result {
3805
+ position: relative;
3806
+ border-top: 1px solid var(--rule);
3807
+ padding-inline: 16px;
3808
+ background: var(--surface);
3809
+ }
3810
+
3811
+ /* The response the reading is in, marked down its whole side; on a pull
3812
+ request's page the cursor marks the block in it. */
3813
+ .round-result[aria-current] {
3814
+ background: none;
3815
+ outline: 0;
3816
+ box-shadow: inset 3px 0 0 var(--ink);
3817
+ }
3818
+
3819
+ body[data-page="prompts"] .round-result[aria-current]::before {
3820
+ content: ">";
3821
+ position: absolute;
3822
+ top: 1rem;
3823
+ left: -2.4ch;
3824
+ font-weight: 700;
3825
+ }
3826
+
3827
+ .handover {
3828
+ box-sizing: border-box;
3829
+ padding: 16px 20px;
3830
+ border-color: var(--rule-strong);
3831
+ color: var(--ink);
3832
+ font-size: 0.867rem;
3833
+ line-height: 1.65;
3834
+ background: var(--panel);
3835
+ }
3836
+
3837
+ body[data-page="prompts"] .main > details > summary {
3838
+ margin-top: 20px;
3839
+ color: var(--quiet);
3840
+ font-size: 0.867rem;
3841
+ }
3842
+
3843
+ .action,
3844
+ form.button_to button.action {
3845
+ margin: 0;
3846
+ padding: 1px 1ch;
3847
+ border: 1px solid var(--ink);
3848
+ background: var(--ink);
3849
+ color: var(--paper);
3850
+ font-weight: 700;
3851
+ text-decoration: none;
3852
+ }
3853
+
3854
+ /* The route: a line to each pull request. The one the cursor is on opens out,
3855
+ its title in full and what else there is to know of it, its keys beside it. */
3856
+
3857
+ body[data-page="bursts"] > .main {
3858
+ --measure: min(64rem, calc(100% - 15rem));
3859
+ }
3860
+
3861
+ .burst,
3862
+ .route {
3863
+ max-width: var(--measure);
3864
+ }
3865
+
3866
+ .burst h1 {
3867
+ margin: 0;
3868
+ font-size: 1.4rem;
3869
+ }
3870
+
3871
+ .burst .tally {
3872
+ max-width: none;
3873
+ margin: 12px 0 16px;
3874
+ color: var(--quiet);
3875
+ }
3876
+
3877
+ .burst .tally .yours {
3878
+ color: var(--ink);
3879
+ font-weight: 700;
3880
+ }
3881
+
3882
+ .burst .taken-in,
3883
+ .burst .gone {
3884
+ margin: 0 0 10px;
3885
+ padding: 0;
3886
+ border: 0;
3887
+ background: none;
3888
+ color: var(--quiet);
3889
+ }
3890
+
3891
+ .route h2 {
3892
+ margin: var(--group-gap) 0 0;
3893
+ padding: 8px 12px;
3894
+ border: 1px solid var(--rule);
3895
+ background: var(--surface-head);
3896
+ color: var(--ink);
3897
+ font-size: 0.8rem;
3898
+ font-weight: 700;
3899
+ letter-spacing: 0.04em;
3900
+ text-transform: uppercase;
3901
+ }
3902
+
3903
+ .lines {
3904
+ margin: 0;
3905
+ padding: 0;
3906
+ list-style: none;
3907
+ border: 1px solid var(--rule);
3908
+ border-top: 0;
3909
+ background: var(--surface);
3910
+ }
3911
+
3912
+ .lines li {
3913
+ position: relative;
3914
+ padding: var(--row-pad) 12px;
3915
+ border: 0;
3916
+ border-bottom: 1px solid var(--rule-soft);
3917
+ background: var(--surface);
3918
+ cursor: pointer;
3919
+ }
3920
+
3921
+ .lines li:nth-child(even) {
3922
+ background: var(--panel);
3923
+ }
3924
+
3925
+ .lines p {
3926
+ margin: 0;
3927
+ }
3928
+
3929
+ .lines .what {
3930
+ display: grid;
3931
+ grid-template-columns: 6ch minmax(0, 1fr) auto;
3932
+ gap: 1ch;
3933
+ align-items: baseline;
3934
+ }
3935
+
3936
+ .lines .stands {
3937
+ min-width: 8ch;
3938
+ text-align: right;
3939
+ }
3940
+
3941
+ .lines .number {
3942
+ margin: 0;
3943
+ color: var(--quiet);
3944
+ text-decoration: none;
3945
+ }
3946
+
3947
+ .lines .title {
3948
+ overflow: hidden;
3949
+ color: inherit;
3950
+ text-decoration: none;
3951
+ text-overflow: ellipsis;
3952
+ white-space: nowrap;
3953
+ }
3954
+
3955
+ .lines .stands,
3956
+ .lines .facts {
3957
+ color: var(--quiet);
3958
+ font-size: 0.867rem;
3959
+ }
3960
+
3961
+ .lines .facts,
3962
+ .lines .beside {
3963
+ display: none;
3964
+ }
3965
+
3966
+ .lines li:hover .title {
3967
+ text-decoration: underline;
3968
+ text-decoration-color: var(--rule-strong);
3969
+ }
3970
+
3971
+ .lines [aria-current] {
3972
+ border: 0;
3973
+ border-bottom: 1px solid var(--rule-strong);
3974
+ background: var(--rest);
3975
+ }
3976
+
3977
+ .lines [aria-current]::before {
3978
+ content: ">";
3979
+ position: absolute;
3980
+ left: -2.4ch;
3981
+ font-weight: 700;
3982
+ }
3983
+
3984
+ .lines [aria-current] .title {
3985
+ font-weight: 700;
3986
+ white-space: normal;
3987
+ }
3988
+
3989
+ .lines [aria-current] .facts {
3990
+ display: block;
3991
+ padding: 4px 0 8px 7ch;
3992
+ line-height: 1.65;
3993
+ }
3994
+
3995
+ .lines [aria-current] .beside {
3996
+ position: absolute;
3997
+ top: 5px;
3998
+ left: calc(100% + 28px);
3999
+ display: grid;
4000
+ gap: var(--control-gap);
4001
+ justify-items: start;
4002
+ color: var(--quiet);
4003
+ font-size: 0.867rem;
4004
+ white-space: nowrap;
4005
+ cursor: default;
4006
+ }
4007
+
4008
+ .lines .beside :is(a, button) {
4009
+ padding: 0;
4010
+ border: 0;
4011
+ background: none;
4012
+ color: inherit;
4013
+ font: inherit;
4014
+ text-decoration: none;
4015
+ cursor: pointer;
4016
+ }
4017
+
4018
+ .lines .beside :is(a, button):hover {
4019
+ color: var(--ink);
4020
+ }
4021
+
4022
+ .lines .beside kbd {
4023
+ margin-right: 0.6ch;
4024
+ border-color: var(--rule);
4025
+ color: var(--quiet);
4026
+ }
4027
+
4028
+ .lines .beside form {
4029
+ margin: 0;
4030
+ }
4031
+
4032
+ .lines .moved {
4033
+ color: var(--ink);
4034
+ font-weight: 700;
4035
+ }
4036
+
4037
+ /* The notices at the head of the route. What joined or left is a line like
4038
+ the route's; what left with choices lists them; a disagreement is a line
4039
+ of words with its fix said quietly after it. */
4040
+
4041
+ .notices {
4042
+ padding-bottom: 8px;
4043
+ border-bottom: 1px solid var(--rule);
4044
+ }
4045
+
4046
+ .notices .lines .what {
4047
+ font-weight: 700;
4048
+ }
4049
+
4050
+ .notices .departed .what {
4051
+ margin: 4px 0 0;
4052
+ font-weight: 700;
4053
+ }
4054
+
4055
+ .notices .departed .number {
4056
+ margin-right: 1ch;
4057
+ color: var(--quiet);
4058
+ }
4059
+
4060
+ .notices .departed ul,
4061
+ .notices .disagreements {
4062
+ margin: 2px 0 6px;
4063
+ padding: 0 0 0 7ch;
4064
+ list-style: none;
4065
+ }
4066
+
4067
+ .notices .disagreements {
4068
+ padding: 0;
4069
+ }
4070
+
4071
+ .notices .disagreements li {
4072
+ padding: 3px 0;
4073
+ font-weight: 700;
4074
+ }
4075
+
4076
+ .notices :is(.fix, .text) {
4077
+ color: var(--quiet);
4078
+ font-weight: 400;
4079
+ }
4080
+
4081
+ /* The rules made in the burst, at the foot of the route: a line each like
4082
+ the route's, and under the one being edited, its one line to write in. */
4083
+
4084
+ .rules {
4085
+ margin-top: 16px;
4086
+ padding-top: 8px;
4087
+ border-top: 1px solid var(--rule);
4088
+ }
4089
+
4090
+ .rules .edit {
4091
+ display: flex;
4092
+ gap: 1ch;
4093
+ align-items: baseline;
4094
+ padding: 2px 0 6px 7ch;
4095
+ }
4096
+
4097
+ .rules .edit[hidden] {
4098
+ display: none;
4099
+ }
4100
+
4101
+ .rules .edit input {
4102
+ flex: 1;
4103
+ padding: 2px 1ch;
4104
+ border: 1px solid var(--rule-strong);
4105
+ background: none;
4106
+ color: var(--ink);
4107
+ font: inherit;
4108
+ }
4109
+
4110
+ .rules .edit .said {
4111
+ color: var(--quiet);
4112
+ font-size: 0.867rem;
4113
+ }
4114
+
4115
+ .rules [data-state="withdrawn"] .title {
4116
+ color: var(--quiet);
4117
+ text-decoration: line-through;
4118
+ }
4119
+
4120
+ /* Wedge strokes replace a straight dividing rule, cut into a shallow seam.
4121
+ Repetition reads as material rather than a row of unexplained symbols. */
4122
+ .route h2,
4123
+ .scenarios h2,
4124
+ .folder h2,
4125
+ .round-results h2 {
4126
+ position: relative;
4127
+ }
4128
+
4129
+ .route h2::after,
4130
+ .scenarios h2::after,
4131
+ .folder h2::after,
4132
+ .round-results h2::after,
4133
+ .part header::after,
4134
+ .theme-group header::after {
4135
+ content: "";
4136
+ position: absolute;
4137
+ right: 0;
4138
+ bottom: -1px;
4139
+ left: 0;
4140
+ height: 4px;
4141
+ background: var(--rule-strong);
4142
+ mask: var(--cuneiform) left center / 42px 10px repeat-x;
4143
+ pointer-events: none;
4144
+ }
4145
+
4146
+ @supports (mask-composite: intersect) {
4147
+ .route h2::after,
4148
+ .scenarios h2::after,
4149
+ .folder h2::after,
4150
+ .round-results h2::after,
4151
+ .part header::after,
4152
+ .theme-group header::after {
4153
+ mask-image: var(--cuneiform), linear-gradient(to right, #000, transparent 85%);
4154
+ mask-size: 42px 10px, 100% 100%;
4155
+ mask-position: left center;
4156
+ mask-repeat: repeat-x, no-repeat;
4157
+ mask-composite: intersect;
4158
+ pointer-events: none;
4159
+ }
4160
+ }
4161
+
4162
+ /* Grain distinguishes group bands and working trays; long reading stays on
4163
+ solid paper. The glyphs repeat as a field, never as a row of controls. */
4164
+ .route h2,
4165
+ .scenarios h2,
4166
+ .folder h2,
4167
+ .round-results h2,
4168
+ .part header,
4169
+ .theme-group header,
4170
+ .side > h2,
4171
+ .try > h2 {
4172
+ background-image: var(--grain-wedges);
4173
+ }
4174
+
4175
+ .draft-tools,
4176
+ details.section[open] > summary {
4177
+ background-image: var(--grain-weave);
4178
+ }
4179
+
4180
+ .scenario > .act {
4181
+ background-image: var(--grain-dots);
4182
+ }
4183
+
4184
+ /* A window too narrow for the column, its keys and the outline at once gives
4185
+ up the outline first: the reading keeps its width, and [ and ] still go
4186
+ from section to section. */
4187
+
4188
+ @media (max-width: 88rem) {
4189
+ body[data-page="pull_requests"] > .main {
4190
+ --measure: min(
4191
+ 41rem,
4192
+ calc(100vw - var(--side) - var(--gutter) - 14rem - 28px)
4193
+ );
4194
+ }
4195
+
4196
+ .outline {
4197
+ display: none;
4198
+ }
4199
+
4200
+ /* Try it then waits at the foot of the page, after its last section. */
4201
+ .rail {
4202
+ position: static;
4203
+ width: auto;
4204
+ max-width: var(--measure);
4205
+ margin-top: 30px;
4206
+ }
4207
+
4208
+ .try {
4209
+ overflow: visible;
4210
+ }
4211
+ }
4212
+
4213
+ /* Narrower still, the route folds over the page, and a block's keys are named
4214
+ in the docked list alone. */
4215
+
4216
+ @media (max-width: 68rem) {
4217
+ body.shell {
4218
+ display: block;
4219
+ }
4220
+
4221
+ body.shell::before {
4222
+ display: none;
4223
+ }
4224
+
4225
+ body.shell .foot {
4226
+ left: 0;
4227
+ }
4228
+
4229
+ .side {
4230
+ position: static;
4231
+ height: auto;
4232
+ max-height: 16rem;
4233
+ padding-bottom: 0.8rem;
4234
+ border-bottom: 1px solid var(--rule);
4235
+ }
4236
+
4237
+ .side .head {
4238
+ grid-template-columns: 72px minmax(0, 1fr);
4239
+ padding-top: 6px;
4240
+ }
4241
+
4242
+ .side .plaque {
4243
+ width: 72px;
4244
+ height: 72px;
4245
+ }
4246
+
4247
+ .side .desk {
4248
+ grid-template-columns: repeat(2, minmax(0, 1fr));
4249
+ gap: 0;
4250
+ font-size: 0.8rem;
4251
+ }
4252
+
4253
+ .side .desk a {
4254
+ padding-block: 1px;
4255
+ }
4256
+
4257
+ .side .name {
4258
+ margin-top: 8px;
4259
+ padding-block: 6px;
4260
+ }
4261
+
4262
+ .side .overall {
4263
+ gap: 4px;
4264
+ margin-top: 4px;
4265
+ }
4266
+
4267
+ body.shell > .main {
4268
+ --gutter: 3.4ch;
4269
+ padding-top: 1.2rem;
4270
+ padding-right: 1rem;
4271
+ }
4272
+
4273
+ body[data-page="pull_requests"] > .main,
4274
+ body[data-page="bursts"] > .main {
4275
+ --measure: 100%;
4276
+ }
4277
+
4278
+ .modebar,
4279
+ .keys-help {
4280
+ padding-left: 1rem;
4281
+ }
4282
+
4283
+ .cursor .beside {
4284
+ display: none;
4285
+ }
4286
+
4287
+ .lines [aria-current] .beside {
4288
+ position: static;
4289
+ display: flex;
4290
+ flex-wrap: wrap;
4291
+ gap: 8px 16px;
4292
+ padding-block: 8px;
4293
+ border-top: 1px solid var(--rule-strong);
4294
+ }
4295
+
4296
+ .pull-request .whole {
4297
+ position: static;
4298
+ width: auto;
4299
+ margin-top: 8px;
4300
+ }
4301
+
4302
+ body[data-page="recordings"] footer.keys {
4303
+ left: 0;
4304
+ flex-wrap: wrap;
4305
+ padding-left: 1rem;
4306
+ }
4307
+
4308
+ .scenario {
4309
+ grid-template-columns: minmax(0, 1fr) minmax(9rem, 15rem);
4310
+ }
4311
+
4312
+ .scenario > .text {
4313
+ grid-column: 1 / -1;
4314
+ }
4315
+ }
4316
+
4317
+ @media (max-width: 40rem) {
4318
+ body:not(.shell) {
4319
+ padding: 24px 16px 80px;
4320
+ }
4321
+
4322
+ .modebar {
4323
+ flex-wrap: wrap;
4324
+ gap: 8px;
4325
+ padding-block: 8px;
4326
+ }
4327
+
4328
+ .modebar .mode {
4329
+ flex-basis: 100%;
4330
+ gap: 4px 12px;
4331
+ }
4332
+
4333
+ .keys-help {
4334
+ grid-template-columns: minmax(0, 1fr);
4335
+ }
4336
+
4337
+ .lines .what {
4338
+ grid-template-columns: 6ch minmax(0, 1fr);
4339
+ }
4340
+
4341
+ .lines .stands {
4342
+ grid-column: 2;
4343
+ text-align: left;
4344
+ }
4345
+
4346
+ .lines .title {
4347
+ white-space: normal;
4348
+ }
4349
+
4350
+ .box,
4351
+ .box[aria-current] {
4352
+ padding-left: 40px;
4353
+ padding-right: 12px;
4354
+ }
4355
+
4356
+ .box:not([aria-current])::after {
4357
+ position: static;
4358
+ display: block;
4359
+ }
4360
+
4361
+ .scenario,
4362
+ .films li,
4363
+ .film {
4364
+ grid-template-columns: minmax(0, 1fr);
4365
+ }
4366
+
4367
+ .scenario > *,
4368
+ .film > * {
4369
+ min-width: 0;
4370
+ }
4371
+
4372
+ .scenario > .text {
4373
+ grid-column: auto;
4374
+ }
4375
+
4376
+ .scenario > .act,
4377
+ .scenario > .seen {
4378
+ border-left: 0;
4379
+ }
4380
+
4381
+ .films li {
4382
+ gap: 4px;
4383
+ }
4384
+
4385
+ .import-choices {
4386
+ flex-wrap: wrap;
4387
+ }
4388
+
4389
+ .handover {
4390
+ padding: 12px;
4391
+ }
4392
+ }
4393
+
4394
+ @media (prefers-reduced-motion: no-preference) {
4395
+ .side a,
4396
+ .outline :is(button, a),
4397
+ details.section > summary,
4398
+ button.choice {
4399
+ transition: color 120ms ease-out, background-color 120ms ease-out;
4400
+ }
4401
+
4402
+ body[data-focus="decide"] li[data-decision][aria-current] {
4403
+ animation: arrive 0.18s cubic-bezier(0.16, 1, 0.3, 1);
4404
+ }
4405
+
4406
+ @keyframes arrive {
4407
+ from {
4408
+ opacity: 0.4;
4409
+ transform: translateY(0.35rem);
4410
+ }
4411
+ }
4412
+ }
4413
+
4414
+ /* Grouse's overlay, for a note on the desk itself, made of the same: square,
4415
+ one face, and no colour. What it asks of the owner, and what went wrong,
4416
+ stand in full relief, as on the desk. Its pill sits at the foot's right,
4417
+ clear of the pane and the bar's own buttons at the left. */
4418
+ grouse-widget {
4419
+ --grouse-accent: var(--ink);
4420
+ --grouse-surface: var(--surface);
4421
+ --grouse-ink: var(--ink);
4422
+ --grouse-muted: var(--quiet);
4423
+ --grouse-danger: var(--ink);
4424
+ --grouse-radius: 0;
4425
+ --grouse-font: var(--mono);
4426
+ }