char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte Somperf(diff): virtualize rich rows with searchable text fallbacksece94e9

main
13.2 KiB601 linesraw
1/* the history down the side, and the shown revision's changes beside it, each scrolling on its own */
2.diff-view {
3  display: grid;
4  grid-template-columns: minmax(224px, 304px) minmax(0, 1fr);
5  height: 100%;
6  min-height: 0;
7}
8.diff-view .spacer {
9  flex: 1;
10}
11
12/* history, as jj log draws it */
13.diff-log {
14  overflow-y: auto;
15  background: var(--panel);
16  border-right: 1px solid var(--line);
17  font-size: var(--text-small);
18}
19.diff-log .revision {
20  display: flex;
21  flex-direction: column;
22  gap: 2px;
23  padding: 8px 12px;
24  color: var(--text);
25  border-bottom: 1px solid var(--line);
26  /* a long history lays out only the entries in sight */
27  content-visibility: auto;
28  contain-intrinsic-size: auto 64px;
29}
30.diff-log .revision:hover {
31  background: var(--raised);
32}
33.diff-log .revision[aria-current="page"] {
34  background: var(--raised);
35  box-shadow: inset 2px 0 var(--accent);
36}
37.diff-log .revision[aria-current="page"]:hover {
38  box-shadow: inset 2px 0 var(--accent-fade);
39}
40.diff-log .revision.immutable .revision-summary {
41  color: var(--muted);
42}
43.revision-line {
44  display: flex;
45  flex-wrap: wrap;
46  align-items: baseline;
47  gap: 0 1ch;
48  font-family: var(--mono);
49}
50.diff-view .glyph {
51  color: var(--muted);
52}
53.diff-view [aria-current="page"] .glyph {
54  color: var(--accent);
55}
56.diff-view [aria-current="page"]:hover .glyph {
57  color: var(--accent-fade);
58}
59.diff-view .change,
60.diff-view .commit {
61  color: var(--muted);
62}
63.diff-view .change b {
64  font-weight: 600;
65  color: var(--hl-builtin);
66}
67.diff-view .commit b {
68  font-weight: 600;
69  color: var(--hl-keyword);
70}
71.diff-view .ref {
72  color: var(--hl-ident);
73}
74.diff-view .tag {
75  margin-right: 0.5ch;
76  color: var(--hl-string);
77}
78.diff-view .tag.conflict {
79  color: var(--error);
80}
81.revision-summary {
82  overflow: hidden;
83  text-overflow: ellipsis;
84  white-space: nowrap;
85}
86.revision-summary.none,
87.commit-subject.none {
88  color: var(--muted);
89}
90.revision-meta {
91  color: var(--muted);
92  font-size: var(--text-small);
93}
94.diff-log .more {
95  width: 100%;
96  padding: 8px;
97}
98
99.diff-main {
100  overflow-y: auto;
101  min-width: 0;
102  padding: 0 24px 32px;
103}
104/* An inherited cursor on the pane restyles every diff row on each refresh in Firefox. */
105.diff-head.loading {
106  cursor: progress;
107}
108.diff-view .meta {
109  margin: 8px 0 0;
110  color: var(--muted);
111  font-size: var(--text-ui);
112}
113.diff-error {
114  margin: 8px 0 0;
115  color: var(--error);
116  font-family: var(--mono);
117  font-size: var(--text-small);
118  white-space: pre-wrap;
119}
120
121/* the commit as sorcery's commit view: subject and body as one block, then its metadata */
122.diff-head {
123  padding: 16px 0 8px;
124}
125.commit-subject {
126  margin: 0;
127  font-size: var(--text-title);
128  font-weight: 600;
129}
130.commit-body {
131  margin: 8px 0 0;
132  padding: 0;
133  background: none;
134  border: 0;
135  font: inherit;
136  color: var(--muted);
137  white-space: pre-wrap;
138}
139.commit-reword textarea {
140  box-sizing: border-box;
141  width: 100%;
142  resize: vertical;
143  font-family: var(--mono);
144}
145.commit-reword .diff-error:empty {
146  display: none;
147}
148.commit-reword-actions {
149  display: flex;
150  align-items: baseline;
151  gap: 8px;
152  margin-top: 8px;
153}
154.commit-reword-actions .meta {
155  margin: 0;
156}
157table.commit-meta {
158  margin-top: 16px;
159  border-collapse: collapse;
160  font-size: var(--text-ui);
161}
162table.commit-meta th {
163  padding: 0 24px 0 0;
164  text-align: left;
165  vertical-align: top;
166  font-weight: 400;
167  color: var(--muted);
168}
169table.commit-meta td {
170  font-family: var(--mono);
171  word-break: break-all;
172}
173.diff-toolbar {
174  display: flex;
175  flex-wrap: wrap;
176  align-items: center;
177  gap: 8px 16px;
178  margin-top: 16px;
179  font-size: var(--text-ui);
180}
181.diffstat {
182  display: flex;
183  gap: 12px;
184  white-space: nowrap;
185}
186.diff-view .add-count {
187  color: var(--added);
188}
189.diff-view .del-count {
190  color: var(--removed);
191}
192.diff-view .generated-count {
193  color: var(--muted);
194}
195.diff-layout {
196  display: inline-flex;
197}
198/* a choice of two, which a box keeps together */
199.diff-layout button {
200  padding: 2px 8px;
201  background: var(--raised);
202  border: 1px solid var(--line);
203  color: var(--muted);
204}
205.diff-layout button + button {
206  border-left: 0;
207}
208.diff-layout button[aria-pressed="true"] {
209  color: var(--accent);
210  border-color: var(--line-strong);
211}
212.diff-layout button[aria-pressed="true"]:hover {
213  color: var(--accent-fade);
214}
215.diff-index {
216  display: grid;
217  grid-template-columns: max-content max-content max-content minmax(0, 1fr);
218  column-gap: 12px;
219  margin: 12px 0 0;
220  padding: 0;
221  list-style: none;
222  font-family: var(--mono);
223  font-size: var(--text-small);
224}
225.diff-index li {
226  display: grid;
227  grid-template-columns: subgrid;
228  grid-column: 1 / -1;
229  align-items: baseline;
230}
231.diff-index button {
232  display: grid;
233  grid-template-columns: subgrid;
234  grid-column: span 2;
235  align-items: baseline;
236  min-width: 0;
237  color: var(--text);
238  text-align: left;
239  overflow-wrap: anywhere;
240}
241.diff-index .status {
242  font-weight: 600;
243}
244.diff-index :is(.add-count, .del-count) {
245  text-align: right;
246  white-space: nowrap;
247}
248.diff-view .status {
249  color: var(--muted);
250}
251.diff-view .status.added {
252  color: var(--added);
253}
254.diff-view .status.deleted {
255  color: var(--removed);
256}
257.diff-view .status:is(.renamed, .copied) {
258  color: var(--hl-keyword);
259}
260
261/* each file in its own box, as sorcery's, its header staying while the file scrolls past; files out of sight are not
262   laid out, and until one has been it takes about the height of its rows */
263.file-diff {
264  margin-top: 16px;
265  border: 1px solid var(--line);
266  content-visibility: auto;
267  contain-intrinsic-size: auto calc(var(--rows) * 16px + 36px);
268}
269.file-summary {
270  position: sticky;
271  top: 0;
272  z-index: 1;
273  display: flex;
274  align-items: baseline;
275  gap: 4px;
276  padding: 4px 12px 4px 4px;
277  background: var(--panel);
278  color: var(--muted);
279  font-size: var(--text-ui);
280}
281.file-summary .chevron {
282  align-self: stretch;
283}
284.file-summary-content {
285  display: inline-flex;
286  flex-wrap: wrap;
287  align-items: baseline;
288  gap: 0 8px;
289  flex: 1;
290  min-width: 0;
291}
292.file-summary-content .path {
293  font-family: var(--mono);
294  font-weight: 600;
295  color: var(--text);
296  overflow-wrap: anywhere;
297}
298.file-actions {
299  display: inline-flex;
300  align-items: baseline;
301  gap: 8px;
302  margin-left: auto;
303}
304.file-actions .mode {
305  font-family: var(--mono);
306  color: var(--hl-keyword);
307}
308.file-actions .generated-note {
309  font-style: italic;
310}
311.file-actions .viewed {
312  display: inline-flex;
313  align-items: center;
314  gap: 4px;
315}
316.file-diff .file-note {
317  margin: 0;
318  padding: 8px 12px;
319  border-top: 1px solid var(--line);
320}
321
322.diff-content {
323  border-top: 1px solid var(--line);
324}
325.diff-chunk {
326  content-visibility: auto;
327  contain-intrinsic-size: auto calc(var(--rows) * 16px);
328  overflow: clip;
329}
330.diff-plain {
331  margin: 0;
332  border: 0;
333  background: none;
334  color: var(--text);
335  font-family: var(--mono);
336  font-size: var(--text-small);
337  white-space: pre-wrap;
338  overflow-wrap: anywhere;
339  tab-size: 4;
340  padding: 0 8px 0 120px;
341}
342.diff-plain-split {
343  display: grid;
344  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
345}
346.diff-plain-split .diff-plain {
347  padding-left: 64px;
348}
349
350/* lines as sorcery's: rows tinted by what happened to them, marks drawn beside the text */
351table.diff {
352  width: 100%;
353  border-collapse: collapse;
354  table-layout: fixed;
355  font-family: var(--mono);
356  font-size: var(--text-small);
357}
358table.diff col.gutter {
359  width: 56px;
360}
361table.diff td {
362  padding: 0 8px;
363  vertical-align: top;
364}
365table.diff td.text {
366  white-space: pre-wrap;
367  word-break: break-word;
368  tab-size: 4;
369}
370table.diff.split td.text + td.ln {
371  border-left: 1px solid var(--line);
372}
373table.diff td.text::before {
374  content: " ";
375  display: inline-block;
376  width: 1ch;
377  margin-right: 0.5ch;
378}
379table.diff td.text.add::before {
380  content: "+";
381  color: var(--added);
382}
383table.diff td.text.del::before {
384  content: "-";
385  color: var(--removed);
386}
387table.diff td.ln {
388  min-width: 40px;
389  text-align: right;
390  white-space: nowrap;
391  color: var(--muted);
392  user-select: none;
393}
394.diff-fold {
395  padding: 2px 8px;
396  font-family: var(--mono);
397  font-size: var(--text-small);
398  color: var(--muted);
399  background: var(--panel);
400}
401.diff-fold .fold {
402  font: inherit;
403}
404table.diff tr.add,
405table.diff.split td.add {
406  background: color-mix(in srgb, var(--added) 9%, transparent);
407}
408table.diff tr.del,
409table.diff.split td.del {
410  background: color-mix(in srgb, var(--removed) 9%, transparent);
411}
412table.diff td.none {
413  background: repeating-linear-gradient(
414    -45deg,
415    transparent 0 4px,
416    color-mix(in srgb, var(--line) 35%, transparent) 4px 5px
417  );
418}
419table.diff mark {
420  color: inherit;
421  border-radius: 2px;
422}
423table.diff .add mark.word {
424  background: color-mix(in srgb, var(--added) 25%, transparent);
425}
426table.diff .del mark.word {
427  background: color-mix(in srgb, var(--removed) 25%, transparent);
428}
429table.diff mark.space {
430  background: color-mix(in srgb, var(--error) 55%, transparent);
431}
432table.diff .badge {
433  margin-left: 0.5ch;
434  color: var(--muted);
435  user-select: none;
436}
437
438@media (max-width: 700px) {
439  .diff-view {
440    grid-template-columns: minmax(0, 1fr);
441    grid-template-rows: auto minmax(0, 1fr);
442  }
443  .diff-log {
444    max-height: 30vh;
445    border-right: 0;
446    border-bottom: 1px solid var(--line);
447  }
448}
449
450.file-diff:has(.diff-edit) {
451  content-visibility: visible;
452}
453/* the bar under an edited file's header; save is its one button, the rest read as links */
454.diff-edit-tools {
455  display: flex;
456  flex-wrap: wrap;
457  align-items: center;
458  gap: 4px 16px;
459  padding: 4px 12px;
460  background: var(--panel);
461  border-top: 1px solid var(--line);
462  font-size: var(--text-small);
463}
464.diff-edit-tools [role="status"] {
465  flex: 1;
466  min-width: 192px;
467  color: var(--muted);
468  white-space: pre-wrap;
469}
470.diff-edit-tools .diff-save {
471  padding: 0;
472}
473.diff-conflict:not([hidden]) {
474  display: inline-flex;
475  gap: 16px;
476}
477.diff-edit-tools .diff-force,
478.diff-conflict button.link {
479  color: var(--accent);
480}
481.diff-edit-tools button.link:disabled {
482  color: var(--muted);
483}
484
485/* the editor drawn as the read-only table: the same type, gutter, marks and tints. codemirror's own theme is scoped
486   by generated classes, so these need the extra specificity of .cm-editor */
487.diff-edit-surface {
488  border-top: 1px solid var(--line);
489}
490.diff-edit-surface .cm-editor {
491  font-size: var(--text-small);
492  color: var(--text);
493  background: none;
494}
495.diff-edit-surface .cm-editor.cm-focused {
496  outline: none;
497}
498.diff-edit-surface .cm-editor .cm-scroller {
499  font-family: var(--mono);
500}
501.diff-edit-surface .cm-editor .cm-content {
502  padding: 0;
503  tab-size: 4;
504  caret-color: var(--accent);
505}
506.diff-edit-surface .cm-editor :is(.cm-line, .cm-deletedLine) {
507  padding: 0 8px 0 0;
508}
509.diff-edit-surface .cm-editor .cm-deletedChunk {
510  padding: 0;
511}
512.diff-edit-surface .cm-editor .cm-gutters {
513  background: none;
514  border: 0;
515  color: var(--muted);
516}
517.diff-edit-surface .cm-editor .cm-lineNumbers .cm-gutterElement {
518  min-width: 40px;
519  padding: 0 8px;
520  box-sizing: content-box;
521}
522.diff-edit-surface .cm-editor .cm-changeGutter {
523  width: 1.5ch;
524  padding: 0;
525}
526.diff-edit-surface .cm-editor .cm-changeGutter .cm-gutterElement {
527  background: none;
528}
529.diff-edit-surface .cm-editor .cm-changeGutter .cm-addedRow::before {
530  content: "+";
531  color: var(--added);
532}
533.diff-edit-surface .cm-editor .cm-changeGutter :is(.cm-removedRow, .cm-deletedLineGutter)::before {
534  content: "-";
535  color: var(--removed);
536}
537.diff-edit-surface .cm-editor :is(.cm-changedLine, .cm-gutterElement.cm-addedRow) {
538  background: color-mix(in srgb, var(--added) 9%, transparent);
539}
540.diff-edit-surface .cm-editor :is(.cm-deletedChunk, .cm-gutterElement:is(.cm-removedRow, .cm-deletedLineGutter)),
541.diff-edit-surface .cm-editor.cm-merge-a .cm-changedLine {
542  background: color-mix(in srgb, var(--removed) 9%, transparent);
543}
544.diff-edit-surface .cm-editor :is(.cm-changedText, .cm-deletedText) {
545  border-radius: 2px;
546  background: color-mix(in srgb, var(--added) 25%, transparent);
547}
548.diff-edit-surface .cm-editor :is(.cm-deletedText, .cm-deletedChunk .cm-deletedText),
549.diff-edit-surface .cm-editor.cm-merge-a .cm-changedText {
550  background: color-mix(in srgb, var(--removed) 25%, transparent);
551}
552/* the read-only diff marks words only where a line was changed, not where one was added or removed outright */
553.diff-edit-surface .cm-editor .cm-wholeChange .cm-changedText,
554.diff-edit-surface .cm-editor .cm-deletedChunk:not(:has(+ .cm-changedLine)) .cm-deletedText {
555  background: none;
556}
557.diff-edit-surface .cm-editor .cm-collapsedLines {
558  padding: 2px 0;
559  color: var(--muted);
560  background: none;
561}
562.diff-edit-surface .cm-editor .cm-collapsedLines::before {
563  content: "⋯";
564  margin-inline-end: 1ch;
565}
566.diff-edit-surface .cm-editor .cm-collapsedLines::after {
567  content: none;
568}
569.diff-edit-surface .cm-editor .cm-collapsedLines:hover {
570  color: var(--accent);
571}
572.diff-edit-surface .cm-editor .cm-mergeSpacer {
573  background: repeating-linear-gradient(
574    -45deg,
575    transparent 0 4px,
576    color-mix(in srgb, var(--line) 35%, transparent) 4px 5px
577  );
578}
579.diff-edit-surface .cm-mergeView {
580  overflow: visible;
581}
582.diff-edit-surface .cm-mergeViewEditor + .cm-mergeViewEditor {
583  border-left: 1px solid var(--line);
584}
585
586.diff-leave {
587  background: var(--panel);
588  color: var(--text);
589  border: 1px solid var(--line);
590  max-width: min(480px, 90vw);
591}
592.diff-leave button + button {
593  margin-left: 8px;
594}
595.diff-leave::backdrop {
596  background: var(--scrim);
597}
598.diff-edit-report {
599  color: var(--muted);
600  font-size: var(--text-ui);
601}